mirror of
https://github.com/neovim/neovim.git
synced 2026-01-20 04:01:15 +10:00
Merge pull request #19278 from zeertzjq/vim-8.2.0132
vim-patch:8.2.{0132,0136,0151}: detecting a script was already sourced is unreliable
This commit is contained in:
@@ -2156,31 +2156,23 @@ scriptitem_T *get_current_script_id(char_u *fname, sctx_T *ret_sctx)
|
||||
sctx_T script_sctx = { .sc_seq = ++last_current_SID_seq,
|
||||
.sc_lnum = 0,
|
||||
.sc_sid = 0 };
|
||||
FileID file_id;
|
||||
scriptitem_T *si = NULL;
|
||||
|
||||
bool file_id_ok = os_fileid((char *)fname, &file_id);
|
||||
assert(script_items.ga_len >= 0);
|
||||
for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0;
|
||||
script_sctx.sc_sid--) {
|
||||
for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0; script_sctx.sc_sid--) {
|
||||
// We used to check inode here, but that doesn't work:
|
||||
// - If a script is edited and written, it may get a different
|
||||
// inode number, even though to the user it is the same script.
|
||||
// - If a script is deleted and another script is written, with a
|
||||
// different name, the inode may be re-used.
|
||||
si = &SCRIPT_ITEM(script_sctx.sc_sid);
|
||||
// Compare dev/ino when possible, it catches symbolic links.
|
||||
// Also compare file names, the inode may change when the file was edited.
|
||||
bool file_id_equal = file_id_ok && si->file_id_valid
|
||||
&& os_fileid_equal(&(si->file_id), &file_id);
|
||||
if (si->sn_name != NULL
|
||||
&& (file_id_equal || FNAMECMP(si->sn_name, fname) == 0)) {
|
||||
if (si->sn_name != NULL && FNAMECMP(si->sn_name, fname) == 0) {
|
||||
// Found it!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (script_sctx.sc_sid == 0) {
|
||||
si = new_script_item((char *)vim_strsave(fname), &script_sctx.sc_sid);
|
||||
if (file_id_ok) {
|
||||
si->file_id_valid = true;
|
||||
si->file_id = file_id;
|
||||
} else {
|
||||
si->file_id_valid = false;
|
||||
}
|
||||
}
|
||||
if (ret_sctx != NULL) {
|
||||
*ret_sctx = script_sctx;
|
||||
|
||||
@@ -15,12 +15,8 @@
|
||||
#define CCGD_ALLBUF 8 // may write all buffers
|
||||
#define CCGD_EXCMD 16 // may suggest using !
|
||||
|
||||
/// Also store the dev/ino, so that we don't have to stat() each
|
||||
/// script when going through the list.
|
||||
typedef struct scriptitem_S {
|
||||
char_u *sn_name;
|
||||
bool file_id_valid;
|
||||
FileID file_id;
|
||||
bool sn_prof_on; ///< true when script is/was profiled
|
||||
bool sn_pr_force; ///< forceit: profile functions in this script
|
||||
proftime_T sn_pr_child; ///< time set when going into first child
|
||||
|
||||
@@ -46,3 +46,14 @@ func Test_source_sandbox()
|
||||
bwipe!
|
||||
call delete('Xsourcehello')
|
||||
endfunc
|
||||
|
||||
" When deleting a file and immediately creating a new one the inode may be
|
||||
" recycled. Vim should not recognize it as the same script.
|
||||
func Test_different_script()
|
||||
call writefile(['let s:var = "asdf"'], 'XoneScript')
|
||||
source XoneScript
|
||||
call delete('XoneScript')
|
||||
call writefile(['let g:var = s:var'], 'XtwoScript')
|
||||
call assert_fails('source XtwoScript', 'E121:')
|
||||
call delete('XtwoScript')
|
||||
endfunc
|
||||
|
||||
@@ -19,6 +19,26 @@ describe(':source', function()
|
||||
clear()
|
||||
end)
|
||||
|
||||
it('sourcing a file that is deleted and recreated is consistent vim-patch:8.1.0151', function()
|
||||
local test_file = 'Xfile.vim'
|
||||
local other_file = 'Xfoobar'
|
||||
local script = [[
|
||||
func Func()
|
||||
endfunc
|
||||
]]
|
||||
write_file(test_file, script)
|
||||
command('source ' .. test_file)
|
||||
os.remove(test_file)
|
||||
write_file(test_file, script)
|
||||
command('source ' .. test_file)
|
||||
os.remove(test_file)
|
||||
write_file(other_file, '')
|
||||
write_file(test_file, script)
|
||||
command('source ' .. test_file)
|
||||
os.remove(other_file)
|
||||
os.remove(test_file)
|
||||
end)
|
||||
|
||||
it('current buffer', function()
|
||||
insert([[
|
||||
let a = 2
|
||||
|
||||
Reference in New Issue
Block a user