src/nvim/screen.c
/*
 * Show wildchar matches in the status line.
 * Show at least the "match" item.
 * We start at item 'first_match' in the list and show all matches that fit.
 *
 * If inversion is possible we use it. Else '=' characters are used.
 */
Show wildchar matches in the status line.
Show at least the "match" item.
We start at item 'first_match' in the list and show all matches that fit.

If inversion is possible we use it. Else '=' characters are used.
Show wildchar matches in the status line . Show at least the " match " item . We start at item ' first_match ' in the list and show all matches that fit . If inversion is possible we use it . Else ' = ' characters are used .
void
win_redr_status_matches (
    expand_T *xp,
    int num_matches,
    char_u **matches,          
    int match,
    int showtail
)
{
#define L_MATCH(m) (showtail ? sm_gettail(matches[m], false) : matches[m])
  int row;
  char_u      *buf;
  int len;
  int clen;                     
  int fillchar;
  int attr;
  int i;
  int highlight = TRUE;
  char_u      *selstart = NULL;
  int selstart_col = 0;
  char_u      *selend = NULL;
  static int first_match = 0;
  int add_left = FALSE;
  char_u      *s;
  int emenu;
  int l;
  if (matches == NULL)          
    return;
  buf = xmalloc(Columns * MB_MAXBYTES + 1);
  if (match == -1) {    
    match = 0;
    highlight = FALSE;
  }
  clen = status_match_len(xp, L_MATCH(match)) + 3;
  if (match == 0)
    first_match = 0;
  else if (match < first_match) {
    first_match = match;
    add_left = TRUE;
  } else {
    for (i = first_match; i < match; ++i)
      clen += status_match_len(xp, L_MATCH(i)) + 2;
    if (first_match > 0)
      clen += 2;
    if ((long)clen > Columns) {
      first_match = match;
      clen = 2;
      for (i = match; i < num_matches; ++i) {
        clen += status_match_len(xp, L_MATCH(i)) + 2;
        if ((long)clen >= Columns) {
          break;
        }
      }
      if (i == num_matches)
        add_left = TRUE;
    }
  }
  if (add_left)
    while (first_match > 0) {
      clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
      if ((long)clen >= Columns) {
        break;
      }
      first_match--;
    }
  fillchar = fillchar_status(&attr, curwin);
  if (first_match == 0) {
    *buf = NUL;
    len = 0;
  } else {
    STRCPY(buf, "< ");
    len = 2;
  }
  clen = len;
  i = first_match;
  while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns) {
    if (i == match) {
      selstart = buf + len;
      selstart_col = clen;
    }
    s = L_MATCH(i);
    emenu = (xp->xp_context == EXPAND_MENUS
             || xp->xp_context == EXPAND_MENUNAMES);
    if (emenu && menu_is_separator(s)) {
      STRCPY(buf + len, transchar('|'));
      l = (int)STRLEN(buf + len);
      len += l;
      clen += l;
    } else
      for (; *s != NUL; ++s) {
        s += skip_status_match_char(xp, s);
        clen += ptr2cells(s);
        if ((l = (*mb_ptr2len)(s)) > 1) {
          STRNCPY(buf + len, s, l);  
          s += l - 1;
          len += l;
        } else {
          STRCPY(buf + len, transchar_byte(*s));
          len += (int)STRLEN(buf + len);
        }
      }
    if (i == match)
      selend = buf + len;
    *(buf + len++) = ' ';
    *(buf + len++) = ' ';
    clen += 2;
    if (++i == num_matches)
      break;
  }
  if (i != num_matches) {
    *(buf + len++) = '>';
    ++clen;
  }
  buf[len] = NUL;
  row = cmdline_row - 1;
  if (row >= 0) {
    if (wild_menu_showing == 0 || wild_menu_showing == WM_LIST) {
      if (msg_scrolled > 0) {
        if (cmdline_row == Rows - 1) {
          msg_scroll_up(false);
          msg_scrolled++;
        } else {
          cmdline_row++;
          row++;
        }
        wild_menu_showing = WM_SCROLLED;
      } else {
        if (lastwin->w_status_height == 0) {
          save_p_ls = p_ls;
          save_p_wmh = p_wmh;
          p_ls = 2;
          p_wmh = 0;
          last_status(FALSE);
        }
        wild_menu_showing = WM_SHOWN;
      }
    }
    ScreenGrid *grid = (wild_menu_showing == WM_SCROLLED)
                        ? &msg_grid_adj : &default_grid;
    grid_puts(grid, buf, row, 0, attr);
    if (selstart != NULL && highlight) {
      *selend = NUL;
      grid_puts(grid, selstart, row, selstart_col, HL_ATTR(HLF_WM));
    }
    grid_fill(grid, row, row + 1, clen, Columns,
              fillchar, fillchar, attr);
  }
  win_redraw_last_status(topframe);
  xfree(buf);
}
void win_redr_status_matches ( expand_T * xp , int num_matches , char_u * * matches , int match , int showtail ) { #define L_MATCH ( m )  (showtail ? sm_gettail(matches[m], false) : matches[m]) int row ; char_u * buf ; int len ; int clen ; int fillchar ; int attr ; int i ; int highlight = TRUE ; char_u * selstart = NULL ; int selstart_col = 0 ; char_u * selend = NULL ; static int first_match = 0 ; int add_left = FALSE ; char_u * s ; int emenu ; int l ; if ( matches == NULL ) return ; buf = xmalloc ( Columns * MB_MAXBYTES + 1 ) ; if ( match == -1 ) { match = 0 ; highlight = FALSE ; } clen = status_match_len ( xp , L_MATCH ( match ) ) + 3 ; if ( match == 0 ) first_match = 0 ; else if ( match < first_match ) { first_match = match ; add_left = TRUE ; } else { for ( i = first_match ; i < match ; ++ i ) clen += status_match_len ( xp , L_MATCH ( i ) ) + 2 ; if ( first_match > 0 ) clen += 2 ; if ( ( long ) clen > Columns ) { first_match = match ; clen = 2 ; for ( i = match ; i < num_matches ; ++ i ) { clen += status_match_len ( xp , L_MATCH ( i ) ) + 2 ; if ( ( long ) clen >= Columns ) { break ; } } if ( i == num_matches ) add_left = TRUE ; } } if ( add_left ) while ( first_match > 0 ) { clen += status_match_len ( xp , L_MATCH ( first_match - 1 ) ) + 2 ; if ( ( long ) clen >= Columns ) { break ; } first_match -- ; } fillchar = fillchar_status ( & attr , curwin ) ; if ( first_match == 0 ) { * buf = NUL ; len = 0 ; } else { STRCPY ( buf , " " ) ; len = 2 ; } clen = len ; i = first_match ; while ( ( long ) ( clen + status_match_len ( xp , L_MATCH ( i ) ) + 2 ) < Columns ) { if ( i == match ) { selstart = buf + len ; selstart_col = clen ; } s = L_MATCH ( i ) ; emenu = ( xp -> xp_context == EXPAND_MENUS || xp -> xp_context == EXPAND_MENUNAMES ) ; if ( emenu && menu_is_separator ( s ) ) { STRCPY ( buf + len , transchar ( ' ' ) ) ; l = ( int ) STRLEN ( buf + len ) ; len += l ; clen += l ; } else for ( ; * s != NUL ; ++ s ) { s += skip_status_match_char ( xp , s ) ; clen += ptr2cells ( s ) ; if ( ( l = ( * mb_ptr2len ) ( s ) ) > 1 ) { STRNCPY ( buf + len , s , l ) ; s += l - 1 ; len += l ; } else { STRCPY ( buf + len , transchar_byte ( * s ) ) ; len += ( int ) STRLEN ( buf + len ) ; } } if ( i == match ) selend = buf + len ; * ( buf + len ++ ) = ' ' ; * ( buf + len ++ ) = ' ' ; clen += 2 ; if ( ++ i == num_matches ) break ; } if ( i != num_matches ) { * ( buf + len ++ ) = ' ' ; ++ clen ; } buf [ len ] = NUL ; row = cmdline_row - 1 ; if ( row >= 0 ) { if ( wild_menu_showing == 0 || wild_menu_showing == WM_LIST ) { if ( msg_scrolled > 0 ) { if ( cmdline_row == Rows - 1 ) { msg_scroll_up ( false ) ; msg_scrolled ++ ; } else { cmdline_row ++ ; row ++ ; } wild_menu_showing = WM_SCROLLED ; } else { if ( lastwin -> w_status_height == 0 ) { save_p_ls = p_ls ; save_p_wmh = p_wmh ; p_ls = 2 ; p_wmh = 0 ; last_status ( FALSE ) ; } wild_menu_showing = WM_SHOWN ; } } ScreenGrid * grid = ( wild_menu_showing == WM_SCROLLED ) ? & msg_grid_adj : & default_grid ; grid_puts ( grid , buf , row , 0 , attr ) ; if ( selstart != NULL && highlight ) { * selend = NUL ; grid_puts ( grid , selstart , row , selstart_col , HL_ATTR ( HLF_WM ) ) ; } grid_fill ( grid , row , row + 1 , clen , Columns , fillchar , fillchar , attr ) ; } win_redraw_last_status ( topframe ) ; xfree ( buf ) ; }
Show wildchar matches in the status line.
Show wildchar matches in the status line .
/* list of matches */ /* length in screen cells */ /* interrupted completion? */ /* don't show match but original text */ /* count 1 for the ending ">" */ /* jumping left, as far as we can go */ /* check if match fits on the screen */ // jumping right, put match at the left /* if showing the last match, we can add some on the left */ /* Check for menu separators - replace with '|' */ // NOLINT(runtime/printf) /* Put the wildmenu just above the command line.  If there is
         * no room, scroll the screen one line up. */ /* Create status line if needed by setting 'laststatus' to 2.
         * Set 'winminheight' to zero to avoid that the window is
         * resized. */ // Tricky: wildmenu can be drawn either over a status line, or at empty // scrolled space in the message output