mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
patch 8.1.0251: using full path is not supported for 'backupdir'
Problem: Using a full path is supported for 'directory' but not for 'backupdir'. (Mikolaj Machowski) Solution: Support 'backupdir' as well. (Christian Brabandt, closes #179)
This commit is contained in:
@@ -1054,6 +1054,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
name, precede it with a backslash.
|
name, precede it with a backslash.
|
||||||
- To include a comma in a directory name precede it with a backslash.
|
- To include a comma in a directory name precede it with a backslash.
|
||||||
- A directory name may end in an '/'.
|
- A directory name may end in an '/'.
|
||||||
|
- For Unix and Win32, if a directory ends in two path separators "//",
|
||||||
|
the swap file name will be built from the complete path to the file
|
||||||
|
with all path separators changed to percent '%' signs. This will
|
||||||
|
ensure file name uniqueness in the backup directory.
|
||||||
|
On Win32, it is also possible to end with "\\". However, When a
|
||||||
|
separating comma is following, you must use "//", since "\\" will
|
||||||
|
include the comma in the file name. Therefore it is recommended to
|
||||||
|
use '//', instead of '\\'.
|
||||||
- Environment variables are expanded |:set_env|.
|
- Environment variables are expanded |:set_env|.
|
||||||
- Careful with '\' characters, type one before a space, type two to
|
- Careful with '\' characters, type one before a space, type two to
|
||||||
get one in the option (see |option-backslash|), for example: >
|
get one in the option (see |option-backslash|), for example: >
|
||||||
@@ -2680,12 +2688,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
- A directory starting with "./" (or ".\" for MS-DOS et al.) means to
|
- A directory starting with "./" (or ".\" for MS-DOS et al.) means to
|
||||||
put the swap file relative to where the edited file is. The leading
|
put the swap file relative to where the edited file is. The leading
|
||||||
"." is replaced with the path name of the edited file.
|
"." is replaced with the path name of the edited file.
|
||||||
- For Unix and Win32, if a directory ends in two path separators "//"
|
- For Unix and Win32, if a directory ends in two path separators "//",
|
||||||
or "\\", the swap file name will be built from the complete path to
|
the swap file name will be built from the complete path to the file
|
||||||
the file with all path separators substituted to percent '%' signs.
|
with all path separators substituted to percent '%' signs. This will
|
||||||
This will ensure file name uniqueness in the preserve directory.
|
ensure file name uniqueness in the preserve directory.
|
||||||
On Win32, when a separating comma is following, you must use "//",
|
On Win32, it is also possible to end with "\\". However, When a
|
||||||
since "\\" will include the comma in the file name.
|
separating comma is following, you must use "//", since "\\" will
|
||||||
|
include the comma in the file name. Therefore it is recommended to
|
||||||
|
use '//', instead of '\\'.
|
||||||
- Spaces after the comma are ignored, other spaces are considered part
|
- Spaces after the comma are ignored, other spaces are considered part
|
||||||
of the directory name. To have a space at the start of a directory
|
of the directory name. To have a space at the start of a directory
|
||||||
name, precede it with a backslash.
|
name, precede it with a backslash.
|
||||||
|
@@ -12,6 +12,7 @@ NEW_TESTS = \
|
|||||||
test_autocmd \
|
test_autocmd \
|
||||||
test_autoload \
|
test_autoload \
|
||||||
test_backspace_opt \
|
test_backspace_opt \
|
||||||
|
test_backup \
|
||||||
test_blockedit \
|
test_blockedit \
|
||||||
test_breakindent \
|
test_breakindent \
|
||||||
test_bufline \
|
test_bufline \
|
||||||
|
36
src/fileio.c
36
src/fileio.c
@@ -3850,6 +3850,9 @@ buf_write(
|
|||||||
stat_T st_new;
|
stat_T st_new;
|
||||||
char_u *dirp;
|
char_u *dirp;
|
||||||
char_u *rootname;
|
char_u *rootname;
|
||||||
|
#if defined(UNIX) || defined(WIN3264)
|
||||||
|
char_u *p;
|
||||||
|
#endif
|
||||||
#if defined(UNIX)
|
#if defined(UNIX)
|
||||||
int did_set_shortname;
|
int did_set_shortname;
|
||||||
mode_t umask_save;
|
mode_t umask_save;
|
||||||
@@ -3887,6 +3890,17 @@ buf_write(
|
|||||||
* Isolate one directory name, using an entry in 'bdir'.
|
* Isolate one directory name, using an entry in 'bdir'.
|
||||||
*/
|
*/
|
||||||
(void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
|
(void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
|
||||||
|
|
||||||
|
#if defined(UNIX) || defined(WIN3264)
|
||||||
|
p = copybuf + STRLEN(copybuf);
|
||||||
|
if (after_pathsep(copybuf, p) && p[-1] == p[-2])
|
||||||
|
// Ends with '//', use full path
|
||||||
|
if ((p = make_percent_swname(copybuf, fname)) != NULL)
|
||||||
|
{
|
||||||
|
backup = modname(p, backup_ext, FALSE);
|
||||||
|
vim_free(p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
rootname = get_file_in_dir(fname, copybuf);
|
rootname = get_file_in_dir(fname, copybuf);
|
||||||
if (rootname == NULL)
|
if (rootname == NULL)
|
||||||
{
|
{
|
||||||
@@ -3904,8 +3918,9 @@ buf_write(
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Make backup file name.
|
* Make the backup file name.
|
||||||
*/
|
*/
|
||||||
|
if (backup == NULL)
|
||||||
backup = buf_modname((buf->b_p_sn || buf->b_shortname),
|
backup = buf_modname((buf->b_p_sn || buf->b_shortname),
|
||||||
rootname, backup_ext, FALSE);
|
rootname, backup_ext, FALSE);
|
||||||
if (backup == NULL)
|
if (backup == NULL)
|
||||||
@@ -4108,15 +4123,30 @@ buf_write(
|
|||||||
* Isolate one directory name and make the backup file name.
|
* Isolate one directory name and make the backup file name.
|
||||||
*/
|
*/
|
||||||
(void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
|
(void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
|
||||||
|
|
||||||
|
#if defined(UNIX) || defined(WIN3264)
|
||||||
|
p = IObuff + STRLEN(IObuff);
|
||||||
|
if (after_pathsep(IObuff, p) && p[-1] == p[-2])
|
||||||
|
// path ends with '//', use full path
|
||||||
|
if ((p = make_percent_swname(IObuff, fname)) != NULL)
|
||||||
|
{
|
||||||
|
backup = modname(p, backup_ext, FALSE);
|
||||||
|
vim_free(p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (backup == NULL)
|
||||||
|
{
|
||||||
rootname = get_file_in_dir(fname, IObuff);
|
rootname = get_file_in_dir(fname, IObuff);
|
||||||
if (rootname == NULL)
|
if (rootname == NULL)
|
||||||
backup = NULL;
|
backup = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backup = buf_modname((buf->b_p_sn || buf->b_shortname),
|
backup = buf_modname(
|
||||||
|
(buf->b_p_sn || buf->b_shortname),
|
||||||
rootname, backup_ext, FALSE);
|
rootname, backup_ext, FALSE);
|
||||||
vim_free(rootname);
|
vim_free(rootname);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (backup != NULL)
|
if (backup != NULL)
|
||||||
{
|
{
|
||||||
@@ -6252,7 +6282,7 @@ shorten_filenames(char_u **fnames, int count)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
|
* Add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
|
||||||
* fo_o_h.ext for MSDOS or when shortname option set.
|
* fo_o_h.ext for MSDOS or when shortname option set.
|
||||||
*
|
*
|
||||||
* Assumed that fname is a valid name found in the filesystem we assure that
|
* Assumed that fname is a valid name found in the filesystem we assure that
|
||||||
|
@@ -262,9 +262,6 @@ static int fnamecmp_ino(char_u *, char_u *, long);
|
|||||||
#endif
|
#endif
|
||||||
static void long_to_char(long, char_u *);
|
static void long_to_char(long, char_u *);
|
||||||
static long char_to_long(char_u *);
|
static long char_to_long(char_u *);
|
||||||
#if defined(UNIX) || defined(WIN3264)
|
|
||||||
static char_u *make_percent_swname(char_u *dir, char_u *name);
|
|
||||||
#endif
|
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading);
|
static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading);
|
||||||
#endif
|
#endif
|
||||||
@@ -2007,18 +2004,18 @@ recover_names(
|
|||||||
return file_count;
|
return file_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
|
#if defined(UNIX) || defined(WIN3264) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
|
* Need _very_ long file names.
|
||||||
* Append the full path to name with path separators made into percent
|
* Append the full path to name with path separators made into percent
|
||||||
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
|
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
|
||||||
*/
|
*/
|
||||||
static char_u *
|
char_u *
|
||||||
make_percent_swname(char_u *dir, char_u *name)
|
make_percent_swname(char_u *dir, char_u *name)
|
||||||
{
|
{
|
||||||
char_u *d, *s, *f;
|
char_u *d = NULL, *s, *f;
|
||||||
|
|
||||||
f = fix_fname(name != NULL ? name : (char_u *)"");
|
f = fix_fname(name != NULL ? name : (char_u *)"");
|
||||||
d = NULL;
|
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
{
|
{
|
||||||
s = alloc((unsigned)(STRLEN(f) + 1));
|
s = alloc((unsigned)(STRLEN(f) + 1));
|
||||||
@@ -4070,8 +4067,6 @@ attention_message(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_EVAL)
|
#if defined(FEAT_EVAL)
|
||||||
static int do_swapexists(buf_T *buf, char_u *fname);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trigger the SwapExists autocommands.
|
* Trigger the SwapExists autocommands.
|
||||||
* Returns a value for equivalent to do_dialog() (see below):
|
* Returns a value for equivalent to do_dialog() (see below):
|
||||||
|
@@ -34,4 +34,5 @@ char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned siz
|
|||||||
void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
|
void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
|
||||||
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
|
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
|
||||||
void goto_byte(long cnt);
|
void goto_byte(long cnt);
|
||||||
|
char_u *make_percent_swname (char_u *dir, char_u *name);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
" This makes testing go faster, since Vim doesn't need to restart.
|
" This makes testing go faster, since Vim doesn't need to restart.
|
||||||
|
|
||||||
source test_assign.vim
|
source test_assign.vim
|
||||||
|
source test_backup.vim
|
||||||
source test_bufline.vim
|
source test_bufline.vim
|
||||||
source test_cd.vim
|
source test_cd.vim
|
||||||
source test_changedtick.vim
|
source test_changedtick.vim
|
||||||
|
58
src/testdir/test_backup.vim
Normal file
58
src/testdir/test_backup.vim
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
" Tests for the backup function
|
||||||
|
|
||||||
|
func Test_backup()
|
||||||
|
set backup backupdir=.
|
||||||
|
new
|
||||||
|
call setline(1, ['line1', 'line2'])
|
||||||
|
:f Xbackup.txt
|
||||||
|
:w! Xbackup.txt
|
||||||
|
" backup file is only created after
|
||||||
|
" writing a second time (before overwriting)
|
||||||
|
:w! Xbackup.txt
|
||||||
|
let l = readfile('Xbackup.txt~')
|
||||||
|
call assert_equal(['line1', 'line2'], l)
|
||||||
|
bw!
|
||||||
|
set backup&vim backupdir&vim
|
||||||
|
call delete('Xbackup.txt')
|
||||||
|
call delete('Xbackup.txt~')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_backup2()
|
||||||
|
set backup backupdir=.//
|
||||||
|
new
|
||||||
|
call setline(1, ['line1', 'line2', 'line3'])
|
||||||
|
:f Xbackup.txt
|
||||||
|
:w! Xbackup.txt
|
||||||
|
" backup file is only created after
|
||||||
|
" writing a second time (before overwriting)
|
||||||
|
:w! Xbackup.txt
|
||||||
|
sp *Xbackup.txt~
|
||||||
|
call assert_equal(['line1', 'line2', 'line3'], getline(1,'$'))
|
||||||
|
let f=expand('%')
|
||||||
|
call assert_match('src%testdir%Xbackup.txt\~', f)
|
||||||
|
bw!
|
||||||
|
bw!
|
||||||
|
call delete('Xbackup.txt')
|
||||||
|
call delete(f)
|
||||||
|
set backup&vim backupdir&vim
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_backup2_backupcopy()
|
||||||
|
set backup backupdir=.// backupcopy=yes
|
||||||
|
new
|
||||||
|
call setline(1, ['line1', 'line2', 'line3'])
|
||||||
|
:f Xbackup.txt
|
||||||
|
:w! Xbackup.txt
|
||||||
|
" backup file is only created after
|
||||||
|
" writing a second time (before overwriting)
|
||||||
|
:w! Xbackup.txt
|
||||||
|
sp *Xbackup.txt~
|
||||||
|
call assert_equal(['line1', 'line2', 'line3'], getline(1,'$'))
|
||||||
|
let f=expand('%')
|
||||||
|
call assert_match('src%testdir%Xbackup.txt\~', f)
|
||||||
|
bw!
|
||||||
|
bw!
|
||||||
|
call delete('Xbackup.txt')
|
||||||
|
call delete(f)
|
||||||
|
set backup&vim backupdir&vim backupcopy&vim
|
||||||
|
endfunc
|
@@ -794,6 +794,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
251,
|
||||||
/**/
|
/**/
|
||||||
250,
|
250,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user