From a952575c3bb8e23cccaaeb91bc5cc0cb908cb02c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 May 2026 09:35:27 +0800 Subject: [PATCH] vim-patch:9.2.0506: home_replace() function can be improved (#39925) Problem: home_replace() function can be improved Solution: Refactor home_replace() to return the length of the string (John Marriott). In addition: - in function set_b0_fname() move ulen into the block where it is used. - In function findswapname() rework logic around displaying "swap file already exists" dialogue so that literal message text is set once. closes: vim/vim#20249 https://github.com/vim/vim/commit/a0931a90eeee6692556f330b5ba1fb413f9ea85d Co-authored-by: John Marriott --- src/nvim/buffer.c | 5 ++--- src/nvim/eval/fs.c | 17 +++++++++++------ src/nvim/fileio.c | 11 ++++++----- src/nvim/memline.c | 5 ++--- src/nvim/shada.c | 3 +-- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5ef7cda17a..09993d03de 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3317,9 +3317,8 @@ void fileinfo(int fullname, int shorthelp, bool dont_truncate) IOSIZE - bufferlen, "%s", name); } else { name = (!fullname && curbuf->b_fname != NULL) ? curbuf->b_fname : curbuf->b_ffname; - home_replace(shorthelp ? curbuf : NULL, name, buffer + bufferlen, - IOSIZE - bufferlen, true); - bufferlen += strlen(buffer + bufferlen); + bufferlen += home_replace(shorthelp ? curbuf : NULL, name, + buffer + bufferlen, IOSIZE - bufferlen, true); } bool dontwrite = bt_dontwrite(curbuf); diff --git a/src/nvim/eval/fs.c b/src/nvim/eval/fs.c index 8bf7414d8e..121897c84b 100644 --- a/src/nvim/eval/fs.c +++ b/src/nvim/eval/fs.c @@ -161,19 +161,24 @@ repeat: has_fullname = false; if (p != NULL) { + size_t dirnamelen = 0; + if (c == '.') { os_dirname(dirname, MAXPATHL); if (has_homerelative) { s = xstrdup(dirname); - home_replace(NULL, s, dirname, MAXPATHL, true); + dirnamelen = home_replace(NULL, s, dirname, MAXPATHL, true); xfree(s); } - size_t namelen = strlen(dirname); + + if (dirnamelen == 0) { + dirnamelen = strlen(dirname); + } // Do not call shorten_fname() here since it removes the prefix // even though the path does not have a prefix. - if (path_fnamencmp(p, dirname, namelen) == 0) { - p += namelen; + if (path_fnamencmp(p, dirname, dirnamelen) == 0) { + p += dirnamelen; if (vim_ispathsep(*p)) { while (*p && vim_ispathsep(*p)) { p++; @@ -188,10 +193,10 @@ repeat: } } } else { - home_replace(NULL, p, dirname, MAXPATHL, true); + dirnamelen = home_replace(NULL, p, dirname, MAXPATHL, true); // Only replace it when it starts with '~' if (*dirname == '~') { - s = xstrdup(dirname); + s = xmemdupz(dirname, dirnamelen); assert(s != NULL); // suppress clang "Argument with 'nonnull' attribute passed null" *fnamep = s; xfree(*bufp); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 7b0d4c6d26..1b6c6e44ba 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2154,19 +2154,20 @@ int set_rw_fname(char *fname, char *sfname) /// Replaces home directory at the start with `~`. /// /// @param[out] ret_buf Buffer to save results to. -/// @param[in] buf_len ret_buf length. +/// @param[in] bufsize ret_buf size. /// @param[in] buf buf_T file name is coming from. /// @param[in] fname File name to write. -void add_quoted_fname(char *const ret_buf, const size_t buf_len, const buf_T *const buf, +void add_quoted_fname(char *const ret_buf, const size_t bufsize, const buf_T *const buf, const char *fname) FUNC_ATTR_NONNULL_ARG(1) { if (fname == NULL) { fname = "-stdin-"; } - ret_buf[0] = '"'; - home_replace(buf, fname, ret_buf + 1, buf_len - 4, true); - xstrlcat(ret_buf, "\" ", buf_len); + size_t len = 0; + ret_buf[len++] = '"'; + len += home_replace(buf, fname, ret_buf + len, bufsize - 4, true); + xstrlcpy(ret_buf + len, "\" ", bufsize - len); } /// Append message for text mode to IObuff. diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 371b4013c8..a4ec90fd95 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -669,13 +669,12 @@ static void set_b0_fname(ZeroBlock *b0p, buf_T *buf) // editing the same file on different machines over a network. // First replace home dir path with "~/" with home_replace(). // Then insert the user name to get "~user/". - home_replace(NULL, buf->b_ffname, b0p->b0_fname, - B0_FNAME_SIZE_CRYPT, true); + size_t flen = home_replace(NULL, buf->b_ffname, b0p->b0_fname, + B0_FNAME_SIZE_CRYPT, true); if (b0p->b0_fname[0] == '~') { // If there is no user name or it is too long, don't use "~/" int retval = os_get_username(uname, B0_UNAME_SIZE); size_t ulen = strlen(uname); - size_t flen = strlen(b0p->b0_fname); if (retval == FAIL || ulen + flen > B0_FNAME_SIZE_CRYPT - 1) { xstrlcpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT); } else { diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 4ca8ead9fa..3d0ef49bf8 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -3538,8 +3538,7 @@ static bool shada_removable(const char *name) for (char *p = p_shada; *p;) { copy_option_part(&p, part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { - home_replace(NULL, part + 1, NameBuff, MAXPATHL, true); - size_t n = strlen(NameBuff); + size_t n = home_replace(NULL, part + 1, NameBuff, MAXPATHL, true); if (mb_strnicmp(NameBuff, new_name, n) == 0) { retval = true; break;