aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt4
-rw-r--r--runtime/lua/vim/lsp/handlers.lua27
-rw-r--r--runtime/lua/vim/lsp/util.lua60
-rw-r--r--src/nvim/misc1.c18
-rw-r--r--src/nvim/quickfix.c17
-rw-r--r--src/nvim/testdir/test_functions.vim24
-rw-r--r--src/nvim/testdir/test_quickfix.vim163
-rw-r--r--test/functional/eval/null_spec.lua2
-rw-r--r--test/functional/ui/messages_spec.lua4
9 files changed, 247 insertions, 72 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index fd7af55e87..fa3ceb1142 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -595,10 +595,6 @@ A jump table for the options with a short description can be found at |Q_op|.
set to one of CJK locales. See Unicode Standard Annex #11
(http://www.unicode.org/reports/tr11).
- Vim may set this option automatically at startup time when Vim is
- compiled with the |+termresponse| feature and if t_u7 is set to the
- escape sequence to request cursor position report.
-
*'autochdir'* *'acd'* *'noautochdir'* *'noacd'*
'autochdir' 'acd' boolean (default off)
global
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 525ec4ce5b..18155ceb7e 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -271,9 +271,7 @@ function M.hover(_, method, result, _, _, config)
-- return { 'No information available' }
return
end
- local bufnr, winnr = util.fancy_floating_markdown(markdown_lines, {
- border = config.border
- })
+ local bufnr, winnr = util.fancy_floating_markdown(markdown_lines, config)
util.close_preview_autocmd({"CursorMoved", "BufHidden", "InsertCharPre"}, winnr)
return bufnr, winnr
end)
@@ -341,17 +339,20 @@ function M.signature_help(_, method, result, _, bufnr, config)
print('No signature help available')
return
end
- local lines = util.convert_signature_help_to_markdown_lines(result)
- lines = util.trim_empty_lines(lines)
- if vim.tbl_isempty(lines) then
- print('No signature help available')
- return
- end
- local syntax = api.nvim_buf_get_option(bufnr, 'syntax')
- local p_bufnr, _ = util.focusable_preview(method, function()
- return lines, util.try_trim_markdown_code_blocks(lines), config
+ local p_bufnr, winnr = util.focusable_float(method, function()
+ local ft = api.nvim_buf_get_option(bufnr, 'filetype')
+ local lines = util.convert_signature_help_to_markdown_lines(result, ft)
+ lines = util.trim_empty_lines(lines)
+ if vim.tbl_isempty(lines) then
+ print('No signature help available')
+ return
+ end
+ local p_bufnr, p_winnr = util.fancy_floating_markdown(lines, config)
+ util.close_preview_autocmd({"CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre"}, p_winnr)
+
+ return p_bufnr, p_winnr
end)
- api.nvim_buf_set_option(p_bufnr, 'syntax', syntax)
+ return p_bufnr, winnr
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 417a3cdb88..ea54290ec3 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -804,9 +804,10 @@ end
--- Converts `textDocument/SignatureHelp` response to markdown lines.
---
--@param signature_help Response of `textDocument/SignatureHelp`
+--@param ft optional filetype that will be use as the `lang` for the label markdown code block
--@returns list of lines of converted markdown.
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp
-function M.convert_signature_help_to_markdown_lines(signature_help)
+function M.convert_signature_help_to_markdown_lines(signature_help, ft)
if not signature_help.signatures then
return
end
@@ -824,7 +825,12 @@ function M.convert_signature_help_to_markdown_lines(signature_help)
if not signature then
return
end
- vim.list_extend(contents, vim.split(signature.label, '\n', true))
+ local label = signature.label
+ if ft then
+ -- wrap inside a code block so fancy_markdown can render it properly
+ label = ("```%s\n%s\n```"):format(ft, label)
+ end
+ vim.list_extend(contents, vim.split(label, '\n', true))
if signature.documentation then
M.convert_input_to_markdown_lines(signature.documentation, contents)
end
@@ -951,7 +957,7 @@ end
---
--@param location a single `Location` or `LocationLink`
--@returns (bufnr,winnr) buffer and window number of floating window or nil
-function M.preview_location(location)
+function M.preview_location(location, opts)
-- location may be LocationLink or Location (more useful for the former)
local uri = location.targetUri or location.uri
if uri == nil then return end
@@ -962,7 +968,13 @@ function M.preview_location(location)
local range = location.targetRange or location.range
local contents = api.nvim_buf_get_lines(bufnr, range.start.line, range["end"].line+1, false)
local syntax = api.nvim_buf_get_option(bufnr, 'syntax')
- return M.open_floating_preview(contents, syntax)
+ if syntax == "" then
+ -- When no syntax is set, we use filetype as fallback. This might not result
+ -- in a valid syntax definition. See also ft detection in fancy_floating_win.
+ -- An empty syntax is more common now with TreeSitter, since TS disables syntax.
+ syntax = api.nvim_buf_get_option(bufnr, 'filetype')
+ end
+ return M.open_floating_preview(contents, syntax, opts)
end
--@private
@@ -1086,12 +1098,16 @@ function M.fancy_floating_markdown(contents, opts)
local ft = line:match("^```([a-zA-Z0-9_]*)$")
-- local ft = line:match("^```(.*)$")
-- TODO(ashkan): validate the filetype here.
+ local is_pre = line:match("^%s*<pre>%s*$")
+ if is_pre then
+ ft = ""
+ end
if ft then
local start = #stripped
i = i + 1
while i <= #contents do
line = contents[i]
- if line == "```" then
+ if line == "```" or (is_pre and line:match("^%s*</pre>%s*$")) then
i = i + 1
break
end
@@ -1120,12 +1136,19 @@ function M.fancy_floating_markdown(contents, opts)
local insert_separator = opts.separator
if insert_separator == nil then insert_separator = true end
if insert_separator then
- for i, h in ipairs(highlights) do
- h.start = h.start + i - 1
- h.finish = h.finish + i - 1
+ local offset = 0
+ for _, h in ipairs(highlights) do
+ h.start = h.start + offset
+ h.finish = h.finish + offset
+ -- check if a seperator already exists and use that one instead of creating a new one
if h.finish + 1 <= #stripped then
- table.insert(stripped, h.finish + 1, string.rep("─", math.min(width, opts.wrap_at or width)))
- height = height + 1
+ if stripped[h.finish + 1]:match("^---+$") then
+ stripped[h.finish + 1] = string.rep("─", math.min(width, opts.wrap_at or width))
+ else
+ table.insert(stripped, h.finish + 1, string.rep("─", math.min(width, opts.wrap_at or width)))
+ offset = offset + 1
+ height = height + 1
+ end
end
end
end
@@ -1144,27 +1167,28 @@ function M.fancy_floating_markdown(contents, opts)
api.nvim_win_set_option(winnr, 'concealcursor', 'n')
vim.cmd("ownsyntax lsp_markdown")
+
local idx = 1
--@private
local function apply_syntax_to_region(ft, start, finish)
- if ft == '' then return end
+ if ft == "" then
+ vim.cmd(string.format("syntax region markdownCode start=+\\%%%dl+ end=+\\%%%dl+ keepend extend", start, finish + 1))
+ return
+ end
local name = ft..idx
idx = idx + 1
local lang = "@"..ft:upper()
+ -- HACK: reset current_syntax, since some syntax files like markdown won't load if it is already set
+ pcall(vim.api.nvim_buf_del_var, bufnr, "current_syntax")
-- TODO(ashkan): better validation before this.
if not pcall(vim.cmd, string.format("syntax include %s syntax/%s.vim", lang, ft)) then
return
end
- vim.cmd(string.format("syntax region %s start=+\\%%%dl+ end=+\\%%%dl+ contains=%s", name, start, finish + 1, lang))
+ vim.cmd(string.format("syntax region %s start=+\\%%%dl+ end=+\\%%%dl+ contains=%s keepend", name, start, finish + 1, lang))
end
- -- Previous highlight region.
- -- TODO(ashkan): this wasn't working for some reason, but I would like to
- -- make sure that regions between code blocks are definitely markdown.
- -- local ph = {start = 0; finish = 1;}
+
for _, h in ipairs(highlights) do
- -- apply_syntax_to_region('markdown', ph.finish, h.start)
apply_syntax_to_region(h.ft, h.start, h.finish)
- -- ph = h
end
vim.api.nvim_set_current_win(cwin)
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 68a1bba78d..38d0a7dadf 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -753,8 +753,12 @@ get_number (
skip_redraw = TRUE; /* skip redraw once */
do_redraw = FALSE;
break;
- } else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
+ } else if (c == Ctrl_C || c == ESC || c == 'q') {
+ n = 0;
break;
+ } else if (c == CAR || c == NL) {
+ break;
+ }
}
no_mapping--;
return n;
@@ -771,11 +775,13 @@ int prompt_for_number(int *mouse_used)
int save_cmdline_row;
int save_State;
- /* When using ":silent" assume that <CR> was entered. */
- if (mouse_used != NULL)
- MSG_PUTS(_("Type number and <Enter> or click with mouse (empty cancels): "));
- else
- MSG_PUTS(_("Type number and <Enter> (empty cancels): "));
+ // When using ":silent" assume that <CR> was entered.
+ if (mouse_used != NULL) {
+ MSG_PUTS(_("Type number and <Enter> or click with the mouse "
+ "(q or empty cancels): "));
+ } else {
+ MSG_PUTS(_("Type number and <Enter> (q or empty cancels): "));
+ }
/* Set the state such that text can be selected/copied/pasted and we still
* get mouse events. */
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index ac27e92932..1a9bbe26f0 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -2672,7 +2672,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum)
static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
int *opened_window)
{
- win_T *usable_win_ptr = NULL;
+ win_T *usable_wp = NULL;
bool usable_win = false;
// If opening a new window, then don't use the location list referred by
@@ -2681,8 +2681,8 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
qf_info_T *ll_ref = newwin ? NULL : curwin->w_llist_ref;
if (ll_ref != NULL) {
// Find a non-quickfix window with this location list
- usable_win_ptr = qf_find_win_with_loclist(ll_ref);
- if (usable_win_ptr != NULL) {
+ usable_wp = qf_find_win_with_loclist(ll_ref);
+ if (usable_wp != NULL) {
usable_win = true;
}
}
@@ -2710,7 +2710,7 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
*opened_window = true; // close it when fail
} else {
if (curwin->w_llist_ref != NULL) { // In a location window
- qf_goto_win_with_ll_file(usable_win_ptr, qf_fnum, ll_ref);
+ qf_goto_win_with_ll_file(usable_wp, qf_fnum, ll_ref);
} else { // In a quickfix window
qf_goto_win_with_qfl_file(qf_fnum);
}
@@ -3038,14 +3038,11 @@ theend:
qfl->qf_ptr = qf_ptr;
qfl->qf_index = qf_index;
}
- if (p_swb != old_swb && opened_window) {
+ if (p_swb != old_swb && p_swb == empty_option && opened_window) {
// Restore old 'switchbuf' value, but not when an autocommand or
// modeline has changed the value.
- if (p_swb == empty_option) {
- p_swb = old_swb;
- swb_flags = old_swb_flags;
- } else
- free_string_option(old_swb);
+ p_swb = old_swb;
+ swb_flags = old_swb_flags;
}
}
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 93f567b3a0..85d1bc7076 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -319,19 +319,19 @@ func Test_setbufvar_options()
let prev_id = win_getid()
wincmd j
- let wh = winheight('.')
+ let wh = winheight(0)
let dummy_buf = bufnr('dummy_buf1', v:true)
call setbufvar(dummy_buf, '&buftype', 'nofile')
execute 'belowright vertical split #' . dummy_buf
- call assert_equal(wh, winheight('.'))
+ call assert_equal(wh, winheight(0))
let dum1_id = win_getid()
wincmd h
- let wh = winheight('.')
+ let wh = winheight(0)
let dummy_buf = bufnr('dummy_buf2', v:true)
call setbufvar(dummy_buf, '&buftype', 'nofile')
execute 'belowright vertical split #' . dummy_buf
- call assert_equal(wh, winheight('.'))
+ call assert_equal(wh, winheight(0))
bwipe!
call win_gotoid(prev_id)
@@ -1067,6 +1067,22 @@ func Test_inputlist()
call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx')
call assert_equal(3, c)
+ " CR to cancel
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<cr>", 'tx')
+ call assert_equal(0, c)
+
+ " Esc to cancel
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<Esc>", 'tx')
+ call assert_equal(0, c)
+
+ " q to cancel
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>q", 'tx')
+ call assert_equal(0, c)
+
+ " Cancel after inputting a number
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>5q", 'tx')
+ call assert_equal(0, c)
+
call assert_fails('call inputlist("")', 'E686:')
endfunc
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 06a0fd5001..bf15f7f52b 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -14,7 +14,7 @@ func s:setup_commands(cchar)
command! -nargs=* Xaddexpr <mods>caddexpr <args>
command! -nargs=* -count Xolder <mods><count>colder <args>
command! -nargs=* Xnewer <mods>cnewer <args>
- command! -nargs=* Xopen <mods>copen <args>
+ command! -nargs=* Xopen <mods> copen <args>
command! -nargs=* Xwindow <mods>cwindow <args>
command! -nargs=* Xbottom <mods>cbottom <args>
command! -nargs=* Xclose <mods>cclose <args>
@@ -32,8 +32,8 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
command! -nargs=* Xexpr <mods>cexpr <args>
- command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
- command! -nargs=* Xvimgrepadd <mods>vimgrepadd <args>
+ command! -count -nargs=* Xvimgrep <mods> <count>vimgrep <args>
+ command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
command! -nargs=* Xgrep <mods> grep <args>
command! -nargs=* Xgrepadd <mods> grepadd <args>
command! -nargs=* Xhelpgrep helpgrep <args>
@@ -51,7 +51,7 @@ func s:setup_commands(cchar)
command! -nargs=* Xaddexpr <mods>laddexpr <args>
command! -nargs=* -count Xolder <mods><count>lolder <args>
command! -nargs=* Xnewer <mods>lnewer <args>
- command! -nargs=* Xopen <mods>lopen <args>
+ command! -nargs=* Xopen <mods> lopen <args>
command! -nargs=* Xwindow <mods>lwindow <args>
command! -nargs=* Xbottom <mods>lbottom <args>
command! -nargs=* Xclose <mods>lclose <args>
@@ -69,8 +69,8 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
command! -nargs=* Xexpr <mods>lexpr <args>
- command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
- command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
+ command! -count -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
+ command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
command! -nargs=* Xgrep <mods> lgrep <args>
command! -nargs=* Xgrepadd <mods> lgrepadd <args>
command! -nargs=* Xhelpgrep lhelpgrep <args>
@@ -157,6 +157,12 @@ func XlistTests(cchar)
\ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
\ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
+ " For help entries in the quickfix list, only the filename without directory
+ " should be displayed
+ Xhelpgrep setqflist()
+ let l = split(execute('Xlist 1', ''), "\n")
+ call assert_match('^ 1 [^\\/]\{-}:', l[0])
+
" Error cases
call assert_fails('Xlist abc', 'E488:')
endfunc
@@ -255,13 +261,13 @@ func XwindowTests(cchar)
" Open the window
Xopen 5
call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
- \ && winheight('.') == 5)
+ \ && winheight(0) == 5)
" Opening the window again, should move the cursor to that window
wincmd t
Xopen 7
call assert_true(winnr('$') == 2 && winnr() == 2 &&
- \ winheight('.') == 7 &&
+ \ winheight(0) == 7 &&
\ getline('.') ==# '|| non-error 1')
" :cnext in quickfix window should move to the next entry
@@ -272,6 +278,14 @@ func XwindowTests(cchar)
Xwindow
call assert_true(winnr('$') == 1)
+ " Specifying the width should adjust the width for a vertically split
+ " quickfix window.
+ vert Xopen
+ call assert_equal(10, winwidth(0))
+ vert Xopen 12
+ call assert_equal(12, winwidth(0))
+ Xclose
+
if a:cchar == 'c'
" Opening the quickfix window in multiple tab pages should reuse the
" quickfix buffer
@@ -352,6 +366,13 @@ func XfileTests(cchar)
\ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
+ " Test for a file with a long line and without a newline at the end
+ let text = repeat('x', 1024)
+ let t = 'a.txt:18:' . text
+ call writefile([t], 'Xqftestfile1', 'b')
+ silent! Xfile Xqftestfile1
+ call assert_equal(text, g:Xgetlist()[0].text)
+
call delete('Xqftestfile1')
endfunc
@@ -475,6 +496,12 @@ func Xtest_browse(cchar)
call assert_equal(5, g:Xgetlist({'idx':0}).idx)
2Xcc
call assert_equal(2, g:Xgetlist({'idx':0}).idx)
+ if a:cchar == 'c'
+ cc
+ else
+ ll
+ endif
+ call assert_equal(2, g:Xgetlist({'idx':0}).idx)
10Xcc
call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Xlast
@@ -483,6 +510,14 @@ func Xtest_browse(cchar)
call assert_equal(11, line('.'))
call assert_fails('Xnext', 'E553')
call assert_fails('Xnfile', 'E553')
+ " To process the range using quickfix list entries, directly use the
+ " quickfix commands (don't use the user defined commands)
+ if a:cchar == 'c'
+ $cc
+ else
+ $ll
+ endif
+ call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Xrewind
call assert_equal('Xqftestfile1', bufname('%'))
call assert_equal(5, line('.'))
@@ -1095,6 +1130,10 @@ func Xinvalid_efm_Tests(cchar)
set efm=%f:%l:%m,%f:%l:%m:%R
call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
+ " Invalid regular expression
+ set efm=%\\%%k
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
+
set efm=
call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
@@ -1125,6 +1164,11 @@ func Test_efm2()
let l = split(execute('clist', ''), "\n")
call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
+ " Test for a long line
+ cexpr 'Xtestfile:' . repeat('a', 1026)
+ let l = getqflist()
+ call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
+
" Test for %P, %Q and %t format specifiers
let lines =<< trim [DATA]
[Xtestfile1]
@@ -1162,6 +1206,14 @@ func Test_efm2()
call delete('Xtestfile2')
call delete('Xtestfile3')
+ " Test for %P, %Q with non-existing files
+ cexpr lines
+ let l = getqflist()
+ call assert_equal(14, len(l))
+ call assert_equal('[Xtestfile1]', l[0].text)
+ call assert_equal('[Xtestfile2]', l[6].text)
+ call assert_equal('[Xtestfile3]', l[9].text)
+
" Tests for %E, %C and %Z format specifiers
let lines =<< trim [DATA]
Error 275
@@ -1203,18 +1255,19 @@ func Test_efm2()
File "/usr/lib/python2.2/unittest.py", line 286, in
failUnlessEqual
raise self.failureException, \\
- AssertionError: 34 != 33
+ W:AssertionError: 34 != 33
--------------------------------------------------------------
Ran 27 tests in 0.063s
[DATA]
- set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
+ set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
cgetexpr lines
let l = getqflist()
call assert_equal(8, len(l))
call assert_equal(89, l[4].lnum)
call assert_equal(1, l[4].valid)
call assert_equal(expand('unittests/dbfacadeTest.py'), bufname(l[4].bufnr))
+ call assert_equal('W', l[4].type)
" Test for %o
set efm=%f(%o):%l\ %m
@@ -1231,6 +1284,14 @@ func Test_efm2()
bd
call delete("Xotestfile")
+ " Test for a long module name
+ cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
+ let l = getqflist()
+ " call assert_equal(repeat('m', 1024), l[0].module)
+ call assert_equal(repeat('m', 1023), l[0].module)
+ call assert_equal(15, l[0].lnum)
+ call assert_equal('message', l[0].text)
+
" The following sequence of commands used to crash Vim
set efm=%W%m
cgetexpr ['msg1']
@@ -1716,9 +1777,11 @@ func Test_switchbuf()
call assert_equal(winid, win_getid())
2cnext
call assert_equal(winid, win_getid())
- enew
+ " Test for 'switchbuf' set to search for files in windows in the current
+ " tabpage and jump to an existing window (if present)
set switchbuf=useopen
+ enew
cfirst | cnext
call assert_equal(file1_winid, win_getid())
2cnext
@@ -1726,6 +1789,8 @@ func Test_switchbuf()
2cnext
call assert_equal(file2_winid, win_getid())
+ " Test for 'switchbuf' set to search for files in tabpages and jump to an
+ " existing tabpage (if present)
enew | only
set switchbuf=usetab
tabedit Xqftestfile1
@@ -1744,6 +1809,7 @@ func Test_switchbuf()
call assert_equal(4, tabpagenr())
tabfirst | tabonly | enew
+ " Test for 'switchbuf' set to open a new window for every file
set switchbuf=split
cfirst | cnext
call assert_equal(1, winnr('$'))
@@ -1751,9 +1817,10 @@ func Test_switchbuf()
call assert_equal(2, winnr('$'))
cnext | cnext
call assert_equal(3, winnr('$'))
- enew | only
+ " Test for 'switchbuf' set to open a new tabpage for every file
set switchbuf=newtab
+ enew | only
cfirst | cnext
call assert_equal(1, tabpagenr('$'))
cnext | cnext
@@ -1770,6 +1837,8 @@ func Test_switchbuf()
call assert_equal(last_winid, win_getid())
enew | only
+ " With an empty 'switchbuf', jumping to a quickfix entry should open the
+ " file in an existing window (if present)
set switchbuf=
edit Xqftestfile1
let file1_winid = win_getid()
@@ -1799,6 +1868,32 @@ func Test_switchbuf()
call assert_equal(4, tabpagenr())
tabfirst | tabonly | enew | only
+ " Jumping to a file that is not present in any of the tabpages and the
+ " current tabpage doesn't have any usable windows, should open it in a new
+ " window in the current tabpage.
+ copen | only
+ cfirst
+ call assert_equal(1, tabpagenr())
+ call assert_equal('Xqftestfile1', bufname(''))
+
+ " If opening a file changes 'switchbuf', then the new value should be
+ " retained.
+ call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
+ enew | only
+ set switchbuf&vim
+ cexpr "Xqftestfile1:1:10"
+ call assert_equal('split', &switchbuf)
+ call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
+ enew | only
+ set switchbuf=useopen
+ cexpr "Xqftestfile1:1:10"
+ call assert_equal('usetab', &switchbuf)
+ call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
+ enew | only
+ set switchbuf=useopen
+ cexpr "Xqftestfile1:1:10"
+ call assert_equal('', &switchbuf)
+
call delete('Xqftestfile1')
call delete('Xqftestfile2')
call delete('Xqftestfile3')
@@ -1825,11 +1920,16 @@ func Xadjust_qflnum(cchar)
call append(6, ['Buffer', 'Window'])
let l = g:Xgetlist()
-
call assert_equal(5, l[0].lnum)
call assert_equal(6, l[2].lnum)
call assert_equal(13, l[3].lnum)
+ " If a file doesn't have any quickfix entries, then deleting lines in the
+ " file should not update the quickfix list
+ call g:Xsetlist([], 'f')
+ 1,2delete
+ call assert_equal([], g:Xgetlist())
+
enew!
call delete(fname)
endfunc
@@ -2617,7 +2717,7 @@ func XvimgrepTests(cchar)
call assert_equal(2, len(l))
call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
- Xvimgrep #\cvim#g Xtestfile?
+ 10Xvimgrep #\cvim#g Xtestfile?
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(8, l[0].col)
@@ -3690,6 +3790,41 @@ func Test_vimgrep_autocmd()
call setqflist([], 'f')
endfunc
+" Test for an autocmd changing the current directory when running vimgrep
+func Xvimgrep_autocmd_cd(cchar)
+ call s:setup_commands(a:cchar)
+
+ %bwipe
+ let save_cwd = getcwd()
+
+ augroup QF_Test
+ au!
+ autocmd BufRead * silent cd %:p:h
+ augroup END
+
+ 10Xvimgrep /vim/ Xdir/**
+ let l = g:Xgetlist()
+ call assert_equal('f1.txt', bufname(l[0].bufnr))
+ call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
+
+ augroup QF_Test
+ au!
+ augroup END
+
+ exe 'cd ' . save_cwd
+endfunc
+
+func Test_vimgrep_autocmd_cd()
+ call mkdir('Xdir/a', 'p')
+ call mkdir('Xdir/b', 'p')
+ call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
+ call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
+ call Xvimgrep_autocmd_cd('c')
+ call Xvimgrep_autocmd_cd('l')
+ %bwipe
+ call delete('Xdir', 'rf')
+endfunc
+
" The following test used to crash Vim
func Test_lhelpgrep_autocmd()
lhelpgrep quickfix
diff --git a/test/functional/eval/null_spec.lua b/test/functional/eval/null_spec.lua
index 4f29811095..8f0041ff27 100644
--- a/test/functional/eval/null_spec.lua
+++ b/test/functional/eval/null_spec.lua
@@ -97,7 +97,7 @@ describe('NULL', function()
null_expr_test('makes filter() return v:_null_list', 'filter(L, "1") is# L', 0, 1)
null_test('is treated by :let as empty list', ':let [l] = L', 'Vim(let):E688: More targets than List items')
null_expr_test('is accepted as an empty list by inputlist()', '[feedkeys("\\n"), inputlist(L)]',
- 'Type number and <Enter> or click with mouse (empty cancels): ', {0, 0})
+ 'Type number and <Enter> or click with the mouse (q or empty cancels): ', {0, 0})
null_expr_test('is accepted as an empty list by writefile()',
('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname),
0, {0, {}})
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 9d7719a7c0..72468392ee 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -811,7 +811,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:^~ }|
]], messages={
- {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with mouse (empty cancels): ' } }, kind = ""}
+ {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""}
}}
feed('1')
@@ -822,7 +822,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:^~ }|
]], messages={
- {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with mouse (empty cancels): ' } }, kind = ""},
+ {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""},
{ content = { { "1" } }, kind = "" }
}}