diff options
author | zeertzjq <zeertzjq@outlook.com> | 2025-02-27 08:44:42 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2025-02-27 08:55:14 +0800 |
commit | e1a3128ec4312f537479bbe4dcd789599ac054fc (patch) | |
tree | c0cffbff8425b9377aff95bd9ad0f4a10acda352 | |
parent | 3cce6570312830dfab9efd9d521125f0049ad55f (diff) | |
download | rneovim-e1a3128ec4312f537479bbe4dcd789599ac054fc.tar.gz rneovim-e1a3128ec4312f537479bbe4dcd789599ac054fc.tar.bz2 rneovim-e1a3128ec4312f537479bbe4dcd789599ac054fc.zip |
vim-patch:9.1.1151: too many strlen() calls in getchar.c
Problem: too many strlen() calls in getchar.c
Solution: store last inserted and recorded lengths,
add functions to retrieve those and use those
functions (John Marriott)
closes: vim/vim#16720
https://github.com/vim/vim/commit/d3c4b7e9461f90bad7a671c1221d65def9cccc89
Co-authored-by: John Marriott <basilisk@internode.on.net>
-rw-r--r-- | src/nvim/edit.c | 8 | ||||
-rw-r--r-- | src/nvim/getchar.c | 38 | ||||
-rw-r--r-- | src/nvim/ops.c | 5 |
3 files changed, 36 insertions, 15 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index af3471184d..223b0acbc0 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -339,7 +339,7 @@ static void insert_enter(InsertState *s) if (s->ptr == NULL) { new_insert_skip = 0; } else { - new_insert_skip = (int)strlen(s->ptr); + new_insert_skip = (int)get_inserted_len(); xfree(s->ptr); } @@ -2342,7 +2342,7 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) // Don't do it when "restart_edit" was set and nothing was inserted, // otherwise CTRL-O w and then <Left> will clear "last_insert". char *ptr = get_inserted(); - int added = ptr == NULL ? 0 : (int)strlen(ptr) - new_insert_skip; + int added = ptr == NULL ? 0 : (int)get_inserted_len() - new_insert_skip; if (did_restart_edit == 0 || added > 0) { xfree(last_insert); last_insert = ptr; @@ -2772,8 +2772,8 @@ char *get_last_insert_save(void) if (last_insert == NULL) { return NULL; } - char *s = xstrdup(last_insert + last_insert_skip); - int len = (int)strlen(s); + size_t len = strlen(last_insert + last_insert_skip); + char *s = xmemdupz(last_insert + last_insert_skip, len); if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC s[len - 1] = NUL; } diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 0817d40bb8..abdc83eb3d 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -155,6 +155,11 @@ static uint8_t noremapbuf_init[TYPELEN_INIT]; ///< initial typebuf.tb_noremap static size_t last_recorded_len = 0; ///< number of last recorded chars +static size_t last_get_recorded_len = 0; ///< length of the string returned from the + ///< last call to get_recorded() +static size_t last_get_inserted_len = 0; ///< length of the string returned from the + ///< last call to get_inserted() + enum { KEYLEN_PART_KEY = -1, ///< keylen value for incomplete key-code KEYLEN_PART_MAP = -2, ///< keylen value for incomplete mapping @@ -225,31 +230,48 @@ static char *get_buffcont(buffheader_T *buffer, int dozero, size_t *len) /// K_SPECIAL in the returned string is escaped. char *get_recorded(void) { - size_t len; - char *p = get_buffcont(&recordbuff, true, &len); + char *p = get_buffcont(&recordbuff, true, &last_get_recorded_len); + if (p == NULL) { + return NULL; + } + free_buff(&recordbuff); // Remove the characters that were added the last time, these must be the // (possibly mapped) characters that stopped the recording. - if (len >= last_recorded_len) { - len -= last_recorded_len; - p[len] = NUL; + if (last_get_recorded_len >= last_recorded_len) { + last_get_recorded_len -= last_recorded_len; + p[last_get_recorded_len] = NUL; } // When stopping recording from Insert mode with CTRL-O q, also remove the // CTRL-O. - if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) { - p[len - 1] = NUL; + if (last_get_recorded_len > 0 && restart_edit != 0 + && p[last_get_recorded_len - 1] == Ctrl_O) { + last_get_recorded_len--; + p[last_get_recorded_len] = NUL; } return p; } +/// Return the length of string returned from the last call of get_recorded(). +size_t get_recorded_len(void) +{ + return last_get_recorded_len; +} + /// Return the contents of the redo buffer as a single string. /// K_SPECIAL in the returned string is escaped. char *get_inserted(void) { - return get_buffcont(&redobuff, false, NULL); + return get_buffcont(&redobuff, false, &last_get_inserted_len); +} + +/// Return the length of string returned from the last call of get_inserted(). +size_t get_inserted_len(void) +{ + return last_get_inserted_len; } /// Add string after the current block of the given buffer diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 72c75534d4..f60a6d50c9 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1039,7 +1039,7 @@ int do_record(int c) // restore the current register name. yankreg_T *old_y_previous = y_previous; - retval = stuff_yank(regname, p); + retval = stuff_yank(regname, p, get_recorded_len()); y_previous = old_y_previous; } @@ -1051,7 +1051,7 @@ int do_record(int c) /// uppercase). "p" must have been allocated. /// /// @return FAIL for failure, OK otherwise -static int stuff_yank(int regname, char *p) +static int stuff_yank(int regname, char *p, size_t plen) { // check for read-only register if (regname != 0 && !valid_yank_reg(regname, true)) { @@ -1063,7 +1063,6 @@ static int stuff_yank(int regname, char *p) return OK; } - const size_t plen = strlen(p); yankreg_T *reg = get_yank_register(regname, YREG_YANK); if (is_append_register(regname) && reg->y_array != NULL) { String *pp = &(reg->y_array[reg->y_size - 1]); |