diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 03:56:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 03:56:56 +0000 |
commit | 75a9fa68f6cdd6769813a8c5e055bfb00a08c089 (patch) | |
tree | daf1676b4e5ea491b7a370467a24b8181cc21827 /src/normal.c | |
parent | Adding upstream version 2:9.1.0377. (diff) | |
download | vim-75a9fa68f6cdd6769813a8c5e055bfb00a08c089.tar.xz vim-75a9fa68f6cdd6769813a8c5e055bfb00a08c089.zip |
Adding upstream version 2:9.1.0496.upstream/2%9.1.0496
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/normal.c')
-rw-r--r-- | src/normal.c | 152 |
1 files changed, 98 insertions, 54 deletions
diff --git a/src/normal.c b/src/normal.c index fef2826..b55d941 100644 --- a/src/normal.c +++ b/src/normal.c @@ -61,7 +61,7 @@ static void nv_end(cmdarg_T *cap); static void nv_dollar(cmdarg_T *cap); static void nv_search(cmdarg_T *cap); static void nv_next(cmdarg_T *cap); -static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrapped); +static int normal_search(cmdarg_T *cap, int dir, char_u *pat, size_t patlen, int opt, int *wrapped); static void nv_csearch(cmdarg_T *cap); static void nv_brackets(cmdarg_T *cap); static void nv_percent(cmdarg_T *cap); @@ -2169,6 +2169,7 @@ find_decl( int flags_arg) // flags passed to searchit() { char_u *pat; + size_t patlen; pos_T old_pos; pos_T par_pos; pos_T found_pos; @@ -2185,8 +2186,9 @@ find_decl( // Put "\V" before the pattern to avoid that the special meaning of "." // and "~" causes trouble. - sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", - len, ptr); + patlen = vim_snprintf((char *)pat, len + 7, + vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", len, ptr); + old_pos = curwin->w_cursor; save_p_ws = p_ws; save_p_scs = p_scs; @@ -2215,7 +2217,7 @@ find_decl( for (;;) { t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD, - pat, 1L, searchflags, RE_LAST, NULL); + pat, patlen, 1L, searchflags, RE_LAST, NULL); if (curwin->w_cursor.lnum >= old_pos.lnum) t = FAIL; // match after start is failure too @@ -2593,7 +2595,7 @@ nv_zg_zw(cmdarg_T *cap, int nchar) // off this fails and find_ident_under_cursor() is // used below. emsg_off++; - len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); + len = spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, NULL); emsg_off--; if (len != 0 && curwin->w_cursor.col <= pos.col) ptr = ml_get_pos(&curwin->w_cursor); @@ -3332,7 +3334,8 @@ nv_K_getcmd( char_u **ptr_arg, int n, char_u *buf, - unsigned buflen) + size_t bufsize, + size_t *buflen) { char_u *ptr = *ptr_arg; int isman; @@ -3342,6 +3345,7 @@ nv_K_getcmd( { // in the help buffer STRCPY(buf, "he! "); + *buflen = STRLEN_LITERAL("he! "); return n; } @@ -3349,10 +3353,9 @@ nv_K_getcmd( { // 'keywordprog' is an ex command if (cap->count0 != 0) - vim_snprintf((char *)buf, buflen, "%s %ld", kp, cap->count0); + *buflen = vim_snprintf((char *)buf, bufsize, "%s %ld ", kp, cap->count0); else - STRCPY(buf, kp); - STRCAT(buf, " "); + *buflen = vim_snprintf((char *)buf, bufsize, "%s ", kp); return n; } @@ -3377,19 +3380,16 @@ nv_K_getcmd( isman = (STRCMP(kp, "man") == 0); isman_s = (STRCMP(kp, "man -s") == 0); if (cap->count0 != 0 && !(isman || isman_s)) - sprintf((char *)buf, ".,.+%ld", cap->count0 - 1); + *buflen = vim_snprintf((char *)buf, bufsize, ".,.+%ld! ", cap->count0 - 1); + else + *buflen = vim_snprintf((char *)buf, bufsize, "! "); - STRCAT(buf, "! "); if (cap->count0 == 0 && isman_s) - STRCAT(buf, "man"); + *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "man "); else - STRCAT(buf, kp); - STRCAT(buf, " "); + *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%s ", kp); if (cap->count0 != 0 && (isman || isman_s)) - { - sprintf((char *)buf + STRLEN(buf), "%ld", cap->count0); - STRCAT(buf, " "); - } + *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%ld ", cap->count0); *ptr_arg = ptr; return n; @@ -3408,7 +3408,8 @@ nv_ident(cmdarg_T *cap) { char_u *ptr = NULL; char_u *buf; - unsigned buflen; + size_t bufsize; + size_t buflen; char_u *newbuf; char_u *p; char_u *kp; // value of 'keywordprg' @@ -3463,11 +3464,12 @@ nv_ident(cmdarg_T *cap) return; } kp_ex = (*kp == ':'); - buflen = (unsigned)(n * 2 + 30 + STRLEN(kp)); - buf = alloc(buflen); + bufsize = (size_t)(n * 2 + 30 + STRLEN(kp)); + buf = alloc(bufsize); if (buf == NULL) return; buf[0] = NUL; + buflen = 0; switch (cmdchar) { @@ -3481,12 +3483,15 @@ nv_ident(cmdarg_T *cap) curwin->w_cursor.col = (colnr_T) (ptr - ml_get_curline()); if (!g_cmd && vim_iswordp(ptr)) + { STRCPY(buf, "\\<"); + buflen = STRLEN_LITERAL("\\<"); + } no_smartcase = TRUE; // don't use 'smartcase' now break; case 'K': - n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, buflen); + n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, bufsize, &buflen); if (n == 0) return; break; @@ -3495,30 +3500,47 @@ nv_ident(cmdarg_T *cap) tag_cmd = TRUE; #ifdef FEAT_CSCOPE if (p_cst) + { STRCPY(buf, "cstag "); + buflen = STRLEN_LITERAL("cstag "); + } else #endif + { STRCPY(buf, "ts "); + buflen = STRLEN_LITERAL("ts "); + } break; default: tag_cmd = TRUE; if (curbuf->b_help) + { STRCPY(buf, "he! "); + buflen = STRLEN_LITERAL("he! "); + } else { if (g_cmd) + { STRCPY(buf, "tj "); + buflen = STRLEN_LITERAL("tj "); + } else if (cap->count0 == 0) + { STRCPY(buf, "ta "); + buflen = STRLEN_LITERAL("ta "); + } else - sprintf((char *)buf, ":%ldta ", cap->count0); + buflen = vim_snprintf((char *)buf, bufsize, ":%ldta ", cap->count0); } } // Now grab the chars in the identifier if (cmdchar == 'K' && !kp_help) { + size_t plen; + ptr = vim_strnsave(ptr, n); if (kp_ex) // Escape the argument properly for an Ex command @@ -3532,7 +3554,8 @@ nv_ident(cmdarg_T *cap) vim_free(buf); return; } - newbuf = vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1); + plen = STRLEN(p); + newbuf = vim_realloc(buf, buflen + plen + 1); if (newbuf == NULL) { vim_free(buf); @@ -3540,7 +3563,8 @@ nv_ident(cmdarg_T *cap) return; } buf = newbuf; - STRCAT(buf, p); + STRCPY(buf + buflen, p); + buflen += plen; vim_free(p); } else @@ -3560,12 +3584,13 @@ nv_ident(cmdarg_T *cap) else aux_ptr = (char_u *)"\\|\"\n*?["; - p = buf + STRLEN(buf); + p = buf + buflen; while (n-- > 0) { // put a backslash before \ and some others if (vim_strchr(aux_ptr, *ptr) != NULL) *p++ = '\\'; + // When current byte is a part of multibyte character, copy all // bytes of that character. if (has_mbyte) @@ -3579,6 +3604,7 @@ nv_ident(cmdarg_T *cap) *p++ = *ptr++; } *p = NUL; + buflen = p - buf; } // Execute the command. @@ -3587,13 +3613,16 @@ nv_ident(cmdarg_T *cap) if (!g_cmd && (has_mbyte ? vim_iswordp(mb_prevptr(ml_get_curline(), ptr)) : vim_iswordc(ptr[-1]))) - STRCAT(buf, "\\>"); + { + STRCPY(buf + buflen, "\\>"); + buflen += STRLEN_LITERAL("\\>"); + } // put pattern in search history init_history(); - add_to_history(HIST_SEARCH, buf, TRUE, NUL); + add_to_history(HIST_SEARCH, buf, buflen, TRUE, NUL); - (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL); + (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, buflen, 0, NULL); } else { @@ -4117,7 +4146,7 @@ nv_search(cmdarg_T *cap) return; } - (void)normal_search(cap, cap->cmdchar, cap->searchbuf, + (void)normal_search(cap, cap->cmdchar, cap->searchbuf, STRLEN(cap->searchbuf), (cap->arg || !EQUAL_POS(save_cursor, curwin->w_cursor)) ? 0 : SEARCH_MARK, NULL); } @@ -4132,7 +4161,7 @@ nv_next(cmdarg_T *cap) { pos_T old = curwin->w_cursor; int wrapped = FALSE; - int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, &wrapped); + int i = normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, &wrapped); if (i == 1 && !wrapped && EQUAL_POS(old, curwin->w_cursor)) { @@ -4140,7 +4169,7 @@ nv_next(cmdarg_T *cap) // happen when an offset is given and the cursor is on the last char // in the buffer: Repeat with count + 1. cap->count1 += 1; - (void)normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, NULL); + (void)normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, NULL); cap->count1 -= 1; } @@ -4161,6 +4190,7 @@ normal_search( cmdarg_T *cap, int dir, char_u *pat, + size_t patlen, int opt, // extra flags for do_search() int *wrapped) { @@ -4176,7 +4206,7 @@ normal_search( curwin->w_set_curswant = TRUE; CLEAR_FIELD(sia); - i = do_search(cap->oap, dir, dir, pat, cap->count1, + i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1, opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia); if (wrapped != NULL) *wrapped = sia.sa_wrapped; @@ -4201,6 +4231,7 @@ normal_search( // "/$" will put the cursor after the end of the line, may need to // correct that here check_cursor(); + return i; } @@ -4529,13 +4560,15 @@ nv_brackets(cmdarg_T *cap) #endif #ifdef FEAT_SPELL - // "[s", "[S", "]s" and "]S": move to next spell error. - else if (cap->nchar == 's' || cap->nchar == 'S') + // "[r", "[s", "[S", "]r", "]s" and "]S": move to next spell error. + else if (cap->nchar == 'r' || cap->nchar == 's' || cap->nchar == 'S') { setpcmark(); for (n = 0; n < cap->count1; ++n) if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD, - cap->nchar == 's' ? TRUE : FALSE, FALSE, NULL) == 0) + cap->nchar == 's' ? SMT_ALL : + cap->nchar == 'r' ? SMT_RARE : + SMT_BAD, FALSE, NULL) == 0) { clearopbeep(cap->oap); break; @@ -6663,29 +6696,40 @@ adjust_for_sel(cmdarg_T *cap) int unadjust_for_sel(void) { - pos_T *pp; - if (*p_sel == 'e' && !EQUAL_POS(VIsual, curwin->w_cursor)) + return unadjust_for_sel_inner(LT_POS(VIsual, curwin->w_cursor) + ? &curwin->w_cursor : &VIsual); + return FALSE; +} + +/* + * Move position "*pp" back one character for 'selection' == "exclusive". + * Returns TRUE when backed up to the previous line. + */ + int +unadjust_for_sel_inner(pos_T *pp) +{ + colnr_T cs, ce; + + if (pp->coladd > 0) + --pp->coladd; + else if (pp->col > 0) { - if (LT_POS(VIsual, curwin->w_cursor)) - pp = &curwin->w_cursor; - else - pp = &VIsual; - if (pp->coladd > 0) - --pp->coladd; - else - if (pp->col > 0) - { - --pp->col; - mb_adjustpos(curbuf, pp); - } - else if (pp->lnum > 1) + --pp->col; + mb_adjustpos(curbuf, pp); + if (virtual_active()) { - --pp->lnum; - pp->col = ml_get_len(pp->lnum); - return TRUE; + getvcol(curwin, pp, &cs, NULL, &ce); + pp->coladd = ce - cs; } } + else if (pp->lnum > 1) + { + --pp->lnum; + pp->col = ml_get_len(pp->lnum); + return TRUE; + } + return FALSE; } |