vim-patch:9.2.1067: Completion shows an included file by full path (#41849)

Problem:  A match found in an included file is shown with the full path
          of the file, while a match from a buffer is shown with the
          name under the current directory.  A file included as
          "./file" even has the "./" left in: "dir/./file".
Solution: Show the file by its name under the current directory, and
          simplify the name of a file found relative to the current
          one (Hirohito Higashi).

closes: vim/vim#21264

cff83f361d

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
This commit is contained in:
zeertzjq
2026-09-11 10:40:11 +08:00
committed by GitHub
parent 486f820a98
commit e25e86a9ed
4 changed files with 52 additions and 7 deletions

View File

@@ -1505,20 +1505,19 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch
}
// When the file doesn't exist, try adding parts of 'suffixesadd'.
size_t NameBufflen = l;
char *suffix = suffixes;
while (true) {
if ((os_path_exists(NameBuff)
&& (find_what == FINDFILE_BOTH
|| ((find_what == FINDFILE_DIR) == os_isdir(NameBuff))))) {
file_name = xmemdupz(NameBuff, NameBufflen);
file_name = xmemdupz(NameBuff, simplify_filename(NameBuff));
goto theend;
}
if (*suffix == NUL) {
break;
}
assert(MAXPATHL >= l);
NameBufflen = l + copy_option_part(&suffix, NameBuff + l, MAXPATHL - l, ",");
copy_option_part(&suffix, NameBuff + l, MAXPATHL - l, ",");
}
}
}

View File

@@ -3338,10 +3338,11 @@ search_line:
}
}
const int add_r = ins_compl_add_infercase(aux, i, p_ic,
curr_fname == curbuf->b_fname
? NULL : curr_fname,
dir, cont_s_ipos, 0);
const int add_r
= ins_compl_add_infercase(aux, i, p_ic,
curr_fname == curbuf->b_fname
? NULL : path_try_shorten_fname(curr_fname),
dir, cont_s_ipos, 0);
if (add_r == OK) {
// if dir was BACKWARD then honor it just once
dir = FORWARD;

View File

@@ -1321,6 +1321,31 @@ describe('completion', function()
]])
end)
-- oldtest: Test_complete_included_file_name()
it('shows included files by relative path', function()
t.mkdir('Xincl')
finally(function()
n.rmdir('Xincl')
end)
t.mkdir('Xincl/sub')
t.write_file('Xincl/sub/inc.vim', 'let included_word = 1\n')
t.write_file('Xincl/main.vim', 'source ./sub/inc.vim\n\n')
n.exec([[
edit Xincl/main.vim
setlocal include=^\\s*source\\s\\+ complete=i completeopt=menuone,noselect
]])
feed('Goincluded_<C-N>')
screen:expect([[
source ./sub/inc.vim |
|
included_^ |
{4:included_word Xincl/sub/inc.vim }{1: }|
{1:~ }|*3
{5:-- Keyword completion (^N^P) }{19:Back at original} |
]])
feed('<Esc>')
end)
-- oldtest: Test_complete_changed_complete_info()
it('no crash calling complete_info() in CompleteChanged', function()
source([[

View File

@@ -3531,6 +3531,26 @@ func s:Tagfunc(t,f,o)
return []
endfunc
" A match from an included file shows the file by its name under the current
" directory, without the "./" of the include line.
func Test_complete_included_file_name()
CheckRunVimInTerminal
call mkdir('Xincl/sub', 'pR')
call writefile(['let included_word = 1'], 'Xincl/sub/inc.vim')
call writefile(['source ./sub/inc.vim', ''], 'Xincl/main.vim')
let lines =<< trim END
setlocal include=^\\s*source\\s\\+ complete=i completeopt=menuone,noselect
END
call writefile(lines, 'Xincl/setup.vim')
let buf = RunVimInTerminal('-S Xincl/setup.vim Xincl/main.vim',
\ {'rows': 8, 'cols': 120})
call term_sendkeys(buf, "Goincluded_\<C-N>")
call WaitForAssert({-> assert_match('included_word\s\+Xincl/sub/inc.vim\s',
\ term_getline(buf, 4))})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
endfunc
" This was using freed memory, since 'complete' was in a wiped out buffer.
" Also using a window that was closed.
func Test_tagfunc_wipes_out_buffer()