patch 9.2.0506: home_replace() function can be improved

Commit: 
https://github.com/vim/vim/commit/a0931a90eeee6692556f330b5ba1fb413f9ea85d
Author: John Marriott <[email protected]>
Date:   Wed May 20 18:38:55 2026 +0000

    patch 9.2.0506: home_replace() function can be improved
    
    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: #20249
    
    Signed-off-by: John Marriott <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/buffer.c b/src/buffer.c
index 43cba3ad8..a903ab375 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3948,9 +3948,8 @@ fileinfo(
            name = curbuf->b_fname;
        else
            name = curbuf->b_ffname;
-       home_replace(shorthelp ? curbuf : NULL, name, (char_u *)buffer + 
bufferlen,
-                                         IOSIZE - (int)bufferlen, TRUE);
-       bufferlen += STRLEN(buffer + bufferlen);
+       bufferlen += home_replace(shorthelp ? curbuf : NULL, name,
+           (char_u *)buffer + bufferlen, IOSIZE - (int)bufferlen, TRUE);
     }
 
     bufferlen += vim_snprintf_safelen(
diff --git a/src/fileio.c b/src/fileio.c
index 1a7ee9b94..af0360dc8 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3200,11 +3200,13 @@ set_rw_fname(char_u *fname, char_u *sfname)
     void
 msg_add_fname(buf_T *buf, char_u *fname)
 {
+    size_t  IObufflen = 0;
+
     if (fname == NULL)
        fname = (char_u *)"-stdin-";
-    home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
-    IObuff[0] = '"';
-    STRCAT(IObuff, "\" ");
+    IObuff[IObufflen++] = '"';
+    IObufflen += home_replace(buf, fname, IObuff + IObufflen, IOSIZE - 4, 
TRUE);
+    STRCPY(IObuff + IObufflen, "\" ");
 }
 
 /*
diff --git a/src/filepath.c b/src/filepath.c
index a41f8c27f..8bdba335c 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -442,27 +442,29 @@ repeat:
 
        if (p != NULL)
        {
+           size_t  dirnamelen = 0;
+
            if (c == '.')
            {
-               size_t  namelen;
-
                mch_dirname(dirname, MAXPATHL);
                if (has_homerelative)
                {
                    s = vim_strsave(dirname);
                    if (s != NULL)
                    {
-                       home_replace(NULL, s, dirname, MAXPATHL, TRUE);
+                       dirnamelen = home_replace(NULL, s, dirname, MAXPATHL, 
TRUE);
                        vim_free(s);
                    }
                }
-               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 (fnamencmp(p, dirname, namelen) == 0)
+               if (fnamencmp(p, dirname, dirnamelen) == 0)
                {
-                   p += namelen;
+                   p += dirnamelen;
                    if (vim_ispathsep(*p))
                    {
                        while (*p && vim_ispathsep(*p))
@@ -480,11 +482,11 @@ 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 = vim_strsave(dirname);
+                   s = vim_strnsave(dirname, dirnamelen);
                    if (s != NULL)
                    {
                        *fnamep = s;
@@ -2724,7 +2726,7 @@ f_filecopy(typval_T *argvars, typval_T *rettv)
  * 'src'.
  * If anything fails (except when out of space) dst equals src.
  */
-    void
+    size_t
 home_replace(
     buf_T      *buf,   // when not NULL, check for help files
     char_u     *src,   // input file name
@@ -2737,21 +2739,19 @@ home_replace(
     size_t     len;
     char_u     *homedir_env, *homedir_env_orig;
     char_u     *p;
+    char_u     *dst_start;
 
     if (src == NULL)
     {
        *dst = NUL;
-       return;
+       return 0;
     }
 
     /*
      * If the file is a help file, remove the path completely.
      */
     if (buf != NULL && buf->b_help)
-    {
-       vim_snprintf((char *)dst, dstlen, "%s", gettail(src));
-       return;
-    }
+       return vim_snprintf_safelen((char *)dst, dstlen, "%s", gettail(src));
 
     /*
      * We check both the value of the $HOME environment variable and the
@@ -2793,6 +2793,7 @@ home_replace(
 
     if (!one)
        src = skipwhite(src);
+    dst_start = dst;           // remember the start
     while (*src && dstlen > 0)
     {
        /*
@@ -2842,6 +2843,8 @@ home_replace(
 
     if (homedir_env != homedir_env_orig)
        vim_free(homedir_env);
+
+    return (size_t)(dst - dst_start);
 }
 
 /*
diff --git a/src/memline.c b/src/memline.c
index ffd3fbd72..51b09cc1c 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -1021,7 +1021,7 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf)
        forward_slash(b0p->b0_fname);
 # endif
 #else
-       size_t  flen, ulen;
+       size_t  flen;
        char_u  uname[B0_UNAME_SIZE];
 
        /*
@@ -1031,11 +1031,12 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf)
         * 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,
+       flen = home_replace(NULL, buf->b_ffname, b0p->b0_fname,
                                                   B0_FNAME_SIZE_CRYPT, TRUE);
        if (b0p->b0_fname[0] == '~')
        {
-           flen = STRLEN(b0p->b0_fname);
+           size_t  ulen;
+
            // If there is no user name or it is too long, don't use "~/"
            if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
                   || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
@@ -5343,24 +5344,32 @@ findswapname(
                    if (swap_exists_action != SEA_NONE
                                                  && choice == SEA_CHOICE_NONE)
                    {
-                       char_u  *name;
-                       int     dialog_result;
-                       size_t  len = STRLEN(_("Swap file \""));
-
-                       name = alloc(STRLEN(fname)
-                               + len
-                               + STRLEN(_("\" already exists!")) + 5);
-                       if (name != NULL)
+                       string_T    prefix = {(char_u *)_("Swap file \""), 0};
+                       string_T    suffix = {(char_u *)_("\" already 
exists!"), 0};
+                       size_t      message_size;
+                       string_T    message;
+                       char_u      *tofree;
+                       int         dialog_result;
+
+                       prefix.length = STRLEN(prefix.string);
+                       suffix.length = STRLEN(suffix.string);
+                       message_size = prefix.length
+                               + STRLEN(fname)
+                               + suffix.length + 5;
+                       message.string = tofree = alloc(message_size);
+                       if (message.string != NULL)
                        {
-                           STRCPY(name, _("Swap file \""));
-                           home_replace(NULL, fname, name + len, 1000, TRUE);
-                           STRCAT(name, _("\" already exists!"));
+                           STRCPY(message.string, prefix.string);
+                           message.length = prefix.length;
+                           message.length += home_replace(NULL, fname,
+                               message.string + message.length, 
(int)(message_size - message.length), TRUE);
+                           STRCPY(message.string + message.length, 
suffix.string);
                        }
+                       else
+                           message.string = (char_u *)_("Swap file already 
exists!");
                        dialog_result = do_dialog(VIM_WARNING,
                                    (char_u *)_("VIM - ATTENTION"),
-                                   name == NULL
-                                       ?  (char_u *)_("Swap file already 
exists!")
-                                       : name,
+                                   message.string,
 # ifdef HAVE_PROCESS_STILL_RUNNING
                                    process_still_running
                                        ? (char_u *)_("&Open Read-Only
&Edit anyway
&Recover
&Quit
&Abort") :
@@ -5373,7 +5382,7 @@ findswapname(
                            dialog_result++;
 # endif
                        choice = dialog_result;
-                       vim_free(name);
+                       vim_free(tofree);
 
                        // pretend screen didn't scroll, need redraw anyway
                        msg_scrolled = 0;
diff --git a/src/po/vim.pot b/src/po/vim.pot
index 2057c23a9..e5cf8c102 100644
--- a/src/po/vim.pot
+++ b/src/po/vim.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim
"
 "Report-Msgid-Bugs-To: [email protected]
"
-"POT-Creation-Date: 2026-05-19 18:20+0000
"
+"POT-Creation-Date: 2026-05-20 18:41+0000
"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
 "Language-Team: LANGUAGE <[email protected]>
"
@@ -2169,10 +2169,10 @@ msgstr ""
 msgid "\" already exists!"
 msgstr ""
 
-msgid "VIM - ATTENTION"
+msgid "Swap file already exists!"
 msgstr ""
 
-msgid "Swap file already exists!"
+msgid "VIM - ATTENTION"
 msgstr ""
 
 msgid ""
diff --git a/src/proto/filepath.pro b/src/proto/filepath.pro
index d00a66775..ac8762383 100644
--- a/src/proto/filepath.pro
+++ b/src/proto/filepath.pro
@@ -36,7 +36,7 @@ char_u *do_browse(int flags, char_u *title, char_u *dflt, 
char_u *ext, char_u *i
 void f_browse(typval_T *argvars, typval_T *rettv);
 void f_browsedir(typval_T *argvars, typval_T *rettv);
 void f_filecopy(typval_T *argvars, typval_T *rettv);
-void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one);
+size_t home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one);
 char_u *home_replace_save(buf_T *buf, char_u *src);
 int fullpathcmp(char_u *s1, char_u *s2, int checkname, int expandenv);
 char_u *gettail(char_u *fname);
diff --git a/src/version.c b/src/version.c
index f46d48acc..dc31e54a7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    506,
 /**/
     505,
 /**/
diff --git a/src/viminfo.c b/src/viminfo.c
index bb84726c8..95ec55ebb 100644
--- a/src/viminfo.c
+++ b/src/viminfo.c
@@ -435,6 +435,8 @@ write_viminfo_bufferlist(FILE *fp)
     fputs(_("
# Buffer list:
"), fp);
     FOR_ALL_BUFFERS(buf)
     {
+       size_t  linelen;
+
        if (buf->b_fname == NULL
                || !buf->b_p_bl
                || bt_quickfix(buf)
@@ -445,8 +447,8 @@ write_viminfo_bufferlist(FILE *fp)
        if (max_buffers-- == 0)
            break;
        putc('%', fp);
-       home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE);
-       vim_snprintf_add((char *)line, LINE_BUF_LEN, "  %ld     %d",
+       linelen = home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE);
+       vim_snprintf((char *)line + linelen, LINE_BUF_LEN - linelen, "  %ld     
%d",
                        (long)buf->b_last_cursor.lnum,
                        buf->b_last_cursor.col);
        viminfo_writestring(fp, line);

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1wPm9F-00F9NZ-9a%40256bit.org.

Raspunde prin e-mail lui