aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ex_cmds2.c24
-rw-r--r--src/nvim/ex_cmds2.h4
-rw-r--r--src/nvim/testdir/test_source.vim11
-rw-r--r--test/functional/ex_cmds/source_spec.lua20
4 files changed, 39 insertions, 20 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index defe22ea9a..897928abec 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -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;
diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h
index 74e52dfb4b..c463bfa5ab 100644
--- a/src/nvim/ex_cmds2.h
+++ b/src/nvim/ex_cmds2.h
@@ -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
diff --git a/src/nvim/testdir/test_source.vim b/src/nvim/testdir/test_source.vim
index 09baec0b7d..b8fe8422b3 100644
--- a/src/nvim/testdir/test_source.vim
+++ b/src/nvim/testdir/test_source.vim
@@ -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
diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua
index fa650d611b..13a40fcc53 100644
--- a/test/functional/ex_cmds/source_spec.lua
+++ b/test/functional/ex_cmds/source_spec.lua
@@ -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