commit 0c27c1175b0ab168778fe0dfdff441885486dda3
parent 856391bc7fa982af5b8ee94d336c2e87ff83f970
Author: yilisharcs <yilisharcs@gmail.com>
Date: Wed, 17 Dec 2025 13:05:16 -0300
refactor(editor): extract backup name generation logic #37001
Problem: The logic for generating backup file names is duplicated in
`buf_write_make_backup` and difficult to reuse.
Solution: Extract name generation logic into `buf_get_backup_name`.
Diffstat:
| M | src/nvim/bufwrite.c | | | 107 | ++++++++++++++++++++++++++++--------------------------------------------------- |
1 file changed, 38 insertions(+), 69 deletions(-)
diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c
@@ -715,6 +715,40 @@ static int get_fileinfo(buf_T *buf, char *fname, bool overwriting, bool forceit,
return OK;
}
+/// @return The backup file name
+char *buf_get_backup_name(char *fname, char **dirp, bool no_prepend_dot, char *backup_ext)
+{
+ char *backup = NULL;
+ // Isolate one directory name, using an entry in 'bdir'.
+ size_t dir_len = copy_option_part(dirp, IObuff, IOSIZE, ",");
+ char *p = IObuff + dir_len;
+ if (**dirp == NUL && !os_isdir(IObuff)) {
+ int ret;
+ char *failed_dir;
+ if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) {
+ semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"),
+ failed_dir, os_strerror(ret));
+ xfree(failed_dir);
+ }
+ }
+ if (after_pathsep(IObuff, p) && p[-1] == p[-2]) {
+ // path ends with '//', use full path
+ if ((p = make_percent_swname(IObuff, p, fname))
+ != NULL) {
+ backup = modname(p, backup_ext, no_prepend_dot);
+ xfree(p);
+ }
+ }
+ if (backup == NULL) {
+ char *rootname = get_file_in_dir(fname, IObuff);
+ if (rootname != NULL) {
+ backup = modname(rootname, backup_ext, no_prepend_dot);
+ xfree(rootname);
+ }
+ }
+ return backup;
+}
+
static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_old, vim_acl_T acl,
int perm, unsigned bkc, bool file_readonly, bool forceit,
bool *backup_copyp, char **backupp, Error_T *err)
@@ -810,48 +844,14 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
// and reused. Creation of a backup COPY will be attempted.
char *dirp = p_bdir;
while (*dirp) {
- // Isolate one directory name, using an entry in 'bdir'.
- size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ",");
- char *p = IObuff + dir_len;
- if (*dirp == NUL && !os_isdir(IObuff)) {
- int ret;
- char *failed_dir;
- if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) {
- semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"),
- failed_dir, os_strerror(ret));
- xfree(failed_dir);
- }
- }
- if (after_pathsep(IObuff, p) && p[-1] == p[-2]) {
- // Ends with '//', Use Full path
- if ((p = make_percent_swname(IObuff, p, fname))
- != NULL) {
- *backupp = modname(p, backup_ext, no_prepend_dot);
- xfree(p);
- }
- }
-
- char *rootname = get_file_in_dir(fname, IObuff);
- if (rootname == NULL) {
+ *backupp = buf_get_backup_name(fname, &dirp, no_prepend_dot, backup_ext);
+ if (*backupp == NULL) {
some_error = true; // out of memory
goto nobackup;
}
FileInfo file_info_new;
{
- //
- // Make the backup file name.
- //
- if (*backupp == NULL) {
- *backupp = modname(rootname, backup_ext, no_prepend_dot);
- }
-
- if (*backupp == NULL) {
- xfree(rootname);
- some_error = true; // out of memory
- goto nobackup;
- }
-
// Check if backup file already exists.
if (os_fileinfo(*backupp, &file_info_new)) {
if (os_fileinfo_id_equal(&file_info_new, file_info_old)) {
@@ -880,7 +880,6 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
}
}
}
- xfree(rootname);
// Try to create the backup file
if (*backupp != NULL) {
@@ -946,43 +945,13 @@ nobackup:
// that works is used.
char *dirp = p_bdir;
while (*dirp) {
- // Isolate one directory name and make the backup file name.
- size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ",");
- char *p = IObuff + dir_len;
- if (*dirp == NUL && !os_isdir(IObuff)) {
- int ret;
- char *failed_dir;
- if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) {
- semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"),
- failed_dir, os_strerror(ret));
- xfree(failed_dir);
- }
- }
- if (after_pathsep(IObuff, p) && p[-1] == p[-2]) {
- // path ends with '//', use full path
- if ((p = make_percent_swname(IObuff, p, fname))
- != NULL) {
- *backupp = modname(p, backup_ext, no_prepend_dot);
- xfree(p);
- }
- }
-
- if (*backupp == NULL) {
- char *rootname = get_file_in_dir(fname, IObuff);
- if (rootname == NULL) {
- *backupp = NULL;
- } else {
- *backupp = modname(rootname, backup_ext, no_prepend_dot);
- xfree(rootname);
- }
- }
-
+ *backupp = buf_get_backup_name(fname, &dirp, no_prepend_dot, backup_ext);
if (*backupp != NULL) {
// If we are not going to keep the backup file, don't
// delete an existing one, try to use another name.
// Change one character, just before the extension.
if (!p_bk && os_path_exists(*backupp)) {
- p = *backupp + strlen(*backupp) - 1 - strlen(backup_ext);
+ char *p = *backupp + strlen(*backupp) - 1 - strlen(backup_ext);
p = MAX(p, *backupp); // empty file name ???
*p = 'z';
while (*p > 'a' && os_path_exists(*backupp)) {