int qf_end_col; // column when the error has range or zero
int qf_nr; // error number
char_u *qf_module; // module name for this error
+ char_u *qf_fname; // different filename if there're hard links
char_u *qf_pattern; // search pattern for the error
char_u *qf_text; // description of the error
char_u qf_viscol; // set to TRUE if qf_col and qf_end_col is
typval_T *user_data, // custom user data or NULL
int valid) // valid entry
{
+ buf_T *buf;
qfline_T *qfp;
qfline_T **lastp; // pointer to qf_last or NULL
+ char_u *fullname = NULL;
+ char_u *p = NULL;
if ((qfp = ALLOC_ONE_ID(qfline_T, aid_qf_qfline)) == NULL)
return QF_FAIL;
if (bufnum != 0)
{
- buf_T *buf = buflist_findnr(bufnum);
+ buf = buflist_findnr(bufnum);
qfp->qf_fnum = bufnum;
if (buf != NULL)
IS_QF_LIST(qfl) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
}
else
+ {
qfp->qf_fnum = qf_get_fnum(qfl, dir, fname);
+ buf = buflist_findnr(qfp->qf_fnum);
+ }
+ if (fname != NULL)
+ fullname = fix_fname(fname);
+ qfp->qf_fname = NULL;
+ if (buf != NULL &&
+ buf->b_ffname != NULL && fullname != NULL)
+ {
+ if (fnamecmp(fullname, buf->b_ffname) != 0)
+ {
+ p = shorten_fname1(fullname);
+ if (p != NULL)
+ qfp->qf_fname = vim_strsave(p);
+ }
+ }
+ vim_free(fullname);
if ((qfp->qf_text = vim_strsave(mesg)) == NULL)
{
vim_free(qfp);
if (qfp->qf_fnum != 0
&& (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
{
- fname = buf->b_fname;
+ if (qfp->qf_fname == NULL)
+ fname = buf->b_fname;
+ else
+ fname = qfp->qf_fname;
if (qfp->qf_type == 1) // :helpgrep
fname = gettail(fname);
}
qfpnext = qfp->qf_next;
if (!stop)
{
+ vim_free(qfp->qf_fname);
vim_free(qfp->qf_module);
vim_free(qfp->qf_text);
vim_free(qfp->qf_pattern);
mch_dirname(dirname, MAXPATHL);
shorten_buf_fname(errbuf, dirname, FALSE);
}
- ga_concat(gap, errbuf->b_fname);
+ if (qfp->qf_fname == NULL)
+ ga_concat(gap, errbuf->b_fname);
+ else
+ ga_concat(gap, qfp->qf_fname);
}
}
" The following test used to crash Vim
func Test_lvimgrep_crash()
+ " this leaves a swapfile .test_quickfix.vim.swp around, why?
sv Xtest
augroup QF_Test
au!
autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
au! BufRead Xtest2.txt
+ " cleanup the swap files
+ bw! Xtest2.txt Xtest1.txt
call setqflist([], 'f')
endfunc
call XbufferTests_range('l')
endfunc
+" Test for displaying fname pass from setqflist when the name
+" are hard links to prevent seemly duplicate entries.
+func Xtest_hardlink_fname(cchar)
+ call s:setup_commands(a:cchar)
+ %bwipe
+ " Create a sample source file
+ let lines =<< trim END
+ void sample() {}
+ int main() { sample(); return 0; }
+ END
+ call writefile(lines, 'test_qf_hardlink1.c', 'D')
+ defer delete('test_qf_hardlink1.c')
+ defer delete('test_qf_hardlink2.c')
+ call system('ln test_qf_hardlink1.c test_qf_hardlink2.c')
+ if v:shell_error
+ throw 'Skipped: ln throws error on this platform'
+ endif
+ call g:Xsetlist([], 'f')
+ " Make a qflist that contains the file and it's hard link
+ " like how LSP plugins set response into qflist
+ call g:Xsetlist([{'filename' : 'test_qf_hardlink1.c', 'lnum' : 1},
+ \ {'filename' : 'test_qf_hardlink2.c', 'lnum' : 1}], ' ')
+ Xopen
+ " Ensure that two entries are displayed with different name
+ " so that they aren't seen as duplication.
+ call assert_equal(['test_qf_hardlink1.c|1| ',
+ \ 'test_qf_hardlink2.c|1| '], getline(1, '$'))
+ Xclose
+endfunc
+
+func Test_hardlink_fname()
+ CheckUnix
+ CheckExecutable ln
+ call Xtest_hardlink_fname('c')
+ call Xtest_hardlink_fname('l')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab