diff options
Diffstat (limited to 'src/nvim/ex_getln.c')
| -rw-r--r-- | src/nvim/ex_getln.c | 654 |
1 files changed, 332 insertions, 322 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 479d195966..38432a34db 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -142,12 +142,12 @@ typedef struct command_line_state { long count; int indent; int c; - int i; - int j; int gotesc; // TRUE when <ESC> just typed int do_abbr; // when TRUE check for abbr. char_u *lookfor; // string to match int hiscnt; // current history line in use + int save_hiscnt; // history line before attempting + // to jump to next match int histype; // history type to be used pos_T search_start; // where 'incsearch' starts searching pos_T save_cursor; @@ -200,7 +200,7 @@ static Array cmdline_block = ARRAY_DICT_INIT; */ typedef void *(*user_expand_func_T)(const char_u *, int, - const char_u * const *, + typval_T *, bool); static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; @@ -279,6 +279,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) s->old_topfill = curwin->w_topfill; s->old_botline = curwin->w_botline; + assert(indent >= 0); + // set some variables for redrawcmd() ccline.cmdfirstc = (s->firstc == '@' ? 0 : s->firstc); ccline.cmdindent = (s->firstc > 0 ? s->indent : 0); @@ -294,7 +296,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) // autoindent for :insert and :append if (s->firstc <= 0) { - memset(ccline.cmdbuff, ' ', s->indent); + memset(ccline.cmdbuff, ' ', (size_t)s->indent); ccline.cmdbuff[s->indent] = NUL; ccline.cmdpos = s->indent; ccline.cmdspos = s->indent; @@ -315,7 +317,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) if (!cmd_silent) { gotocmdline(true); redrawcmdprompt(); // draw prompt or indent - set_cmdspos(); + ccline.cmdspos = cmd_startcol(); if (!msg_scroll) { msg_ext_clear(false); } @@ -382,7 +384,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) bool tl_ret = true; dict_T *dict = get_vim_var_dict(VV_EVENT); char firstcbuf[2]; - firstcbuf[0] = firstc > 0 ? firstc : '-'; + firstcbuf[0] = (char)(firstc > 0 ? firstc : '-'); firstcbuf[1] = 0; if (has_event(EVENT_CMDLINEENTER)) { @@ -676,37 +678,37 @@ static int command_line_execute(VimState *state, int key) // Hitting <Down> after "emenu Name.": complete submenu if (s->c == K_DOWN && ccline.cmdpos > 0 && ccline.cmdbuff[ccline.cmdpos - 1] == '.') { - s->c = p_wc; + s->c = (int)p_wc; } else if (s->c == K_UP) { // Hitting <Up>: Remove one submenu name in front of the // cursor int found = false; - s->j = (int)(s->xpc.xp_pattern - ccline.cmdbuff); - s->i = 0; - while (--s->j > 0) { + int j = (int)(s->xpc.xp_pattern - ccline.cmdbuff); + int i = 0; + while (--j > 0) { // check for start of menu name - if (ccline.cmdbuff[s->j] == ' ' - && ccline.cmdbuff[s->j - 1] != '\\') { - s->i = s->j + 1; + if (ccline.cmdbuff[j] == ' ' + && ccline.cmdbuff[j - 1] != '\\') { + i = j + 1; break; } // check for start of submenu name - if (ccline.cmdbuff[s->j] == '.' - && ccline.cmdbuff[s->j - 1] != '\\') { + if (ccline.cmdbuff[j] == '.' + && ccline.cmdbuff[j - 1] != '\\') { if (found) { - s->i = s->j + 1; + i = j + 1; break; } else { found = true; } } } - if (s->i > 0) { - cmdline_del(s->i); + if (i > 0) { + cmdline_del(i); } - s->c = p_wc; + s->c = (int)p_wc; s->xpc.xp_context = EXPAND_NOTHING; } } @@ -728,44 +730,44 @@ static int command_line_execute(VimState *state, int key) || ccline.cmdbuff[ccline.cmdpos - 2] != '.' || ccline.cmdbuff[ccline.cmdpos - 3] != '.')) { // go down a directory - s->c = p_wc; + s->c = (int)p_wc; } else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0 && s->c == K_DOWN) { // If in a direct ancestor, strip off one ../ to go down int found = false; - s->j = ccline.cmdpos; - s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); - while (--s->j > s->i) { - s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j); - if (vim_ispathsep(ccline.cmdbuff[s->j])) { + int j = ccline.cmdpos; + int i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); + while (--j > i) { + j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + j); + if (vim_ispathsep(ccline.cmdbuff[j])) { found = true; break; } } if (found - && ccline.cmdbuff[s->j - 1] == '.' - && ccline.cmdbuff[s->j - 2] == '.' - && (vim_ispathsep(ccline.cmdbuff[s->j - 3]) || s->j == s->i + 2)) { - cmdline_del(s->j - 2); - s->c = p_wc; + && ccline.cmdbuff[j - 1] == '.' + && ccline.cmdbuff[j - 2] == '.' + && (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) { + cmdline_del(j - 2); + s->c = (int)p_wc; } } else if (s->c == K_UP) { // go up a directory int found = false; - s->j = ccline.cmdpos - 1; - s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); - while (--s->j > s->i) { - s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j); - if (vim_ispathsep(ccline.cmdbuff[s->j]) + int j = ccline.cmdpos - 1; + int i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); + while (--j > i) { + j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + j); + if (vim_ispathsep(ccline.cmdbuff[j]) #ifdef BACKSLASH_IN_FILENAME - && vim_strchr((const char_u *)" *?[{`$%#", ccline.cmdbuff[s->j + 1]) + && vim_strchr((const char_u *)" *?[{`$%#", ccline.cmdbuff[j + 1]) == NULL #endif ) { if (found) { - s->i = s->j + 1; + i = j + 1; break; } else { found = true; @@ -774,28 +776,28 @@ static int command_line_execute(VimState *state, int key) } if (!found) { - s->j = s->i; - } else if (STRNCMP(ccline.cmdbuff + s->j, upseg, 4) == 0) { - s->j += 4; - } else if (STRNCMP(ccline.cmdbuff + s->j, upseg + 1, 3) == 0 - && s->j == s->i) { - s->j += 3; + j = i; + } else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0) { + j += 4; + } else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0 + && j == i) { + j += 3; } else { - s->j = 0; + j = 0; } - if (s->j > 0) { + if (j > 0) { // TODO(tarruda): this is only for DOS/Unix systems - need to put in // machine-specific stuff here and in upseg init - cmdline_del(s->j); + cmdline_del(j); put_on_cmdline(upseg + 1, 3, false); - } else if (ccline.cmdpos > s->i) { - cmdline_del(s->i); + } else if (ccline.cmdpos > i) { + cmdline_del(i); } // Now complete in the new directory. Set KeyTyped in case the // Up key came from a mapping. - s->c = p_wc; + s->c = (int)p_wc; KeyTyped = true; } } @@ -943,7 +945,7 @@ static int command_line_execute(VimState *state, int key) } } else { // typed p_wc first time s->wim_index = 0; - s->j = ccline.cmdpos; + int j = ccline.cmdpos; // if 'wildmode' first contains "longest", get longest // common part @@ -970,7 +972,7 @@ static int command_line_execute(VimState *state, int key) if (s->res == OK && s->xpc.xp_numfiles > 1) { // a "longest" that didn't do anything is skipped (but not // "list:longest") - if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == s->j) { + if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j) { s->wim_index = 1; } if ((wim_flags[s->wim_index] & WIM_LIST) @@ -1069,13 +1071,13 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match) search_flags += SEARCH_KEEP; } emsg_off++; - s->i = searchit(curwin, curbuf, &t, NULL, - next_match ? FORWARD : BACKWARD, - pat, s->count, search_flags, - RE_SEARCH, 0, NULL, NULL); + int found = searchit(curwin, curbuf, &t, NULL, + next_match ? FORWARD : BACKWARD, + pat, s->count, search_flags, + RE_SEARCH, 0, NULL, NULL); emsg_off--; ui_busy_stop(); - if (s->i) { + if (found) { s->search_start = s->match_start; s->match_end = t; s->match_start = t; @@ -1124,7 +1126,7 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match) static void command_line_next_histidx(CommandLineState *s, bool next_match) { - s->j = (int)STRLEN(s->lookfor); + int j = (int)STRLEN(s->lookfor); for (;; ) { // one step backwards if (!next_match) { @@ -1137,7 +1139,7 @@ static void command_line_next_histidx(CommandLineState *s, bool next_match) s->hiscnt--; } else { // at top of list - s->hiscnt = s->i; + s->hiscnt = s->save_hiscnt; break; } } else { // one step forwards @@ -1161,14 +1163,14 @@ static void command_line_next_histidx(CommandLineState *s, bool next_match) } if (s->hiscnt < 0 || history[s->histype][s->hiscnt].hisstr == NULL) { - s->hiscnt = s->i; + s->hiscnt = s->save_hiscnt; break; } if ((s->c != K_UP && s->c != K_DOWN) - || s->hiscnt == s->i + || s->hiscnt == s->save_hiscnt || STRNCMP(history[s->histype][s->hiscnt].hisstr, - s->lookfor, (size_t)s->j) == 0) { + s->lookfor, (size_t)j) == 0) { break; } } @@ -1193,7 +1195,7 @@ static int command_line_handle_key(CommandLineState *s) ++ccline.cmdpos; } - if (has_mbyte && s->c == K_DEL) { + if (s->c == K_DEL) { ccline.cmdpos += mb_off_next(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos); } @@ -1201,43 +1203,30 @@ static int command_line_handle_key(CommandLineState *s) if (ccline.cmdpos > 0) { char_u *p; - s->j = ccline.cmdpos; - p = ccline.cmdbuff + s->j; - if (has_mbyte) { - p = mb_prevptr(ccline.cmdbuff, p); - - if (s->c == Ctrl_W) { - while (p > ccline.cmdbuff && ascii_isspace(*p)) { - p = mb_prevptr(ccline.cmdbuff, p); - } + int j = ccline.cmdpos; + p = mb_prevptr(ccline.cmdbuff, ccline.cmdbuff + j); - s->i = mb_get_class(p); - while (p > ccline.cmdbuff && mb_get_class(p) == s->i) - p = mb_prevptr(ccline.cmdbuff, p); - - if (mb_get_class(p) != s->i) { - p += (*mb_ptr2len)(p); - } + if (s->c == Ctrl_W) { + while (p > ccline.cmdbuff && ascii_isspace(*p)) { + p = mb_prevptr(ccline.cmdbuff, p); } - } else if (s->c == Ctrl_W) { - while (p > ccline.cmdbuff && ascii_isspace(p[-1])) { - --p; + + int i = mb_get_class(p); + while (p > ccline.cmdbuff && mb_get_class(p) == i) { + p = mb_prevptr(ccline.cmdbuff, p); } - s->i = vim_iswordc(p[-1]); - while (p > ccline.cmdbuff && !ascii_isspace(p[-1]) - && vim_iswordc(p[-1]) == s->i) - --p; - } else { - --p; + if (mb_get_class(p) != i) { + p += utfc_ptr2len(p); + } } ccline.cmdpos = (int)(p - ccline.cmdbuff); - ccline.cmdlen -= s->j - ccline.cmdpos; - s->i = ccline.cmdpos; + ccline.cmdlen -= j - ccline.cmdpos; + int i = ccline.cmdpos; - while (s->i < ccline.cmdlen) { - ccline.cmdbuff[s->i++] = ccline.cmdbuff[s->j++]; + while (i < ccline.cmdlen) { + ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; } // Truncate at the end, required for multi-byte chars. @@ -1307,13 +1296,13 @@ static int command_line_handle_key(CommandLineState *s) status_redraw_curbuf(); return command_line_not_changed(s); - case Ctrl_U: + case Ctrl_U: { // delete all characters left of the cursor - s->j = ccline.cmdpos; - ccline.cmdlen -= s->j; - s->i = ccline.cmdpos = 0; - while (s->i < ccline.cmdlen) { - ccline.cmdbuff[s->i++] = ccline.cmdbuff[s->j++]; + int j = ccline.cmdpos; + ccline.cmdlen -= j; + int i = ccline.cmdpos = 0; + while (i < ccline.cmdlen) { + ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; } // Truncate at the end, required for multi-byte chars. @@ -1323,6 +1312,7 @@ static int command_line_handle_key(CommandLineState *s) } redrawcmd(); return command_line_changed(s); + } case ESC: // get here if p_wc != ESC or when ESC typed twice case Ctrl_C: @@ -1339,15 +1329,15 @@ static int command_line_handle_key(CommandLineState *s) // putting it in history return 0; // back to cmd mode - case Ctrl_R: // insert register + case Ctrl_R: { // insert register putcmdline('"', true); - ++no_mapping; - s->i = s->c = plain_vgetc(); // CTRL-R <char> - if (s->i == Ctrl_O) { - s->i = Ctrl_R; // CTRL-R CTRL-O == CTRL-R CTRL-R + no_mapping++; + int i = s->c = plain_vgetc(); // CTRL-R <char> + if (i == Ctrl_O) { + i = Ctrl_R; // CTRL-R CTRL-O == CTRL-R CTRL-R } - if (s->i == Ctrl_R) { + if (i == Ctrl_R) { s->c = plain_vgetc(); // CTRL-R CTRL-R <char> } --no_mapping; @@ -1369,7 +1359,7 @@ static int command_line_handle_key(CommandLineState *s) } if (s->c != ESC) { // use ESC to cancel inserting register - cmdline_paste(s->c, s->i == Ctrl_R, false); + cmdline_paste(s->c, i == Ctrl_R, false); // When there was a serious error abort getting the // command line. @@ -1391,6 +1381,7 @@ static int command_line_handle_key(CommandLineState *s) ccline.special_char = NUL; redrawcmd(); return command_line_changed(s); + } case Ctrl_D: if (showmatches(&s->xpc, false) == EXPAND_NOTHING) { @@ -1409,24 +1400,17 @@ static int command_line_handle_key(CommandLineState *s) break; } - s->i = cmdline_charsize(ccline.cmdpos); - if (KeyTyped && ccline.cmdspos + s->i >= Columns * Rows) { + int cells = cmdline_charsize(ccline.cmdpos); + if (KeyTyped && ccline.cmdspos + cells >= Columns * Rows) { break; } - ccline.cmdspos += s->i; - if (has_mbyte) { - ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff - + ccline.cmdpos); - } else { - ++ccline.cmdpos; - } + ccline.cmdspos += cells; + ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos); } while ((s->c == K_S_RIGHT || s->c == K_C_RIGHT || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))) && ccline.cmdbuff[ccline.cmdpos] != ' '); - if (has_mbyte) { - set_cmdspos_cursor(); - } + ccline.cmdspos = cmd_screencol(ccline.cmdpos); return command_line_not_changed(s); case K_LEFT: @@ -1446,7 +1430,7 @@ static int command_line_handle_key(CommandLineState *s) || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))) && ccline.cmdbuff[ccline.cmdpos - 1] != ' '); - set_cmdspos_cursor(); + ccline.cmdspos = cmd_screencol(ccline.cmdpos); if (ccline.special_char != NUL) { putcmdline(ccline.special_char, ccline.special_shift); } @@ -1493,22 +1477,19 @@ static int command_line_handle_key(CommandLineState *s) return command_line_not_changed(s); // Ignore mouse } - set_cmdspos(); + ccline.cmdspos = cmd_startcol(); for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen; - ++ccline.cmdpos) { - s->i = cmdline_charsize(ccline.cmdpos); + ccline.cmdpos++) { + int cells = cmdline_charsize(ccline.cmdpos); if (mouse_row <= cmdline_row + ccline.cmdspos / Columns - && mouse_col < ccline.cmdspos % Columns + s->i) { + && mouse_col < ccline.cmdspos % Columns + cells) { break; } - if (has_mbyte) { - // Count ">" for double-wide char that doesn't fit. - correct_cmdspos(ccline.cmdpos, s->i); - ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff - + ccline.cmdpos) - 1; - } - ccline.cmdspos += s->i; + // Count ">" for double-wide char that doesn't fit. + correct_screencol(ccline.cmdpos, cells, &ccline.cmdspos); + ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos) - 1; + ccline.cmdspos += cells; } return command_line_not_changed(s); @@ -1537,7 +1518,7 @@ static int command_line_handle_key(CommandLineState *s) case K_S_HOME: case K_C_HOME: ccline.cmdpos = 0; - set_cmdspos(); + ccline.cmdspos = cmd_startcol(); return command_line_not_changed(s); case Ctrl_E: // end of command line @@ -1546,7 +1527,7 @@ static int command_line_handle_key(CommandLineState *s) case K_S_END: case K_C_END: ccline.cmdpos = ccline.cmdlen; - set_cmdspos_cursor(); + ccline.cmdspos = cmd_screencol(ccline.cmdpos); return command_line_not_changed(s); case Ctrl_A: // all matches @@ -1613,7 +1594,7 @@ static int command_line_handle_key(CommandLineState *s) return command_line_not_changed(s); } - s->i = s->hiscnt; + s->save_hiscnt = s->hiscnt; // save current command string so it can be restored later if (s->lookfor == NULL) { @@ -1625,7 +1606,7 @@ static int command_line_handle_key(CommandLineState *s) || s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN); command_line_next_histidx(s, next_match); - if (s->hiscnt != s->i) { + if (s->hiscnt != s->save_hiscnt) { // jumped to other entry char_u *p; int len = 0; @@ -1646,35 +1627,35 @@ static int command_line_handle_key(CommandLineState *s) // adding the history entry vs the one used now. // First loop: count length. // Second loop: copy the characters. - for (s->i = 0; s->i <= 1; ++s->i) { + for (int i = 0; i <= 1; i++) { len = 0; - for (s->j = 0; p[s->j] != NUL; ++s->j) { + for (int j = 0; p[j] != NUL; j++) { // Replace old sep with new sep, unless it is // escaped. - if (p[s->j] == old_firstc - && (s->j == 0 || p[s->j - 1] != '\\')) { - if (s->i > 0) { - ccline.cmdbuff[len] = s->firstc; + if (p[j] == old_firstc + && (j == 0 || p[j - 1] != '\\')) { + if (i > 0) { + ccline.cmdbuff[len] = (char_u)s->firstc; } } else { // Escape new sep, unless it is already // escaped. - if (p[s->j] == s->firstc - && (s->j == 0 || p[s->j - 1] != '\\')) { - if (s->i > 0) { + if (p[j] == s->firstc + && (j == 0 || p[j - 1] != '\\')) { + if (i > 0) { ccline.cmdbuff[len] = '\\'; } ++len; } - if (s->i > 0) { - ccline.cmdbuff[len] = p[s->j]; + if (i > 0) { + ccline.cmdbuff[len] = p[j]; } } ++len; } - if (s->i == 0) { + if (i == 0) { alloc_cmdbuff(len); } } @@ -1766,9 +1747,9 @@ static int command_line_handle_key(CommandLineState *s) if (IS_SPECIAL(s->c) || mod_mask != 0) { put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true); } else { - s->j = utf_char2bytes(s->c, IObuff); - IObuff[s->j] = NUL; // exclude composing chars - put_on_cmdline(IObuff, s->j, true); + int j = utf_char2bytes(s->c, IObuff); + IObuff[j] = NUL; // exclude composing chars + put_on_cmdline(IObuff, j, true); } return command_line_changed(s); } @@ -1810,7 +1791,7 @@ static int command_line_changed(CommandLineState *s) dict_T *dict = get_vim_var_dict(VV_EVENT); char firstcbuf[2]; - firstcbuf[0] = s->firstc > 0 ? s->firstc : '-'; + firstcbuf[0] = (char)(s->firstc > 0 ? s->firstc : '-'); firstcbuf[1] = 0; // set v:event to a dictionary with information about the commandline @@ -1845,10 +1826,11 @@ static int command_line_changed(CommandLineState *s) s->incsearch_postponed = false; curwin->w_cursor = s->search_start; // start at old position save_last_search_pattern(); + int i; // If there is no command line, don't do anything if (ccline.cmdlen == 0) { - s->i = 0; + i = 0; SET_NO_HLSEARCH(true); // turn off previous highlight redraw_all_later(SOME_VALID); } else { @@ -1861,15 +1843,14 @@ static int command_line_changed(CommandLineState *s) if (!p_hls) { search_flags += SEARCH_KEEP; } - s->i = do_search(NULL, s->firstc, ccline.cmdbuff, s->count, - search_flags, - &tm, NULL); + i = do_search(NULL, s->firstc, ccline.cmdbuff, s->count, + search_flags, &tm, NULL); emsg_off--; // if interrupted while searching, behave like it failed if (got_int) { (void)vpeekc(); // remove <C-C> from input stream got_int = false; // don't abandon the command line - s->i = 0; + i = 0; } else if (char_avail()) { // cancelled searching because a char was typed s->incsearch_postponed = true; @@ -1877,7 +1858,7 @@ static int command_line_changed(CommandLineState *s) ui_busy_stop(); } - if (s->i != 0) { + if (i != 0) { highlight_match = true; // highlight position } else { highlight_match = false; // remove highlight @@ -1892,7 +1873,7 @@ static int command_line_changed(CommandLineState *s) changed_cline_bef_curs(); update_topline(); - if (s->i != 0) { + if (i != 0) { pos_T save_pos = curwin->w_cursor; s->match_start = curwin->w_cursor; @@ -1921,7 +1902,7 @@ static int command_line_changed(CommandLineState *s) restore_last_search_pattern(); // Leave it at the end to make CTRL-R CTRL-W work. - if (s->i != 0) { + if (i != 0) { curwin->w_cursor = end_pos; } @@ -1978,6 +1959,7 @@ static int command_line_changed(CommandLineState *s) static void abandon_cmdline(void) { XFREE_CLEAR(ccline.cmdbuff); + ccline.redraw_state = kCmdRedrawNone; if (msg_scrolled == 0) { compute_cmdrow(); } @@ -2131,58 +2113,52 @@ static int cmdline_charsize(int idx) return ptr2cells(ccline.cmdbuff + idx); } -/* - * Compute the offset of the cursor on the command line for the prompt and - * indent. - */ -static void set_cmdspos(void) +/// Compute the offset of the cursor on the command line for the prompt and +/// indent. +static int cmd_startcol(void) { - if (ccline.cmdfirstc != NUL) - ccline.cmdspos = 1 + ccline.cmdindent; - else - ccline.cmdspos = 0 + ccline.cmdindent; + return ccline.cmdindent + ((ccline.cmdfirstc != NUL) ? 1 : 0); } -/* - * Compute the screen position for the cursor on the command line. - */ -static void set_cmdspos_cursor(void) + +/// Compute the column position for a byte position on the command line. +static int cmd_screencol(int bytepos) { - int i, m, c; + int m; // maximum column - set_cmdspos(); + int col = cmd_startcol(); if (KeyTyped) { m = Columns * Rows; if (m < 0) /* overflow, Columns or Rows at weird value */ m = MAXCOL; - } else + } else { m = MAXCOL; - for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i) { - c = cmdline_charsize(i); - /* Count ">" for double-wide multi-byte char that doesn't fit. */ - if (has_mbyte) - correct_cmdspos(i, c); - /* If the cmdline doesn't fit, show cursor on last visible char. - * Don't move the cursor itself, so we can still append. */ - if ((ccline.cmdspos += c) >= m) { - ccline.cmdspos -= c; + } + + for (int i = 0; i < ccline.cmdlen && i < bytepos; + i += utfc_ptr2len(ccline.cmdbuff + i)) { + int c = cmdline_charsize(i); + // Count ">" for double-wide multi-byte char that doesn't fit. + correct_screencol(i, c, &col); + + // If the cmdline doesn't fit, show cursor on last visible char. + // Don't move the cursor itself, so we can still append. + if ((col += c) >= m) { + col -= c; break; } - if (has_mbyte) - i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1; } + return col; } -/* - * Check if the character at "idx", which is "cells" wide, is a multi-byte - * character that doesn't fit, so that a ">" must be displayed. - */ -static void correct_cmdspos(int idx, int cells) +/// Check if the character at "idx", which is "cells" wide, is a multi-byte +/// character that doesn't fit, so that a ">" must be displayed. +static void correct_screencol(int idx, int cells, int *col) { if (utfc_ptr2len(ccline.cmdbuff + idx) > 1 && utf_ptr2cells(ccline.cmdbuff + idx) > 1 - && ccline.cmdspos % Columns + cells > Columns) { - ccline.cmdspos++; + && (*col) % Columns + cells > Columns) { + (*col)++; } } @@ -2323,8 +2299,10 @@ add_indent: char_u *s = skipwhite(p); // Insert spaces after leading whitespaces. - memmove(s + num_spaces, s, line_ga.ga_len - (s - p) + 1); - memset(s, ' ', num_spaces); + long move_len = line_ga.ga_len - (s - p) + 1; + assert(move_len >= 0); + memmove(s + num_spaces, s, (size_t)move_len); + memset(s, ' ', (size_t)num_spaces); line_ga.ga_len += num_spaces; } @@ -2377,8 +2355,10 @@ redraw: while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) { *--to = NUL; } - memmove(to, from, line_ga.ga_len - (from - p) + 1); - line_ga.ga_len -= from - to; + long move_len = line_ga.ga_len - (from - p) + 1; + assert(move_len > 0); + memmove(to, from, (size_t)move_len); + line_ga.ga_len -= (int)(from - to); // Removed to much indentation, fix it before redrawing. num_spaces = indent - old_indent; @@ -2484,7 +2464,7 @@ static void alloc_cmdbuff(int len) else len += 20; - ccline.cmdbuff = xmalloc(len); + ccline.cmdbuff = xmalloc((size_t)len); ccline.cmdbufflen = len; } @@ -2521,7 +2501,7 @@ static void realloc_cmdbuff(int len) static char_u *arshape_buf = NULL; # if defined(EXITFREE) -void free_cmdline_buf(void) +void free_arshape_buf(void) { xfree(arshape_buf); } @@ -2561,26 +2541,28 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, size_t prev_end = 0; for (size_t i = 0 ; i < kv_size(colors) ; i++) { const ParserHighlightChunk chunk = kv_A(colors, i); + assert(chunk.start.col < INT_MAX); + assert(chunk.end_col < INT_MAX); if (chunk.start.col != prev_end) { kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) { - .start = prev_end, - .end = chunk.start.col, + .start = (int)prev_end, + .end = (int)chunk.start.col, .attr = 0, })); } const int id = syn_name2id((const char_u *)chunk.group); const int attr = (id == 0 ? 0 : syn_id2attr(id)); kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) { - .start = chunk.start.col, - .end = chunk.end_col, + .start = (int)chunk.start.col, + .end = (int)chunk.end_col, .attr = attr, })); prev_end = chunk.end_col; } if (prev_end < (size_t)colored_ccline->cmdlen) { kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) { - .start = prev_end, - .end = (size_t)colored_ccline->cmdlen, + .start = (int)prev_end, + .end = colored_ccline->cmdlen, .attr = 0, })); } @@ -2745,8 +2727,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) } if (start != prev_end) { kv_push(ccline_colors->colors, ((CmdlineColorChunk) { - .start = prev_end, - .end = start, + .start = (int)prev_end, + .end = (int)start, .attr = 0, })); } @@ -2775,15 +2757,15 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) const int id = syn_name2id((char_u *)group); const int attr = (id == 0 ? 0 : syn_id2attr(id)); kv_push(ccline_colors->colors, ((CmdlineColorChunk) { - .start = start, - .end = end, + .start = (int)start, + .end = (int)end, .attr = attr, })); i++; }); if (prev_end < colored_ccline->cmdlen) { kv_push(ccline_colors->colors, ((CmdlineColorChunk) { - .start = prev_end, + .start = (int)prev_end, .end = colored_ccline->cmdlen, .attr = 0, })); @@ -2861,15 +2843,16 @@ static void draw_cmdline(int start, int len) goto draw_cmdline_no_arabicshape; } - static int buflen = 0; + static size_t buflen = 0; + assert(len >= 0); // Do arabic shaping into a temporary buffer. This is very // inefficient! - if (len * 2 + 2 > buflen) { + if ((size_t)len * 2 + 2 > buflen) { // Re-allocate the buffer. We keep it around to avoid a lot of // alloc()/free() calls. xfree(arshape_buf); - buflen = len * 2 + 2; + buflen = (size_t)len * 2 + 2; arshape_buf = xmalloc(buflen); } @@ -2927,7 +2910,7 @@ static void draw_cmdline(int start, int len) } } else { prev_c = u8c; - memmove(arshape_buf + newlen, p, mb_l); + memmove(arshape_buf + newlen, p, (size_t)mb_l); newlen += mb_l; } } @@ -2972,8 +2955,9 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) Array item = ARRAY_DICT_INIT; ADD(item, INTEGER_OBJ(chunk.attr)); + assert(chunk.end >= chunk.start); ADD(item, STRING_OBJ(cbuf_to_string((char *)line->cmdbuff + chunk.start, - chunk.end-chunk.start))); + (size_t)(chunk.end-chunk.start)))); ADD(content, ARRAY_OBJ(item)); } } else { @@ -2994,7 +2978,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) } } -void ui_ext_cmdline_block_append(int indent, const char *line) +void ui_ext_cmdline_block_append(size_t indent, const char *line) { char *buf = xmallocz(indent + strlen(line)); memset(buf, ' ', indent); @@ -3073,7 +3057,7 @@ void cmdline_ui_flush(void) * right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc. * "c" must be printable (fit in one display cell)! */ -void putcmdline(int c, int shift) +void putcmdline(char c, int shift) { if (cmd_silent) { return; @@ -3215,7 +3199,7 @@ void put_on_cmdline(char_u *str, int len, int redraw) c = cmdline_charsize(ccline.cmdpos); // count ">" for a double-wide char that doesn't fit. if (has_mbyte) { - correct_cmdspos(ccline.cmdpos, c); + correct_screencol(ccline.cmdpos, c, &ccline.cmdspos); } // Stop cursor at the end of the screen, but do increment the // insert position, so that entering a very long command @@ -3392,8 +3376,9 @@ void cmdline_paste_str(char_u *s, int literally) /// Delete characters on the command line, from "from" to the current position. static void cmdline_del(int from) { + assert(ccline.cmdpos <= ccline.cmdlen); memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos, - (size_t)ccline.cmdlen - ccline.cmdpos + 1); + (size_t)ccline.cmdlen - (size_t)ccline.cmdpos + 1); ccline.cmdlen -= ccline.cmdpos - from; ccline.cmdpos = from; } @@ -3428,7 +3413,7 @@ static void redrawcmdprompt(void) if (ccline.cmdprompt != NULL) { msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr); ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns; - // do the reverse of set_cmdspos() + // do the reverse of cmd_startcol() if (ccline.cmdfirstc != NUL) { ccline.cmdindent--; } @@ -3470,7 +3455,7 @@ void redrawcmd(void) msg_clr_eos(); msg_no_more = FALSE; - set_cmdspos_cursor(); + ccline.cmdspos = cmd_screencol(ccline.cmdpos); if (ccline.special_char != NUL) { putcmdline(ccline.special_char, ccline.special_shift); @@ -3514,15 +3499,17 @@ static void cursorcmd(void) } if (cmdmsg_rl) { - msg_row = cmdline_row + (ccline.cmdspos / (int)(Columns - 1)); - msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1; - if (msg_row <= 0) + msg_row = cmdline_row + (ccline.cmdspos / (Columns - 1)); + msg_col = Columns - (ccline.cmdspos % (Columns - 1)) - 1; + if (msg_row <= 0) { msg_row = Rows - 1; + } } else { - msg_row = cmdline_row + (ccline.cmdspos / (int)Columns); - msg_col = ccline.cmdspos % (int)Columns; - if (msg_row >= Rows) + msg_row = cmdline_row + (ccline.cmdspos / Columns); + msg_col = ccline.cmdspos % Columns; + if (msg_row >= Rows) { msg_row = Rows - 1; + } } ui_cursor_goto(msg_row, msg_col); @@ -3624,7 +3611,8 @@ nextwild ( } i = (int)(xp->xp_pattern - ccline.cmdbuff); - xp->xp_pattern_len = ccline.cmdpos - i; + assert(ccline.cmdpos >= i); + xp->xp_pattern_len = (size_t)ccline.cmdpos - (size_t)i; if (type == WILD_NEXT || type == WILD_PREV) { // Get next/previous match for a previous expanded pattern. @@ -3644,7 +3632,7 @@ nextwild ( xfree(p1); // Longest match: make sure it is not shorter, happens with :help. if (p2 != NULL && type == WILD_LONGEST) { - for (j = 0; j < xp->xp_pattern_len; j++) { + for (j = 0; (size_t)j < xp->xp_pattern_len; j++) { if (ccline.cmdbuff[i + j] == '*' || ccline.cmdbuff[i + j] == '?') { break; @@ -3657,14 +3645,15 @@ nextwild ( } if (p2 != NULL && !got_int) { - difflen = (int)STRLEN(p2) - xp->xp_pattern_len; + difflen = (int)STRLEN(p2) - (int)xp->xp_pattern_len; if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen) { realloc_cmdbuff(ccline.cmdlen + difflen + 4); xp->xp_pattern = ccline.cmdbuff + i; } + assert(ccline.cmdpos <= ccline.cmdlen); memmove(&ccline.cmdbuff[ccline.cmdpos + difflen], &ccline.cmdbuff[ccline.cmdpos], - (size_t)ccline.cmdlen - ccline.cmdpos + 1); + (size_t)ccline.cmdlen - (size_t)ccline.cmdpos + 1); memmove(&ccline.cmdbuff[i], p2, STRLEN(p2)); ccline.cmdlen += difflen; ccline.cmdpos += difflen; @@ -3861,7 +3850,7 @@ ExpandOne ( size_t len = 0; for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) { - mb_len = utfc_ptr2len(&xp->xp_files[0][len]); + mb_len = (size_t)utfc_ptr2len(&xp->xp_files[0][len]); int c0 = utf_ptr2char(&xp->xp_files[0][len]); for (i = 1; i < xp->xp_numfiles; i++) { int ci = utf_ptr2char(&xp->xp_files[i][len]); @@ -4100,7 +4089,8 @@ void cmdline_pum_display(bool changed_array) */ static int showmatches(expand_T *xp, int wildmenu) { -#define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m]) +#define L_SHOWFILE(m) (showtail \ + ? sm_gettail(files_found[m], false) : files_found[m]) int num_files; char_u **files_found; int i, j, k; @@ -4132,19 +4122,19 @@ static int showmatches(expand_T *xp, int wildmenu) || ui_has(kUIWildmenu); if (compl_use_pum) { + assert(num_files >= 0); compl_match_arraysize = num_files; - compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T)); + compl_match_array = xcalloc((size_t)compl_match_arraysize, + sizeof(pumitem_T)); for (i = 0; i < num_files; i++) { compl_match_array[i].pum_text = L_SHOWFILE(i); } - ssize_t offset = showtail ? sm_gettail(xp->xp_pattern)-xp->xp_pattern : 0; + char_u *endpos = (showtail + ? sm_gettail(xp->xp_pattern, true) : xp->xp_pattern); if (ui_has(kUICmdline)) { - compl_startcol = ccline.cmdpos - strnlen((char *)xp->xp_pattern+offset, - xp->xp_pattern_len-offset); + compl_startcol = (int)(endpos - ccline.cmdbuff); } else { - compl_startcol = ccline.cmdspos - - mb_string2cells_len(xp->xp_pattern+offset, - xp->xp_pattern_len-offset); + compl_startcol = cmd_screencol((int)(endpos - ccline.cmdbuff)); } compl_selected = -1; cmdline_pum_display(true); @@ -4180,14 +4170,15 @@ static int showmatches(expand_T *xp, int wildmenu) maxlen = j; } - if (xp->xp_context == EXPAND_TAGS_LISTFILES) + if (xp->xp_context == EXPAND_TAGS_LISTFILES) { lines = num_files; - else { - /* compute the number of columns and lines for the listing */ - maxlen += 2; /* two spaces between file names */ - columns = ((int)Columns + 2) / maxlen; - if (columns < 1) + } else { + // compute the number of columns and lines for the listing + maxlen += 2; // two spaces between file names + columns = (Columns + 2) / maxlen; + if (columns < 1) { columns = 1; + } lines = (num_files + columns - 1) / columns; } @@ -4276,7 +4267,7 @@ static int showmatches(expand_T *xp, int wildmenu) * Private path_tail for showmatches() (and win_redr_status_matches()): * Find tail of file name path, but ignore trailing "/". */ -char_u *sm_gettail(char_u *s) +char_u *sm_gettail(char_u *s, bool eager) { char_u *p; char_u *t = s; @@ -4287,9 +4278,13 @@ char_u *sm_gettail(char_u *s) #ifdef BACKSLASH_IN_FILENAME && !rem_backslash(p) #endif - ) - had_sep = TRUE; - else if (had_sep) { + ) { + if (eager) { + t = p+1; + } else { + had_sep = true; + } + } else if (had_sep) { t = p; had_sep = FALSE; } @@ -4329,24 +4324,20 @@ static int expand_showtail(expand_T *xp) return TRUE; } -/* - * Prepare a string for expansion. - * When expanding file names: The string will be used with expand_wildcards(). - * Copy "fname[len]" into allocated memory and add a '*' at the end. - * When expanding other names: The string will be used with regcomp(). Copy - * the name into allocated memory and prepend "^". - */ -char_u * -addstar ( - char_u *fname, - int len, - int context /* EXPAND_FILES etc. */ -) +/// Prepare a string for expansion. +/// +/// When expanding file names: The string will be used with expand_wildcards(). +/// Copy "fname[len]" into allocated memory and add a '*' at the end. +/// When expanding other names: The string will be used with regcomp(). Copy +/// the name into allocated memory and prepend "^". +/// +/// @param context EXPAND_FILES etc. +char_u *addstar(char_u *fname, size_t len, int context) FUNC_ATTR_NONNULL_RET { char_u *retval; - int i, j; - int new_len; + size_t i, j; + size_t new_len; char_u *tail; int ends_in_star; @@ -4437,9 +4428,10 @@ addstar ( tail = path_tail(retval); ends_in_star = (len > 0 && retval[len - 1] == '*'); #ifndef BACKSLASH_IN_FILENAME - for (i = len - 2; i >= 0; --i) { - if (retval[i] != '\\') + for (ssize_t k = (ssize_t)len - 2; k >= 0; k--) { + if (retval[k] != '\\') { break; + } ends_in_star = !ends_in_star; } #endif @@ -4520,7 +4512,7 @@ set_cmd_context ( int use_ccline // use ccline for info ) { - int old_char = NUL; + char_u old_char = NUL; /* * Avoid a UMR warning from Purify, only save the character if it has been @@ -4584,8 +4576,9 @@ expand_cmdline ( return EXPAND_NOTHING; } - /* add star to file name, or convert to regexp if not exp. files. */ - xp->xp_pattern_len = (int)(str + col - xp->xp_pattern); + // add star to file name, or convert to regexp if not exp. files. + assert((str + col) - xp->xp_pattern >= 0); + xp->xp_pattern_len = (size_t)((str + col) - xp->xp_pattern); file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context); if (p_wic) @@ -4875,7 +4868,7 @@ void ExpandGeneric( ) { int i; - int count = 0; + size_t count = 0; char_u *str; // count the number of matching names @@ -4891,7 +4884,8 @@ void ExpandGeneric( } if (count == 0) return; - *num_file = count; + assert(count < INT_MAX); + *num_file = (int)count; *file = (char_u **)xmalloc(count * sizeof(char_u *)); // copy the matching names into allocated memory @@ -4952,7 +4946,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, { char_u *pat; int i; - char_u *path; + char_u *path = NULL; garray_T ga; char_u *buf = xmalloc(MAXPATHL); size_t l; @@ -4971,15 +4965,14 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, flags |= EW_FILE | EW_EXEC | EW_SHELLCMD; bool mustfree = false; // Track memory allocation for *path. - // For an absolute name we don't use $PATH. - if (path_is_absolute(pat)) { - path = (char_u *)" "; - } else if (pat[0] == '.' && (vim_ispathsep(pat[1]) - || (pat[1] == '.' - && vim_ispathsep(pat[2])))) { + if (pat[0] == '.' && (vim_ispathsep(pat[1]) + || (pat[1] == '.' && vim_ispathsep(pat[2])))) { path = (char_u *)"."; } else { - path = (char_u *)vim_getenv("PATH"); + // For an absolute name we don't use $PATH. + if (!path_is_absolute(pat)) { + path = (char_u *)vim_getenv("PATH"); + } if (path == NULL) { path = (char_u *)""; } else { @@ -4993,6 +4986,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, * current directory, to find "subdir/cmd". */ ga_init(&ga, (int)sizeof(char *), 10); + hashtab_T found_ht; + hash_init(&found_ht); for (s = path; ; s = e) { if (*s == NUL) { if (did_curdir) { @@ -5004,17 +4999,15 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, did_curdir = true; } - if (*s == ' ') { - s++; // Skip space used for absolute path name. - } - - e = vim_strchr(s, ':'); - if (e == NULL) + e = vim_strchr(s, ENV_SEPCHAR); + if (e == NULL) { e = s + STRLEN(s); + } - l = e - s; - if (l > MAXPATHL - 5) + l = (size_t)(e - s); + if (l > MAXPATHL - 5) { break; + } STRLCPY(buf, s, l + 1); add_pathsep((char *)buf); l = STRLEN(buf); @@ -5025,14 +5018,24 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, if (ret == OK) { ga_grow(&ga, *num_file); { - for (i = 0; i < *num_file; ++i) { - s = (*file)[i]; - if (STRLEN(s) > l) { - /* Remove the path again. */ - STRMOVE(s, s + l); - ((char_u **)ga.ga_data)[ga.ga_len++] = s; - } else - xfree(s); + for (i = 0; i < *num_file; i++) { + char_u *name = (*file)[i]; + + if (STRLEN(name) > l) { + // Check if this name was already found. + hash_T hash = hash_hash(name + l); + hashitem_T *hi = + hash_lookup(&found_ht, (const char *)(name + l), + STRLEN(name + l), hash); + if (HASHITEM_EMPTY(hi)) { + // Remove the path that was prepended. + STRMOVE(name, name + l); + ((char_u **)ga.ga_data)[ga.ga_len++] = name; + hash_add_item(&found_ht, hi, name, hash); + name = NULL; + } + } + xfree(name); } xfree(*file); } @@ -5048,6 +5051,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, if (mustfree) { xfree(path); } + hash_clear(&found_ht); } /// Call "user_expand_func()" to invoke a user defined Vim script function and @@ -5055,9 +5059,9 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, static void * call_user_expand_func(user_expand_func_T user_expand_func, expand_T *xp, int *num_file, char_u ***file) { - int keep = 0; - char_u num[50]; - char_u *args[3]; + char_u keep = 0; + typval_T args[4]; + char_u *pat = NULL; int save_current_SID = current_SID; void *ret; struct cmdline_info save_ccline; @@ -5072,10 +5076,14 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, ccline.cmdbuff[ccline.cmdlen] = 0; } - args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len); - args[1] = xp->xp_line; - sprintf((char *)num, "%d", xp->xp_col); - args[2] = num; + pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len); + args[0].v_type = VAR_STRING; + args[1].v_type = VAR_STRING; + args[2].v_type = VAR_NUMBER; + args[3].v_type = VAR_UNKNOWN; + args[0].vval.v_string = pat; + args[1].vval.v_string = xp->xp_line; + args[2].vval.v_number = xp->xp_col; /* Save the cmdline, we don't know what the function may do. */ save_ccline = ccline; @@ -5085,7 +5093,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, ret = user_expand_func(xp->xp_arg, 3, - (const char_u * const *)args, + args, false); ccline = save_ccline; @@ -5093,7 +5101,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, if (ccline.cmdbuff != NULL) ccline.cmdbuff[ccline.cmdlen] = keep; - xfree(args[0]); + xfree(pat); return ret; } @@ -5117,14 +5125,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, e = vim_strchr(s, '\n'); if (e == NULL) e = s + STRLEN(s); - const int keep = *e; + const char_u keep = *e; *e = NUL; const bool skip = xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0; *e = keep; if (!skip) { - GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s))); + GA_APPEND(char_u *, &ga, vim_strnsave(s, (size_t)(e - s))); } if (*e != NUL) { @@ -5226,7 +5234,8 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, } s++; *e = NUL; - memmove(match, s, e - s + 1); + assert((e - s) + 1 >= 0); + memmove(match, s, (size_t)(e - s) + 1); } } @@ -5262,8 +5271,7 @@ static int ExpandPackAddDir(char_u *pat, int *num_file, char_u ***file) for (int i = 0; i < ga.ga_len; i++) { char_u *match = ((char_u **)ga.ga_data)[i]; s = path_tail(match); - char_u *e = s + STRLEN(s); - memmove(match, s, e - s + 1); + memmove(match, s, STRLEN(s)+1); } if (GA_EMPTY(&ga)) { @@ -5407,7 +5415,9 @@ void init_history(void) // On copying them to the new arrays, we take the chance to reorder them. if (newlen != oldlen) { for (int type = 0; type < HIST_COUNT; type++) { - histentry_T *temp = newlen ? xmalloc(newlen * sizeof(*temp)) : NULL; + histentry_T *temp = (newlen + ? xmalloc((size_t)newlen * sizeof(*temp)) + : NULL); int j = hisidx[type]; if (j >= 0) { @@ -5572,7 +5582,6 @@ add_to_history ( ) { histentry_T *hisptr; - int len; if (hislen == 0 || histype == HIST_INVALID) { // no history return; @@ -5604,12 +5613,12 @@ add_to_history ( hisptr = &history[histype][hisidx[histype]]; hist_free_entry(hisptr); - /* Store the separator after the NUL of the string. */ - len = (int)STRLEN(new_entry); + // Store the separator after the NUL of the string. + size_t len = STRLEN(new_entry); hisptr->hisstr = vim_strnsave(new_entry, len + 2); hisptr->timestamp = os_time(); hisptr->additional_elements = NULL; - hisptr->hisstr[len + 1] = sep; + hisptr->hisstr[len + 1] = (char_u)sep; hisptr->hisnum = ++hisnum[histype]; if (histype == HIST_SEARCH && in_map) @@ -5663,7 +5672,7 @@ char_u *get_cmdline_str(void) if (p == NULL) return NULL; - return vim_strnsave(p->cmdbuff, p->cmdlen); + return vim_strnsave(p->cmdbuff, (size_t)p->cmdlen); } /* @@ -5932,7 +5941,7 @@ void ex_history(exarg_T *eap) while (ASCII_ISALPHA(*end) || vim_strchr((char_u *)":=@>/?", *end) != NULL) end++; - histype1 = get_histtype((const char *)arg, end - arg, false); + histype1 = get_histtype((const char *)arg, (size_t)(end - arg), false); if (histype1 == HIST_INVALID) { if (STRNICMP(arg, "all", end - arg) == 0) { histype1 = 0; @@ -5971,13 +5980,14 @@ void ex_history(exarg_T *eap) if (hist[i].hisstr != NULL && hist[i].hisnum >= j && hist[i].hisnum <= k) { msg_putchar('\n'); - sprintf((char *)IObuff, "%c%6d ", i == idx ? '>' : ' ', - hist[i].hisnum); - if (vim_strsize(hist[i].hisstr) > (int)Columns - 10) + snprintf((char *)IObuff, IOSIZE, "%c%6d ", i == idx ? '>' : ' ', + hist[i].hisnum); + if (vim_strsize(hist[i].hisstr) > Columns - 10) { trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff), - (int)Columns - 10, IOSIZE - (int)STRLEN(IObuff)); - else + Columns - 10, IOSIZE - (int)STRLEN(IObuff)); + } else { STRCAT(IObuff, hist[i].hisstr); + } msg_outtrans(IObuff); ui_flush(); } @@ -6138,8 +6148,8 @@ static int open_cmdwin(void) State = NORMAL; setmouse(); - /* Trigger CmdwinEnter autocommands. */ - typestr[0] = cmdwin_type; + // Trigger CmdwinEnter autocommands. + typestr[0] = (char_u)cmdwin_type; typestr[1] = NUL; apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf); if (restart_edit != 0) /* autocmd with ":startinsert" */ @@ -6217,7 +6227,7 @@ static int open_cmdwin(void) if (ccline.cmdpos > ccline.cmdlen) ccline.cmdpos = ccline.cmdlen; if (cmdwin_result == K_IGNORE) { - set_cmdspos_cursor(); + ccline.cmdspos = cmd_screencol(ccline.cmdpos); redrawcmd(); } } |
