mirror of
https://github.com/neovim/neovim.git
synced 2026-07-16 14:11:28 +00:00
Merge pull request #13105 from janlazo/vim-8.2.0728
vim-patch:8.2.{444,778,1219,1384,1557}
This commit is contained in:
@@ -3593,7 +3593,7 @@ restore_backup:
|
||||
* the backup file our 'original' file.
|
||||
*/
|
||||
if (*p_pm && dobackup) {
|
||||
char *org = modname((char *)fname, (char *)p_pm, FALSE);
|
||||
char *const org = modname((char *)fname, (char *)p_pm, false);
|
||||
|
||||
if (backup != NULL) {
|
||||
/*
|
||||
|
||||
@@ -1360,7 +1360,7 @@ recover_names (
|
||||
* Try finding a swap file by simply adding ".swp" to the file name.
|
||||
*/
|
||||
if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) {
|
||||
char_u *swapname = (char_u *)modname((char *)fname_res, ".swp", TRUE);
|
||||
char_u *swapname = (char_u *)modname((char *)fname_res, ".swp", true);
|
||||
if (swapname != NULL) {
|
||||
if (os_path_exists(swapname)) {
|
||||
files = xmalloc(sizeof(char_u *));
|
||||
@@ -1638,10 +1638,11 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
|
||||
// May also add the file name with a dot prepended, for swap file in same
|
||||
// dir as original file.
|
||||
if (prepend_dot) {
|
||||
names[num_names] = (char_u *)modname((char *)path, ".sw?", TRUE);
|
||||
if (names[num_names] == NULL)
|
||||
names[num_names] = (char_u *)modname((char *)path, ".sw?", true);
|
||||
if (names[num_names] == NULL) {
|
||||
return num_names;
|
||||
++num_names;
|
||||
}
|
||||
num_names++;
|
||||
}
|
||||
|
||||
// Form the normal swap file name pattern by appending ".sw?".
|
||||
@@ -2422,17 +2423,17 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy)
|
||||
return ml_replace_buf(curbuf, lnum, line, copy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace line lnum, with buffering, in current buffer.
|
||||
*
|
||||
* If "copy" is TRUE, make a copy of the line, otherwise the line has been
|
||||
* copied to allocated memory already.
|
||||
*
|
||||
* Check: The caller of this function should probably also call
|
||||
* changed_lines(), unless update_screen(NOT_VALID) is used.
|
||||
*
|
||||
* return FAIL for failure, OK otherwise
|
||||
*/
|
||||
// Replace line "lnum", with buffering, in current buffer.
|
||||
//
|
||||
// If "copy" is true, make a copy of the line, otherwise the line has been
|
||||
// copied to allocated memory already.
|
||||
// If "copy" is false the "line" may be freed to add text properties!
|
||||
// Do not use it after calling ml_replace().
|
||||
//
|
||||
// Check: The caller of this function should probably also call
|
||||
// changed_lines(), unless update_screen(NOT_VALID) is used.
|
||||
//
|
||||
// return FAIL for failure, OK otherwise
|
||||
int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy)
|
||||
{
|
||||
if (line == NULL) /* just checking... */
|
||||
@@ -3193,6 +3194,12 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
|
||||
char_u *fname_res = fname;
|
||||
#ifdef HAVE_READLINK
|
||||
char_u fname_buf[MAXPATHL];
|
||||
|
||||
// Expand symlink in the file name, so that we put the swap file with the
|
||||
// actual file instead of with the symlink.
|
||||
if (resolve_symlink(fname, fname_buf) == OK) {
|
||||
fname_res = fname_buf;
|
||||
}
|
||||
#endif
|
||||
int len = (int)STRLEN(dir_name);
|
||||
|
||||
@@ -3201,20 +3208,14 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
|
||||
&& len > 1
|
||||
&& s[-1] == s[-2]) { // Ends with '//', Use Full path
|
||||
r = NULL;
|
||||
if ((s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname)) != NULL) {
|
||||
r = (char_u *)modname((char *)s, ".swp", FALSE);
|
||||
s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname_res);
|
||||
if (s != NULL) {
|
||||
r = (char_u *)modname((char *)s, ".swp", false);
|
||||
xfree(s);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
/* Expand symlink in the file name, so that we put the swap file with the
|
||||
* actual file instead of with the symlink. */
|
||||
if (resolve_symlink(fname, fname_buf) == OK)
|
||||
fname_res = fname_buf;
|
||||
#endif
|
||||
|
||||
// Prepend a '.' to the swap file name for the current directory.
|
||||
r = (char_u *)modname((char *)fname_res, ".swp",
|
||||
dir_name[0] == '.' && dir_name[1] == NUL);
|
||||
|
||||
@@ -983,7 +983,7 @@ void preserve_exit(void)
|
||||
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
|
||||
mch_errmsg((uint8_t *)"Vim: preserving files...\n");
|
||||
mch_errmsg("Vim: preserving files...\r\n");
|
||||
ui_flush();
|
||||
ml_sync_all(false, false, true); // preserve all swap files
|
||||
break;
|
||||
@@ -992,7 +992,7 @@ void preserve_exit(void)
|
||||
|
||||
ml_close_all(false); // close all memfiles, without deleting
|
||||
|
||||
mch_errmsg("Vim: Finished.\n");
|
||||
mch_errmsg("Vim: Finished.\r\n");
|
||||
|
||||
getout(1);
|
||||
}
|
||||
|
||||
@@ -161,8 +161,8 @@ static void deadly_signal(int signum)
|
||||
|
||||
WLOG("got signal %d (%s)", signum, signal_name(signum));
|
||||
|
||||
snprintf((char *)IObuff, sizeof(IObuff), "Vim: Caught deadly signal '%s'\n",
|
||||
signal_name(signum));
|
||||
snprintf((char *)IObuff, sizeof(IObuff), "Vim: Caught deadly signal '%s'\r\n",
|
||||
signal_name(signum));
|
||||
|
||||
// Preserve files and exit.
|
||||
preserve_exit();
|
||||
|
||||
@@ -5068,6 +5068,20 @@ static void vgr_jump_to_match(qf_info_T *qi, int forceit, int *redraw_for_dummy,
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if "buf" had an existing swap file, the current swap file does
|
||||
// not end in ".swp".
|
||||
static bool existing_swapfile(const buf_T *buf)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
|
||||
const char_u *const fname = buf->b_ml.ml_mfp->mf_fname;
|
||||
const size_t len = STRLEN(fname);
|
||||
|
||||
return fname[len - 1] != 'p' || fname[len - 2] != 'w';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ":vimgrep {pattern} file(s)"
|
||||
// ":vimgrepadd {pattern} file(s)"
|
||||
// ":lvimgrep {pattern} file(s)"
|
||||
@@ -5225,7 +5239,9 @@ void ex_vimgrep(exarg_T *eap)
|
||||
if (!found_match) {
|
||||
wipe_dummy_buffer(buf, dirname_start);
|
||||
buf = NULL;
|
||||
} else if (buf != first_match_buf || (flags & VGR_NOJUMP)) {
|
||||
} else if (buf != first_match_buf
|
||||
|| (flags & VGR_NOJUMP)
|
||||
|| existing_swapfile(buf)) {
|
||||
unload_dummy_buffer(buf, dirname_start);
|
||||
// Keeping the buffer, remove the dummy flag.
|
||||
buf->b_flags &= ~BF_DUMMY;
|
||||
|
||||
@@ -78,6 +78,9 @@ set encoding=utf-8
|
||||
let s:test_script_fname = expand('%')
|
||||
au! SwapExists * call HandleSwapExists()
|
||||
func HandleSwapExists()
|
||||
if exists('g:ignoreSwapExists')
|
||||
return
|
||||
endif
|
||||
" Ignore finding a swap file for the test script (the user might be
|
||||
" editing it and do ":make test_name") and the output file.
|
||||
" Report finding another swap file and chose 'q' to avoid getting stuck.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
" Test for the quickfix commands.
|
||||
|
||||
if !has('quickfix')
|
||||
finish
|
||||
endif
|
||||
source check.vim
|
||||
CheckFeature quickfix
|
||||
|
||||
set encoding=utf-8
|
||||
|
||||
@@ -2568,6 +2567,41 @@ func Test_vimgrep_incsearch()
|
||||
set noincsearch
|
||||
endfunc
|
||||
|
||||
" Test vimgrep without swap file
|
||||
func Test_vimgrep_without_swap_file()
|
||||
let lines =<< trim [SCRIPT]
|
||||
vimgrep grep test_c*
|
||||
call writefile(['done'], 'Xresult')
|
||||
qall!
|
||||
[SCRIPT]
|
||||
call writefile(lines, 'Xscript')
|
||||
if RunVim([], [], '--clean -n -S Xscript Xscript')
|
||||
call assert_equal(['done'], readfile('Xresult'))
|
||||
endif
|
||||
call delete('Xscript')
|
||||
call delete('Xresult')
|
||||
endfunc
|
||||
|
||||
func Test_vimgrep_existing_swapfile()
|
||||
call writefile(['match apple with apple'], 'Xapple')
|
||||
call writefile(['swapfile'], '.Xapple.swp')
|
||||
let g:foundSwap = 0
|
||||
let g:ignoreSwapExists = 1
|
||||
augroup grep
|
||||
au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
|
||||
augroup END
|
||||
vimgrep apple Xapple
|
||||
call assert_equal(1, g:foundSwap)
|
||||
call assert_match('.Xapple.swo', swapname(''))
|
||||
|
||||
call delete('Xapple')
|
||||
call delete('Xapple.swp')
|
||||
augroup grep
|
||||
au! SwapExists
|
||||
augroup END
|
||||
unlet g:ignoreSwapExists
|
||||
endfunc
|
||||
|
||||
func XfreeTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
" Tests for the swap feature
|
||||
|
||||
source check.vim
|
||||
|
||||
func s:swapname()
|
||||
return trim(execute('swapname'))
|
||||
endfunc
|
||||
@@ -305,3 +307,61 @@ func Test_swap_recover_ext()
|
||||
augroup END
|
||||
augroup! test_swap_recover_ext
|
||||
endfunc
|
||||
|
||||
" Test for selecting 'q' in the attention prompt
|
||||
func Test_swap_prompt_splitwin()
|
||||
CheckRunVimInTerminal
|
||||
|
||||
call writefile(['foo bar'], 'Xfile1')
|
||||
edit Xfile1
|
||||
preserve " should help to make sure the swap file exists
|
||||
|
||||
let buf = RunVimInTerminal('', {'rows': 20})
|
||||
call term_sendkeys(buf, ":set nomore\n")
|
||||
call term_sendkeys(buf, ":set noruler\n")
|
||||
call term_sendkeys(buf, ":split Xfile1\n")
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))})
|
||||
call term_sendkeys(buf, "q")
|
||||
call term_wait(buf)
|
||||
call term_sendkeys(buf, ":\<CR>")
|
||||
call WaitForAssert({-> assert_match('^:$', term_getline(buf, 20))})
|
||||
call term_sendkeys(buf, ":echomsg winnr('$')\<CR>")
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))})
|
||||
call StopVimInTerminal(buf)
|
||||
%bwipe!
|
||||
call delete('Xfile1')
|
||||
endfunc
|
||||
|
||||
func Test_swap_symlink()
|
||||
if !has("unix")
|
||||
return
|
||||
endif
|
||||
|
||||
call writefile(['text'], 'Xtestfile')
|
||||
silent !ln -s -f Xtestfile Xtestlink
|
||||
|
||||
set dir=.
|
||||
|
||||
" Test that swap file uses the name of the file when editing through a
|
||||
" symbolic link (so that editing the file twice is detected)
|
||||
edit Xtestlink
|
||||
call assert_match('Xtestfile\.swp$', s:swapname())
|
||||
bwipe!
|
||||
|
||||
call mkdir('Xswapdir')
|
||||
exe 'set dir=' . getcwd() . '/Xswapdir//'
|
||||
|
||||
" Check that this also works when 'directory' ends with '//'
|
||||
edit Xtestlink
|
||||
call assert_match('Xtestfile\.swp$', s:swapname())
|
||||
bwipe!
|
||||
|
||||
set dir&
|
||||
call delete('Xtestfile')
|
||||
call delete('Xtestlink')
|
||||
call delete('Xswapdir', 'rf')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
Reference in New Issue
Block a user