diff options
45 files changed, 852 insertions, 287 deletions
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index ae43aeeb25..dcdc2384dc 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -759,13 +759,15 @@ three lines: > 3:d<CR> is translated into: .,.+2d<CR> < -Visual Mode and Range *v_:* - *:star-visual-range* +Visual Mode and Range + *v_:* {Visual}: Starts a command-line with the Visual selected lines as a range. The code `:'<,'>` is used for this range, which makes it possible to select a similar line from the command-line history for repeating a command on different Visually selected lines. + +:* *:star* *:star-visual-range* When Visual mode was already ended, a short way to use the Visual area for a range is `:*`. diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index ee42edf154..77cbf7d9b7 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -360,6 +360,22 @@ Overview of which map command works in which mode. More details below. :cmap :cnoremap :cunmap Command-line :tmap :tnoremap :tunmap Terminal +Same information in a table: + *map-table* + Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang | ~ +Command +------+-----+-----+-----+-----+-----+------+------+ ~ +[nore]map | yes | - | - | yes | yes | yes | - | - | +n[nore]map | yes | - | - | - | - | - | - | - | +[nore]map! | - | yes | yes | - | - | - | - | - | +i[nore]map | - | yes | - | - | - | - | - | - | +c[nore]map | - | - | yes | - | - | - | - | - | +v[nore]map | - | - | - | yes | yes | - | - | - | +x[nore]map | - | - | - | yes | - | - | - | - | +s[nore]map | - | - | - | - | yes | - | - | - | +o[nore]map | - | - | - | - | - | yes | - | - | +t[nore]map | - | - | - | - | - | - | yes | - | +l[nore]map | - | yes | yes | - | - | - | - | yes | + COMMANDS MODES ~ Normal Visual+Select Operator-pending ~ diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index fd7af55e87..cc9696e536 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 @@ -5056,6 +5052,7 @@ A jump table for the options with a short description can be found at |Q_op|. global values for local options) options all options and mappings (also global values for local options) + skiprtp exclude 'runtimepath' and 'packpath' from the options resize size of the Vim window: 'lines' and 'columns' sesdir the directory in which the session file is located will become the current directory (useful with diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index c67e52bd42..a937cfee98 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -1014,13 +1014,6 @@ commands can be combined to create a NewGrep command: > updated. With the [!] any changes in the current buffer are abandoned. - 'f' When the 'f' flag is specified, fuzzy string - matching is used to find matching lines. In this - case, {pattern} is treated as a literal string - instead of a regular expression. See - |matchfuzzy()| for more info about fuzzy - matching. - |QuickFixCmdPre| and |QuickFixCmdPost| are triggered. A file that is opened for matching may use a buffer number, but it is reused if possible to avoid diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index b237d70760..dd05084652 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -50,6 +50,11 @@ Multiple repeats *multi-repeat* :[range]v[global]/{pattern}/[cmd] Same as :g!. +Example: > + :g/^Obsolete/d _ +Using the underscore after `:d` avoids clobbering registers or the clipboard. +This also makes it faster. + Instead of the '/' which surrounds the {pattern}, you can use any other single byte character, but not an alphabetic character, '\', '"' or '|'. This is useful if you want to include a '/' in the search pattern or diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 474a447284..ed70ac5ce8 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -714,7 +714,7 @@ au BufNewFile,BufRead *.haml setf haml au BufNewFile,BufRead *.hsm setf hamster " Haskell -au BufNewFile,BufRead *.hs,*.hsc,*.hs-boot setf haskell +au BufNewFile,BufRead *.hs,*.hsc,*.hs-boot,*.hsig setf haskell au BufNewFile,BufRead *.lhs setf lhaskell au BufNewFile,BufRead *.chs setf chaskell au BufNewFile,BufRead cabal.project setf cabalproject diff --git a/runtime/ftplugin/meson.vim b/runtime/ftplugin/meson.vim index e432ebf196..d48fa1dfd1 100644 --- a/runtime/ftplugin/meson.vim +++ b/runtime/ftplugin/meson.vim @@ -1,6 +1,7 @@ " Vim filetype plugin file " Language: meson " License: VIM License +" Maintainer: Liam Beguin <liambeguin@gmail.com> " Original Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com> " Last Change: 2018 Nov 27 diff --git a/runtime/ftplugin/systemverilog.vim b/runtime/ftplugin/systemverilog.vim index 4d0f565fcc..e350427022 100644 --- a/runtime/ftplugin/systemverilog.vim +++ b/runtime/ftplugin/systemverilog.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: SystemVerilog " Maintainer: kocha <kocha.lsifrontend@gmail.com> -" Last Change: 12-Aug-2013. +" Last Change: 07-May-2021 if exists("b:did_ftplugin") finish @@ -9,3 +9,36 @@ endif " Behaves just like Verilog runtime! ftplugin/verilog.vim + +let s:cpo_save = &cpo +set cpo&vim + +" Add SystemVerilog keywords for matchit plugin. +if exists("loaded_matchit") + let b:match_words = + \ '\<begin\>:\<end\>,' . + \ '\<case\>\|\<casex\>\|\<casez\>:\<endcase\>,' . + \ '\<module\>:\<endmodule\>,' . + \ '\<if\>:`\@<!\<else\>,' . + \ '\<function\>:\<endfunction\>,' . + \ '`ifn\?def\>:`elsif\>:`else\>:`endif\>,' . + \ '\<task\>:\<endtask\>,' . + \ '\<specify\>:\<endspecify\>,' . + \ '\<config\>:\<endconfig\>,' . + \ '\<generate\>:\<endgenerate\>,' . + \ '\<fork\>:\<join\>\|\<join_any\>\|\<join_none\>,' . + \ '\<primitive\>:\<endprimitive\>,' . + \ '\<table\>:\<endtable\>,' . + \ '\<checker\>:\<endchecker\>,' . + \ '\<class\>:\<endclass\>,' . + \ '\<clocking\>:\<endclocking\>,' . + \ '\<gruop\>:\<endgruop\>,' . + \ '\<interface\>:\<endinterface\>,' . + \ '\<package\>:\<endpackage\>,' . + \ '\<program\>:\<endprogram\>,' . + \ '\<property\>:\<endproperty\>,' . + \ '\<sequence\>:\<endsequence\>' +endif + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/indent/meson.vim b/runtime/indent/meson.vim index f116781f74..549209ca33 100644 --- a/runtime/indent/meson.vim +++ b/runtime/indent/meson.vim @@ -2,6 +2,7 @@ " Language: Meson " License: VIM License " Maintainer: Nirbheek Chauhan <nirbheek.chauhan@gmail.com> +" Liam Beguin <liambeguin@gmail.com> " Original Authors: David Bustos <bustos@caltech.edu> " Bram Moolenaar <Bram@vim.org> " Last Change: 2019 Oct 18 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/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 0cabd1a0d4..98835d6708 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -523,27 +523,33 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) decoded.error = convert_NIL(decoded.error) decoded.result = convert_NIL(decoded.result) + -- We sent a number, so we expect a number. + local result_id = tonumber(decoded.id) + -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal. if decoded.error then + local mute_error = false if decoded.error.code == protocol.ErrorCodes.RequestCancelled then local _ = log.debug() and log.debug("Received cancellation ack", decoded) + mute_error = true elseif decoded.error.code == protocol.ErrorCodes.ContentModified then local _ = log.debug() and log.debug("Received content modified ack", decoded) + mute_error = true end - local result_id = tonumber(decoded.id) - -- Clear any callback since this is cancelled now. - -- This is safe to do assuming that these conditions hold: - -- - The server will not send a result callback after this cancellation. - -- - If the server sent this cancellation ACK after sending the result, the user of this RPC - -- client will ignore the result themselves. - if result_id then - message_callbacks[result_id] = nil + + if mute_error then + -- Clear any callback since this is cancelled now. + -- This is safe to do assuming that these conditions hold: + -- - The server will not send a result callback after this cancellation. + -- - If the server sent this cancellation ACK after sending the result, the user of this RPC + -- client will ignore the result themselves. + if result_id then + message_callbacks[result_id] = nil + end + return end - return end - -- We sent a number, so we expect a number. - local result_id = tonumber(decoded.id) local callback = message_callbacks[result_id] if callback then message_callbacks[result_id] = nil diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 83aa6747d2..7809c9b7e3 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -4,6 +4,7 @@ local validate = vim.validate local api = vim.api local list_extend = vim.list_extend local highlight = require 'vim.highlight' +local uv = vim.loop local npcall = vim.F.npcall local split = vim.split @@ -73,7 +74,7 @@ function M.set_lines(lines, A, B, new_lines) -- way the LSP describes the range including the last newline is by -- specifying a line number after what we would call the last line. local i_n = math.min(B[1] + 1, #lines) - if not (i_0 >= 1 and i_0 <= #lines and i_n >= 1 and i_n <= #lines) then + if not (i_0 >= 1 and i_0 <= #lines + 1 and i_n >= 1 and i_n <= #lines) then error("Invalid range: "..vim.inspect{A = A; B = B; #lines, new_lines}) end local prefix = "" @@ -804,9 +805,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 +826,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 +958,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 +969,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 @@ -1154,34 +1167,29 @@ function M.fancy_floating_markdown(contents, opts) api.nvim_win_set_option(winnr, 'conceallevel', 2) 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 - vim.cmd(string.format("syntax region markdownCodeBlock start=+\\%%%dl+ end=+\\%%%dl+ keepend extend", start, finish + 1)) + 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 keepend", name, start, finish + 1, lang)) end - -- Previous highlight region. - local ph = 1 + for _, h in ipairs(highlights) do - if ph <= h.start - 1 then - apply_syntax_to_region('lsp_markdown', ph, h.start - 1) - end apply_syntax_to_region(h.ft, h.start, h.finish) - ph = h.finish + 1 - end - - if ph <= #stripped then - apply_syntax_to_region('lsp_markdown', ph, #stripped) end vim.api.nvim_set_current_win(cwin) @@ -1354,6 +1362,45 @@ local position_sort = sort_by_key(function(v) return {v.start.line, v.start.character} end) +-- Gets the zero-indexed line from the given uri. +-- For non-file uris, we load the buffer and get the line. +-- If a loaded buffer exists, then that is used. +-- Otherwise we get the line using libuv which is a lot faster than loading the buffer. +--@param uri string uri of the resource to get the line from +--@param row number zero-indexed line number +--@return string the line at row in filename +function M.get_line(uri, row) + -- load the buffer if this is not a file uri + -- Custom language server protocol extensions can result in servers sending URIs with custom schemes. Plugins are able to load these via `BufReadCmd` autocmds. + if uri:sub(1, 4) ~= "file" then + local bufnr = vim.uri_to_bufnr(uri) + vim.fn.bufload(bufnr) + return (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { "" })[1] + end + + local filename = vim.uri_to_fname(uri) + + -- use loaded buffers if available + if vim.fn.bufloaded(filename) == 1 then + local bufnr = vim.fn.bufnr(filename, false) + return (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { "" })[1] + end + + local fd = uv.fs_open(filename, "r", 438) + -- TODO: what should we do in this case? + if not fd then return "" end + local stat = uv.fs_fstat(fd) + local data = uv.fs_read(fd, stat.size, 0) + uv.fs_close(fd) + + local lnum = 0 + for line in string.gmatch(data, "([^\n]*)\n?") do + if lnum == row then return line end + lnum = lnum + 1 + end + return "" +end + --- Returns the items with the byte position calculated correctly and in sorted --- order, for display in quickfix and location lists. --- @@ -1382,14 +1429,12 @@ function M.locations_to_items(locations) for _, uri in ipairs(keys) do local rows = grouped[uri] table.sort(rows, position_sort) - local bufnr = vim.uri_to_bufnr(uri) - vim.fn.bufload(bufnr) local filename = vim.uri_to_fname(uri) for _, temp in ipairs(rows) do local pos = temp.start local row = pos.line - local line = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1] - local col = M.character_offset(bufnr, row, pos.character) + local line = M.get_line(uri, row) + local col = pos.character table.insert(items, { filename = filename, lnum = row + 1, @@ -1447,13 +1492,13 @@ function M.symbols_to_items(symbols, bufnr) kind = kind, text = '['..kind..'] '..symbol.name, }) - elseif symbol.range then -- DocumentSymbole type + elseif symbol.selectionRange then -- DocumentSymbole type local kind = M._get_symbol_kind_name(symbol.kind) table.insert(_items, { -- bufnr = _bufnr, filename = vim.api.nvim_buf_get_name(_bufnr), - lnum = symbol.range.start.line + 1, - col = symbol.range.start.character + 1, + lnum = symbol.selectionRange.start.line + 1, + col = symbol.selectionRange.start.character + 1, kind = kind, text = '['..kind..'] '..symbol.name }) diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index a62df1dcec..ae1274f81f 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -2,7 +2,7 @@ " " Author: Bram Moolenaar " Copyright: Vim license applies, see ":help license" -" Last Change: 2021 Jan 03 +" Last Change: 2021 May 16 " " WORK IN PROGRESS - Only the basics work " Note: On MS-Windows you need a recent version of gdb. The one included with @@ -246,7 +246,9 @@ func s:StartDebug_term(dict) let s:gdbbuf = gdb_job_info['buffer'] let s:gdbwin = win_getid(winnr()) - " Set arguments to be run + " Set arguments to be run. First wait a bit to make detecting gdb a bit + " more reliable. + sleep 200m if len(proc_args) call chansend(s:gdb_job_id, 'set args ' . join(proc_args) . "\r") endif diff --git a/runtime/syntax/dts.vim b/runtime/syntax/dts.vim index cd4bd776b7..d75b9c178a 100644 --- a/runtime/syntax/dts.vim +++ b/runtime/syntax/dts.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: dts/dtsi (device tree files) " Maintainer: Daniel Mack <vim@zonque.org> -" Last Change: 2013 Oct 20 +" Last Change: 2021 May 15 if exists("b:current_syntax") finish @@ -9,7 +9,7 @@ endif syntax region dtsComment start="/\*" end="\*/" syntax match dtsReference "&[[:alpha:][:digit:]_]\+" -syntax region dtsBinaryProperty start="\[" end="\]" +syntax region dtsBinaryProperty start="\[" end="\]" syntax match dtsStringProperty "\".*\"" syntax match dtsKeyword "/.\{-1,\}/" syntax match dtsLabel "^[[:space:]]*[[:alpha:][:digit:]_]\+:" @@ -18,6 +18,38 @@ syntax region dtsCellProperty start="<" end=">" contains=dtsReference,dtsBinar syntax region dtsCommentInner start="/\*" end="\*/" syntax match dtsCommentLine "//.*$" +" Accept %: for # (C99) +syn region cPreCondit start="^\s*\zs\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError +syn match cPreConditMatch display "^\s*\zs\(%:\|#\)\s*\(else\|endif\)\>" +if !exists("c_no_if0") + syn cluster cCppOutInGroup contains=cCppInIf,cCppInElse,cCppInElse2,cCppOutIf,cCppOutIf2,cCppOutElse,cCppInSkip,cCppOutSkip + syn region cCppOutWrapper start="^\s*\zs\(%:\|#\)\s*if\s\+0\+\s*\($\|//\|/\*\|&\)" end=".\@=\|$" contains=cCppOutIf,cCppOutElse,@NoSpell fold + syn region cCppOutIf contained start="0\+" matchgroup=cCppOutWrapper end="^\s*\(%:\|#\)\s*endif\>" contains=cCppOutIf2,cCppOutElse + if !exists("c_no_if0_fold") + syn region cCppOutIf2 contained matchgroup=cCppOutWrapper start="0\+" end="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0\+\s*\($\|//\|/\*\|&\)\)\@!\|endif\>\)"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell fold + else + syn region cCppOutIf2 contained matchgroup=cCppOutWrapper start="0\+" end="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0\+\s*\($\|//\|/\*\|&\)\)\@!\|endif\>\)"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell + endif + syn region cCppOutElse contained matchgroup=cCppOutWrapper start="^\s*\(%:\|#\)\s*\(else\|elif\)" end="^\s*\(%:\|#\)\s*endif\>"me=s-1 contains=TOP,cPreCondit + syn region cCppInWrapper start="^\s*\zs\(%:\|#\)\s*if\s\+0*[1-9]\d*\s*\($\|//\|/\*\||\)" end=".\@=\|$" contains=cCppInIf,cCppInElse fold + syn region cCppInIf contained matchgroup=cCppInWrapper start="\d\+" end="^\s*\(%:\|#\)\s*endif\>" contains=TOP,cPreCondit + if !exists("c_no_if0_fold") + syn region cCppInElse contained start="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2 fold + else + syn region cCppInElse contained start="^\s*\(%:\|#\)\s*\(else\>\|elif\s\+\(0*[1-9]\d*\s*\($\|//\|/\*\||\)\)\@!\)" end=".\@=\|$" containedin=cCppInIf contains=cCppInElse2 + endif + syn region cCppInElse2 contained matchgroup=cCppInWrapper start="^\s*\(%:\|#\)\s*\(else\|elif\)\([^/]\|/[^/*]\)*" end="^\s*\(%:\|#\)\s*endif\>"me=s-1 contains=cSpaceError,cCppOutSkip,@Spell + syn region cCppOutSkip contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppOutSkip + syn region cCppInSkip contained matchgroup=cCppInWrapper start="^\s*\(%:\|#\)\s*\(if\s\+\(\d\+\s*\($\|//\|/\*\||\|&\)\)\@!\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" containedin=cCppOutElse,cCppInIf,cCppInSkip contains=TOP,cPreProc +endif +syn region cIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+ +syn match cIncluded display contained "<[^>]*>" +syn match cInclude display "^\s*\zs\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded +"syn match cLineSkip "\\$" +syn cluster cPreProcGroup contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOutWrapper,cCppInWrapper,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti,cBadBlock +syn region cDefine start="^\s*\zs\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell +syn region cPreProc start="^\s*\zs\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell + hi def link dtsCellProperty Number hi def link dtsBinaryProperty Number hi def link dtsStringProperty String @@ -26,5 +58,21 @@ hi def link dtsLabel Label hi def link dtsNode Structure hi def link dtsReference Macro hi def link dtsComment Comment -hi def link dtsCommentInner Comment +hi def link dtsCommentInner Comment hi def link dtsCommentLine Comment + +hi def link cInclude Include +hi def link cPreProc PreProc +hi def link cDefine Macro +hi def link cIncluded cString +hi def link cString String + +hi def link cCppInWrapper cCppOutWrapper +hi def link cCppOutWrapper cPreCondit +hi def link cPreConditMatch cPreCondit +hi def link cPreCondit PreCondit +hi def link cCppOutSkip cCppOutIf2 + +hi def link cCppInElse2 cCppOutIf2 +hi def link cCppOutIf2 cCppOut +hi def link cCppOut Comment diff --git a/runtime/syntax/meson.vim b/runtime/syntax/meson.vim index 78de2ab89e..7e6b565f19 100644 --- a/runtime/syntax/meson.vim +++ b/runtime/syntax/meson.vim @@ -2,6 +2,7 @@ " Language: Meson " License: VIM License " Maintainer: Nirbheek Chauhan <nirbheek.chauhan@gmail.com> +" Liam Beguin <liambeguin@gmail.com> " Last Change: 2019 Oct 18 " Credits: Zvezdan Petkovic <zpetkovic@acm.org> " Neil Schemenauer <nas@meson.ca> @@ -17,11 +18,7 @@ " let meson_space_error_highlight = 1 " -" For version 5.x: Clear all syntax items. -" For version 6.x: Quit when a syntax file was already loaded. -if version < 600 - syntax clear -elseif exists("b:current_syntax") +if exists("b:current_syntax") finish endif @@ -32,8 +29,9 @@ set cpo&vim " http://mesonbuild.com/Syntax.html syn keyword mesonConditional elif else if endif -syn keyword mesonRepeat foreach endforeach -syn keyword mesonOperator and not or +syn keyword mesonRepeat foreach endforeach +syn keyword mesonOperator and not or in +syn keyword mesonStatement continue break syn match mesonComment "#.*$" contains=mesonTodo,@Spell syn keyword mesonTodo FIXME NOTE NOTES TODO XXX contained @@ -117,10 +115,12 @@ syn keyword mesonBuiltin \ subdir \ subdir_done \ subproject + \ summary \ target_machine \ test \ vcs_tag \ warning + \ range if exists("meson_space_error_highlight") " trailing whitespace @@ -130,31 +130,20 @@ if exists("meson_space_error_highlight") syn match mesonSpaceError display "\t\+ " endif -if version >= 508 || !exists("did_meson_syn_inits") - if version <= 508 - let did_meson_syn_inits = 1 - command -nargs=+ HiLink hi link <args> - else - command -nargs=+ HiLink hi def link <args> - endif - - " The default highlight links. Can be overridden later. - HiLink mesonStatement Statement - HiLink mesonConditional Conditional - HiLink mesonRepeat Repeat - HiLink mesonOperator Operator - HiLink mesonComment Comment - HiLink mesonTodo Todo - HiLink mesonString String - HiLink mesonEscape Special - HiLink mesonNumber Number - HiLink mesonBuiltin Function - HiLink mesonConstant Number - if exists("meson_space_error_highlight") - HiLink mesonSpaceError Error - endif - - delcommand HiLink +" The default highlight links. Can be overridden later. +hi def link mesonStatement Statement +hi def link mesonConditional Conditional +hi def link mesonRepeat Repeat +hi def link mesonOperator Operator +hi def link mesonComment Comment +hi def link mesonTodo Todo +hi def link mesonString String +hi def link mesonEscape Special +hi def link mesonNumber Number +hi def link mesonBuiltin Function +hi def link mesonConstant Number +if exists("meson_space_error_higlight") + hi def link mesonSpaceError Error endif let b:current_syntax = "meson" diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 31b7b1bd8f..5f8b81822b 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -982,12 +982,14 @@ static int check_external_diff(diffio_T *diffio) char_u linebuf[LBUFLEN]; for (;;) { - // There must be a line that contains "1c1". + // For normal diff there must be a line that contains + // "1c1". For unified diff "@@ -1 +1 @@". if (vim_fgets(linebuf, LBUFLEN, fd)) { break; } - if (STRNCMP(linebuf, "1c1", 3) == 0) { + if (STRNCMP(linebuf, "1c1", 3) == 0 + || STRNCMP(linebuf, "@@ -1 +1 @@", 11) == 0) { ok = kTrue; } } diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 9e4e69e124..c1e52d6994 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -937,11 +937,13 @@ void ex_mkrc(exarg_T *eap) if (!view_session || (eap->cmdidx == CMD_mksession && (*flagp & SSOP_OPTIONS))) { - failed |= (makemap(fd, NULL) == FAIL - || makeset(fd, OPT_GLOBAL, false) == FAIL); - if (p_hls && fprintf(fd, "%s", "set hlsearch\n") < 0) { - failed = true; + int flags = OPT_GLOBAL; + + if (eap->cmdidx == CMD_mksession && (*flagp & SSOP_SKIP_RTP)) { + flags |= OPT_SKIPRTP; } + failed |= (makemap(fd, NULL) == FAIL + || makeset(fd, flags, false) == FAIL); } if (!failed && view_session) { @@ -1002,6 +1004,9 @@ void ex_mkrc(exarg_T *eap) < 0) { failed = true; } + if (p_hls && fprintf(fd, "%s", "set hlsearch\n") < 0) { + failed = true; + } if (no_hlsearch && fprintf(fd, "%s", "nohlsearch\n") < 0) { failed = true; } 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/option.c b/src/nvim/option.c index 8f8a57caf2..335fa1cb62 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -5232,6 +5232,11 @@ int makeset(FILE *fd, int opt_flags, int local_only) continue; } + if ((opt_flags & OPT_SKIPRTP) + && (p->var == (char_u *)&p_rtp || p->var == (char_u *)&p_pp)) { + continue; + } + round = 2; if (p->indir != PV_NONE) { if (p->var == VAR_WIN) { diff --git a/src/nvim/option.h b/src/nvim/option.h index 60f14dea44..c6ee03e052 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -19,6 +19,9 @@ typedef enum { OPT_MODELINE = 8, ///< Option in modeline. OPT_WINONLY = 16, ///< Only set window-local options. OPT_NOWIN = 32, ///< Don’t set window-local options. + OPT_ONECOLUMN = 64, ///< list options one per line + OPT_NO_REDRAW = 128, ///< ignore redraw flags on option + OPT_SKIPRTP = 256, ///< "skiprtp" in 'sessionoptions' } OptionFlags; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 62df28c55e..beb62a6a0b 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -572,11 +572,12 @@ EXTERN char_u *p_slm; // 'selectmode' EXTERN char_u *p_ssop; // 'sessionoptions' EXTERN unsigned ssop_flags; # ifdef IN_OPTION_C -// Also used for 'viewoptions'! +// Also used for 'viewoptions'! Keep in sync with SSOP_ flags. static char *(p_ssop_values[]) = { "buffers", "winpos", "resize", "winsize", "localoptions", "options", "help", "blank", "globals", "slash", "unix", - "sesdir", "curdir", "folds", "cursor", "tabpages", NULL + "sesdir", "curdir", "folds", "cursor", "tabpages", "terminal", "skiprtp", + NULL }; # endif # define SSOP_BUFFERS 0x001 @@ -595,6 +596,8 @@ static char *(p_ssop_values[]) = { # define SSOP_FOLDS 0x2000 # define SSOP_CURSOR 0x4000 # define SSOP_TABPAGES 0x8000 +# define SSOP_TERMINAL 0x10000 +# define SSOP_SKIP_RTP 0x20000 EXTERN char_u *p_sh; // 'shell' EXTERN char_u *p_shcf; // 'shellcmdflag' 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/regexp.c b/src/nvim/regexp.c index e0cc25421a..accf9b0bb5 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -692,6 +692,7 @@ static char_u *regparse; ///< Input-scan pointer. static int prevchr_len; ///< byte length of previous char static int num_complex_braces; ///< Complex \{...} count static int regnpar; ///< () count. +static bool wants_nfa; ///< regex should use NFA engine static int regnzpar; ///< \z() count. static int re_has_z; ///< \z item detected static char_u *regcode; ///< Code-emit pointer, or JUST_CALC_SIZE @@ -3974,17 +3975,25 @@ static bool regmatch( pos = getmark_buf(rex.reg_buf, mark, false); if (pos == NULL // mark doesn't exist - || pos->lnum <= 0 // mark isn't set in reg_buf - || (pos->lnum == rex.lnum + rex.reg_firstlnum - ? (pos->col == (colnr_T)(rex.input - rex.line) - ? (cmp == '<' || cmp == '>') - : (pos->col < (colnr_T)(rex.input - rex.line) - ? cmp != '>' - : cmp != '<')) - : (pos->lnum < rex.lnum + rex.reg_firstlnum - ? cmp != '>' - : cmp != '<'))) { + || pos->lnum <= 0) { // mark isn't set in reg_buf status = RA_NOMATCH; + } else { + const colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum + && pos->col == MAXCOL + ? (colnr_T)STRLEN(reg_getline(pos->lnum - rex.reg_firstlnum)) + : pos->col; + + if (pos->lnum == rex.lnum + rex.reg_firstlnum + ? (pos_col == (colnr_T)(rex.input - rex.line) + ? (cmp == '<' || cmp == '>') + : (pos_col < (colnr_T)(rex.input - rex.line) + ? cmp != '>' + : cmp != '<')) + : (pos->lnum < rex.lnum + rex.reg_firstlnum + ? cmp != '>' + : cmp != '<')) { + status = RA_NOMATCH; + } } } break; @@ -7240,7 +7249,7 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) // Check for error compiling regexp with initial engine. if (prog == NULL) { #ifdef BT_REGEXP_DEBUG_LOG - // Debugging log for NFA. + // Debugging log for BT engine. if (regexp_engine != BACKTRACKING_ENGINE) { FILE *f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a"); if (f) { @@ -7257,6 +7266,7 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) // But don't try if an error message was given. if (regexp_engine == AUTOMATIC_ENGINE && !called_emsg) { regexp_engine = BACKTRACKING_ENGINE; + report_re_switch(expr); prog = bt_regengine.regcomp(expr, re_flags); } } diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 923db6422e..5047e0db03 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -328,6 +328,11 @@ static int *post_start; ///< holds the postfix form of r.e. static int *post_end; static int *post_ptr; +// Set when the pattern should use the NFA engine. +// E.g. [[:upper:]] only allows 8bit characters for BT engine, +// while NFA engine handles multibyte characters correctly. +static bool wants_nfa; + static int nstate; ///< Number of states in the NFA. Also used when executing. static int istate; ///< Index in the state vector, used in alloc_state() @@ -377,6 +382,7 @@ nfa_regcomp_start ( post_start = (int *)xmalloc(postfix_size); post_ptr = post_start; post_end = post_start + nstate_max; + wants_nfa = false; rex.nfa_has_zend = false; rex.nfa_has_backref = false; @@ -1618,6 +1624,7 @@ collection: EMIT(NFA_CLASS_GRAPH); break; case CLASS_LOWER: + wants_nfa = true; EMIT(NFA_CLASS_LOWER); break; case CLASS_PRINT: @@ -1630,6 +1637,7 @@ collection: EMIT(NFA_CLASS_SPACE); break; case CLASS_UPPER: + wants_nfa = true; EMIT(NFA_CLASS_UPPER); break; case CLASS_XDIGIT: @@ -1998,10 +2006,17 @@ static int nfa_regpiece(void) return OK; } - // The engine is very inefficient (uses too many states) when the maximum - // is much larger than the minimum and when the maximum is large. Bail out - // if we can use the other engine. - if ((nfa_re_flags & RE_AUTO) && (maxval > 500 || maxval > minval + 200)) { + // The engine is very inefficient (uses too many states) when the + // maximum is much larger than the minimum and when the maximum is + // large. However, when maxval is MAX_LIMIT, it is okay, as this + // will emit NFA_STAR. + // Bail out if we can use the other engine, but only, when the + // pattern does not need the NFA engine like (e.g. [[:upper:]]\{2,\} + // does not work with with characters > 8 bit with the BT engine) + if ((nfa_re_flags & RE_AUTO) + && (maxval > 500 || maxval > minval + 200) + && (maxval != MAX_LIMIT && minval < 200) + && !wants_nfa) { return FAIL; } @@ -6055,21 +6070,27 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, { pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, false); - // Compare the mark position to the match position. - result = (pos != NULL // mark doesn't exist - && pos->lnum > 0 // mark isn't set in reg_buf - && (pos->lnum == rex.lnum + rex.reg_firstlnum - ? (pos->col == (colnr_T)(rex.input - rex.line) - ? t->state->c == NFA_MARK - : (pos->col < (colnr_T)(rex.input - rex.line) - ? t->state->c == NFA_MARK_GT - : t->state->c == NFA_MARK_LT)) - : (pos->lnum < rex.lnum + rex.reg_firstlnum - ? t->state->c == NFA_MARK_GT - : t->state->c == NFA_MARK_LT))); - if (result) { - add_here = true; - add_state = t->state->out; + // Compare the mark position to the match position, if the mark + // exists and mark is set in reg_buf. + if (pos != NULL && pos->lnum > 0) { + const colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum + && pos->col == MAXCOL + ? (colnr_T)STRLEN(reg_getline(pos->lnum - rex.reg_firstlnum)) + : pos->col; + + result = pos->lnum == rex.lnum + rex.reg_firstlnum + ? (pos_col == (colnr_T)(rex.input - rex.line) + ? t->state->c == NFA_MARK + : (pos_col < (colnr_T)(rex.input - rex.line) + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT)) + : (pos->lnum < rex.lnum + rex.reg_firstlnum + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT); + if (result) { + add_here = true; + add_state = t->state->out; + } } break; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 5151d82c1b..90ac4ac7aa 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -4138,9 +4138,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, // highlight the cursor position itself. // Also highlight the 'colorcolumn' if it is different than // 'cursorcolumn' + // Also highlight the 'colorcolumn' if 'breakindent' and/or 'showbreak' + // options are set vcol_save_attr = -1; - if (draw_state == WL_LINE && !lnum_in_visual_area - && search_attr == 0 && area_attr == 0) { + if ((draw_state == WL_LINE + || draw_state == WL_BRI + || draw_state == WL_SBR) + && !lnum_in_visual_area + && search_attr == 0 + && area_attr == 0 + && filler_todo <= 0) { if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum) { vcol_save_attr = char_attr; diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim index 0e20ac1593..f456ff4250 100644 --- a/src/nvim/testdir/shared.vim +++ b/src/nvim/testdir/shared.vim @@ -179,7 +179,7 @@ endfunc func s:WaitForCommon(expr, assert, timeout) " using reltime() is more accurate, but not always available let slept = 0 - if has('reltime') + if exists('*reltimefloat') let start = reltime() endif @@ -204,7 +204,7 @@ func s:WaitForCommon(expr, assert, timeout) endif sleep 10m - if has('reltime') + if exists('*reltimefloat') let slept = float2nr(reltimefloat(reltime(start)) * 1000) else let slept += 10 @@ -220,7 +220,7 @@ endfunc " feeds key-input and resumes process. Return time waited in milliseconds. " Without +timers it uses simply :sleep. func Standby(msec) - if has('timers') + if has('timers') && exists('*reltimefloat') let start = reltime() let g:_standby_timer = timer_start(a:msec, function('s:feedkeys')) call getchar() diff --git a/src/nvim/testdir/test_cscope.vim b/src/nvim/testdir/test_cscope.vim index e5dab05511..cc6154af69 100644 --- a/src/nvim/testdir/test_cscope.vim +++ b/src/nvim/testdir/test_cscope.vim @@ -22,7 +22,7 @@ endfunc func Test_cscopeWithCscopeConnections() call CscopeSetupOrClean(1) - " Test 0: E568: duplicate cscope database not added + " Test: E568: duplicate cscope database not added try set nocscopeverbose cscope add Xcscope.out @@ -33,44 +33,49 @@ func Test_cscopeWithCscopeConnections() call assert_fails('cscope add', 'E560') call assert_fails('cscope add Xcscope.out', 'E568') call assert_fails('cscope add doesnotexist.out', 'E563') + if has('unix') + call assert_fails('cscope add /dev/null', 'E564:') + endif - " Test 1: Find this C-Symbol + " Test: Find this C-Symbol for cmd in ['cs find s main', 'cs find 0 main'] let a = execute(cmd) - " Test 1.1 test where it moves the cursor + " Test where it moves the cursor call assert_equal('main(void)', getline('.')) - " Test 1.2 test the output of the :cs command + " Test the output of the :cs command call assert_match('\n(1 of 1): <<main>> main(void )', a) endfor - " Test 2: Find this definition - for cmd in ['cs find g test_mf_hash', 'cs find 1 test_mf_hash'] + " Test: Find this definition + for cmd in ['cs find g test_mf_hash', + \ 'cs find 1 test_mf_hash', + \ 'cs find 1 test_mf_hash'] " leading space ignored. exe cmd call assert_equal(['', '/*', ' * Test mf_hash_*() functions.', ' */', ' static void', 'test_mf_hash(void)', '{'], getline(line('.')-5, line('.')+1)) endfor - " Test 3: Find functions called by this function + " Test: Find functions called by this function for cmd in ['cs find d test_mf_hash', 'cs find 2 test_mf_hash'] let a = execute(cmd) call assert_match('\n(1 of 42): <<mf_hash_init>> mf_hash_init(&ht);', a) call assert_equal(' mf_hash_init(&ht);', getline('.')) endfor - " Test 4: Find functions calling this function + " Test: Find functions calling this function for cmd in ['cs find c test_mf_hash', 'cs find 3 test_mf_hash'] let a = execute(cmd) call assert_match('\n(1 of 1): <<main>> test_mf_hash();', a) call assert_equal(' test_mf_hash();', getline('.')) endfor - " Test 5: Find this text string + " Test: Find this text string for cmd in ['cs find t Bram', 'cs find 4 Bram'] let a = execute(cmd) call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a) call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.')) endfor - " Test 6: Find this egrep pattern + " Test: Find this egrep pattern " test all matches returned by cscope for cmd in ['cs find e ^\#includ.', 'cs find 6 ^\#includ.'] let a = execute(cmd) @@ -83,7 +88,7 @@ func Test_cscopeWithCscopeConnections() call assert_fails('cnext', 'E553:') endfor - " Test 7: Find the same egrep pattern using lcscope this time. + " Test: Find the same egrep pattern using lcscope this time. let a = execute('lcs find e ^\#includ.') call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a) call assert_equal('#include <assert.h>', getline('.')) @@ -93,7 +98,7 @@ func Test_cscopeWithCscopeConnections() call assert_equal('#include "memfile.c"', getline('.')) call assert_fails('lnext', 'E553:') - " Test 8: Find this file + " Test: Find this file for cmd in ['cs find f Xmemfile_test.c', 'cs find 7 Xmemfile_test.c'] enew let a = execute(cmd) @@ -101,7 +106,7 @@ func Test_cscopeWithCscopeConnections() call assert_equal('Xmemfile_test.c', @%) endfor - " Test 9: Find files #including this file + " Test: Find files #including this file for cmd in ['cs find i assert.h', 'cs find 8 assert.h'] enew let a = execute(cmd) @@ -112,39 +117,42 @@ func Test_cscopeWithCscopeConnections() call assert_equal('#include <assert.h>', getline('.')) endfor - " Test 10: Invalid find command + " Test: Invalid find command + call assert_fails('cs find', 'E560:') call assert_fails('cs find x', 'E560:') - " Test 11: Find places where this symbol is assigned a value - " this needs a cscope >= 15.8 - " unfortunately, Travis has cscope version 15.7 - let cscope_version = systemlist('cscope --version')[0] - let cs_version = str2float(matchstr(cscope_version, '\d\+\(\.\d\+\)\?')) - if cs_version >= 15.8 - for cmd in ['cs find a item', 'cs find 9 item'] - let a = execute(cmd) - call assert_equal(['', '(1 of 4): <<test_mf_hash>> item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);'], split(a, '\n', 1)) - call assert_equal(' item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);', getline('.')) - cnext - call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) - cnext - call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) - cnext - call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) - endfor + if has('float') + " Test: Find places where this symbol is assigned a value + " this needs a cscope >= 15.8 + " unfortunately, Travis has cscope version 15.7 + let cscope_version = systemlist('cscope --version')[0] + let cs_version = str2float(matchstr(cscope_version, '\d\+\(\.\d\+\)\?')) + if cs_version >= 15.8 + for cmd in ['cs find a item', 'cs find 9 item'] + let a = execute(cmd) + call assert_equal(['', '(1 of 4): <<test_mf_hash>> item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);'], split(a, '\n', 1)) + call assert_equal(' item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);', getline('.')) + cnext + call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) + cnext + call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) + cnext + call assert_equal(' item = mf_hash_find(&ht, key);', getline('.')) + endfor + endif endif - " Test 12: leading whitespace is not removed for cscope find text + " Test: leading whitespace is not removed for cscope find text let a = execute('cscope find t test_mf_hash') call assert_equal(['', '(1 of 1): <<<unknown>>> test_mf_hash();'], split(a, '\n', 1)) call assert_equal(' test_mf_hash();', getline('.')) - " Test 13: test with scscope + " Test: test with scscope let a = execute('scs find t Bram') call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a) call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.')) - " Test 14: cscope help + " Test: cscope help for cmd in ['cs', 'cs help', 'cs xxx'] let a = execute(cmd) call assert_match('^cscope commands:\n', a) @@ -158,28 +166,35 @@ func Test_cscopeWithCscopeConnections() let a = execute('scscope help') call assert_match('This cscope command does not support splitting the window\.', a) - " Test 15: reset connections + " Test: reset connections let a = execute('cscope reset') call assert_match('\nAdded cscope database.*Xcscope.out (#0)', a) call assert_match('\nAll cscope databases reset', a) - " Test 16: cscope show + " Test: cscope show let a = execute('cscope show') call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a) - " Test 17: cstag and 'csto' option + " Test: cstag and 'csto' option set csto=0 let a = execute('cstag TEST_COUNT') call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a) call assert_equal('#define TEST_COUNT 50000', getline('.')) + call assert_fails('cstag DOES_NOT_EXIST', 'E257:') set csto=1 let a = execute('cstag index_to_key') call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a) call assert_equal('#define index_to_key(i) ((i) ^ 15167)', getline('.')) - call assert_fails('cstag xxx', 'E257:') + call assert_fails('cstag DOES_NOT_EXIST', 'E257:') call assert_fails('cstag', 'E562:') + let save_tags = &tags + set tags= + call assert_fails('cstag DOES_NOT_EXIST', 'E257:') + let a = execute('cstag index_to_key') + call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a) + let &tags = save_tags - " Test 18: 'cst' option + " Test: 'cst' option set nocst call assert_fails('tag TEST_COUNT', 'E426:') set cst @@ -189,12 +204,28 @@ func Test_cscopeWithCscopeConnections() let a = execute('tags') call assert_match('1 1 TEST_COUNT\s\+\d\+\s\+#define index_to_key', a) - " Test 19: this should trigger call to cs_print_tags() + " Test: 'cscoperelative' + call mkdir('Xcscoperelative') + cd Xcscoperelative + let a = execute('cs find g test_mf_hash') + call assert_notequal('test_mf_hash(void)', getline('.')) + set cscoperelative + let a = execute('cs find g test_mf_hash') + call assert_equal('test_mf_hash(void)', getline('.')) + set nocscoperelative + cd .. + call delete('Xcscoperelative', 'd') + + " Test: E259: no match found + call assert_fails('cscope find g DOES_NOT_EXIST', 'E259:') + + " Test: this should trigger call to cs_print_tags() " Unclear how to check result though, we just exercise the code. set cst cscopequickfix=s0 call feedkeys(":cs find s main\<CR>", 't') - " Test 20: cscope kill + " Test: cscope kill + call assert_fails('cscope kill', 'E560:') call assert_fails('cscope kill 2', 'E261:') call assert_fails('cscope kill xxx', 'E261:') @@ -211,20 +242,20 @@ func Test_cscopeWithCscopeConnections() let a = execute('cscope kill -1') call assert_equal('', a) - " Test 21: 'csprg' option + " Test: 'csprg' option call assert_equal('cscope', &csprg) set csprg=doesnotexist call assert_fails('cscope add Xcscope2.out', 'E609:') set csprg=cscope - " Test 22: multiple cscope connections + " Test: multiple cscope connections cscope add Xcscope.out cscope add Xcscope2.out . -C let a = execute('cscope show') call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a) call assert_match('\n 1 \d\+.*Xcscope2.out\s*\.', a) - " Test 23: test Ex command line completion + " Test: test Ex command line completion call feedkeys(":cs \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"cs add find help kill reset show', @:) @@ -240,19 +271,26 @@ func Test_cscopeWithCscopeConnections() call feedkeys(":cs add Xcscope\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"cs add Xcscope.out Xcscope2.out', @:) - " Test 24: cscope_connection() + " Test: cscope_connection() call assert_equal(cscope_connection(), 1) call assert_equal(cscope_connection(0, 'out'), 1) call assert_equal(cscope_connection(0, 'xxx'), 1) + call assert_equal(cscope_connection(1, 'out'), 1) call assert_equal(cscope_connection(1, 'xxx'), 0) + call assert_equal(cscope_connection(2, 'out'), 0) + call assert_equal(cscope_connection(2, getcwd() .. '/Xcscope.out', 1), 1) + call assert_equal(cscope_connection(3, 'xxx', '..'), 0) call assert_equal(cscope_connection(3, 'out', 'xxx'), 0) call assert_equal(cscope_connection(3, 'out', '.'), 1) + call assert_equal(cscope_connection(4, 'out', '.'), 0) - " CleanUp + call assert_equal(cscope_connection(5, 'out'), 0) + call assert_equal(cscope_connection(-1, 'out'), 0) + call CscopeSetupOrClean(0) endfunc diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 1ade11a8ed..8592f48af7 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -802,6 +802,7 @@ func VerifyBoth(buf, dumpfile, extra) " also test unified diff call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:") + call term_sendkeys(a:buf, ":redraw!\<CR>:") call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified') call term_sendkeys(a:buf, ":call StopUnified()\<CR>:") endfunc @@ -823,10 +824,11 @@ func Test_diff_screen() func UnifiedDiffExpr() " Prepend some text to check diff type detection call writefile(['warning', ' message'], v:fname_out) - silent exe '!diff -u ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out + silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out endfunc func SetupUnified() set diffexpr=UnifiedDiffExpr() + diffupdate endfunc func StopUnified() set diffexpr= @@ -1146,4 +1148,38 @@ func Test_diff_and_scroll() set ls& endfunc +func Test_diff_filler_cursorcolumn() + CheckScreendump + + let content =<< trim END + call setline(1, ['aa', 'bb', 'cc']) + vnew + call setline(1, ['aa', 'cc']) + windo diffthis + wincmd p + setlocal cursorcolumn foldcolumn=0 + norm! gg0 + redraw! + END + call writefile(content, 'Xtest_diff_cuc') + let buf = RunVimInTerminal('-S Xtest_diff_cuc', {}) + + call VerifyScreenDump(buf, 'Test_diff_cuc_01', {}) + + call term_sendkeys(buf, "l") + call term_sendkeys(buf, "\<C-l>") + call VerifyScreenDump(buf, 'Test_diff_cuc_02', {}) + call term_sendkeys(buf, "0j") + call term_sendkeys(buf, "\<C-l>") + call VerifyScreenDump(buf, 'Test_diff_cuc_03', {}) + call term_sendkeys(buf, "l") + call term_sendkeys(buf, "\<C-l>") + call VerifyScreenDump(buf, 'Test_diff_cuc_04', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_diff_cuc') +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 056b953d0b..09fdbf4e20 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -211,7 +211,7 @@ let s:filename_checks = { \ 'gtkrc': ['.gtkrc', 'gtkrc', '.gtkrc-file', 'gtkrc-file'], \ 'haml': ['file.haml'], \ 'hamster': ['file.hsm'], - \ 'haskell': ['file.hs', 'file.hsc', 'file.hs-boot'], + \ 'haskell': ['file.hs', 'file.hsc', 'file.hs-boot', 'file.hsig'], \ 'haste': ['file.ht'], \ 'hastepreproc': ['file.htpp'], \ 'hb': ['file.hb'], diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 93f567b3a0..224ca257ab 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -28,12 +28,14 @@ func Test_empty() call assert_equal(0, empty(1)) call assert_equal(0, empty(-1)) - call assert_equal(1, empty(0.0)) - call assert_equal(1, empty(-0.0)) - call assert_equal(0, empty(1.0)) - call assert_equal(0, empty(-1.0)) - call assert_equal(0, empty(1.0/0.0)) - call assert_equal(0, empty(0.0/0.0)) + if has('float') + call assert_equal(1, empty(0.0)) + call assert_equal(1, empty(-0.0)) + call assert_equal(0, empty(1.0)) + call assert_equal(0, empty(-1.0)) + call assert_equal(0, empty(1.0/0.0)) + call assert_equal(0, empty(0.0/0.0)) + endif call assert_equal(1, empty([])) call assert_equal(0, empty(['a'])) @@ -115,7 +117,9 @@ func Test_strwidth() call assert_fails('call strwidth({->0})', 'E729:') call assert_fails('call strwidth([])', 'E730:') call assert_fails('call strwidth({})', 'E731:') - call assert_fails('call strwidth(1.2)', 'E806:') + if has('float') + call assert_fails('call strwidth(1.2)', 'E806:') + endif endfor set ambiwidth& @@ -319,19 +323,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 +1071,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_glob2regpat.vim b/src/nvim/testdir/test_glob2regpat.vim index e6e41f13e7..354f239ef1 100644 --- a/src/nvim/testdir/test_glob2regpat.vim +++ b/src/nvim/testdir/test_glob2regpat.vim @@ -1,7 +1,9 @@ " Test glob2regpat() func Test_glob2regpat_invalid() - call assert_fails('call glob2regpat(1.33)', 'E806:') + if has('float') + call assert_fails('call glob2regpat(1.33)', 'E806:') + endif call assert_fails('call glob2regpat("}")', 'E219:') call assert_fails('call glob2regpat("{")', 'E220:') endfunc diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim index ce22de09ca..24c9c3580e 100644 --- a/src/nvim/testdir/test_highlight.vim +++ b/src/nvim/testdir/test_highlight.vim @@ -595,6 +595,42 @@ func Test_cursorline_with_visualmode() call delete('Xtest_cursorline_with_visualmode') endfunc +func Test_colorcolumn_bri() + CheckScreendump + + " check 'colorcolumn' when 'breakindent' is set + let lines =<< trim END + call setline(1, 'The quick brown fox jumped over the lazy dogs') + END + call writefile(lines, 'Xtest_colorcolumn_bri') + let buf = RunVimInTerminal('-S Xtest_colorcolumn_bri', {'rows': 10,'columns': 40}) + call term_sendkeys(buf, ":set co=40 linebreak bri briopt=shift:2 cc=40,41,43\<CR>") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_colorcolumn_2', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_colorcolumn_bri') +endfunc + +func Test_colorcolumn_sbr() + CheckScreendump + + " check 'colorcolumn' when 'showbreak' is set + let lines =<< trim END + call setline(1, 'The quick brown fox jumped over the lazy dogs') + END + call writefile(lines, 'Xtest_colorcolumn_srb') + let buf = RunVimInTerminal('-S Xtest_colorcolumn_srb', {'rows': 10,'columns': 40}) + call term_sendkeys(buf, ":set co=40 showbreak=+++>\\ cc=40,41,43\<CR>") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_colorcolumn_3', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_colorcolumn_srb') +endfunc + " This test must come before the Test_cursorline test, as it appears this " defines the Normal highlighting group anyway. func Test_1_highlight_Normalgroup_exists() diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim index affb141a26..5152af8f58 100644 --- a/src/nvim/testdir/test_listdict.vim +++ b/src/nvim/testdir/test_listdict.vim @@ -689,7 +689,9 @@ func Test_listdict_extend() let l = [1, 2, 3] call assert_fails("call extend(l, [4, 5, 6], 4)", 'E684:') call assert_fails("call extend(l, [4, 5, 6], -4)", 'E684:') - call assert_fails("call extend(l, [4, 5, 6], 1.2)", 'E805:') + if has('float') + call assert_fails("call extend(l, [4, 5, 6], 1.2)", 'E805:') + endif " Test extend() with dictionaries. @@ -713,7 +715,9 @@ func Test_listdict_extend() let d = {'a': 'A', 'b': 'B'} call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 'error')", 'E737:') call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 'xxx')", 'E475:') - call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 1.2)", 'E806:') + if has('float') + call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 1.2)", 'E806:') + endif call assert_equal({'a': 'A', 'b': 'B'}, d) call assert_fails("call extend([1, 2], 1)", 'E712:') diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim index 52aac05ea1..8c90f21600 100644 --- a/src/nvim/testdir/test_partial.vim +++ b/src/nvim/testdir/test_partial.vim @@ -105,7 +105,7 @@ fun InnerCall(funcref) endfu fun OuterCall() - let opt = { 'func' : function('sin') } + let opt = { 'func' : function('max') } call InnerCall(opt.func) endfu 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/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim index cacdd68d10..712f1e6025 100644 --- a/src/nvim/testdir/test_regexp_latin.vim +++ b/src/nvim/testdir/test_regexp_latin.vim @@ -1,7 +1,10 @@ " Tests for regexp in latin1 encoding + " set encoding=latin1 scriptencoding latin1 +source check.vim + func s:equivalence_test() let str = "AÀÁÂÃÄÅ B C D EÈÉÊË F G H IÌÍÎÏ J K L M NÑ OÒÓÔÕÖØ P Q R S T UÙÚÛÜ V W X YÝ Z aàáâãäå b c d eèéêë f g h iìíîï j k l m nñ oòóôõöø p q r s t uùúûü v w x yýÿ z" let groups = split(str) @@ -42,9 +45,9 @@ func Test_range_with_newline() endfunc func Test_pattern_compile_speed() - if !exists('+spellcapcheck') || !has('reltime') - return - endif + CheckOption spellcapcheck + CheckFunction reltimefloat + let start = reltime() " this used to be very slow, not it should be about a second set spc=\\v(((((Nxxxxxxx&&xxxx){179})+)+)+){179} diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim index 513780938e..d8d5797dcf 100644 --- a/src/nvim/testdir/test_regexp_utf8.vim +++ b/src/nvim/testdir/test_regexp_utf8.vim @@ -542,6 +542,52 @@ func Test_match_start_of_line_combining() bwipe! endfunc +" Check that [[:upper:]] matches for automatic engine +func Test_match_char_class_upper() + new + let _engine=®expengine + + " Test 1: [[:upper:]]\{2,\} + set regexpengine=0 + call setline(1, ['05. ПЕСНЯ О ГЕРОЯХ муз. А. Давиденко, М. Коваля и Б. Шехтера ...', '05. PJESNJA O GJEROJAKH mus. A. Davidjenko, M. Kovalja i B. Shjekhtjera ...']) + call cursor(1,1) + let search_cmd='norm /\<[[:upper:]]\{2,\}\>' .. "\<CR>" + exe search_cmd + call assert_equal(4, searchcount().total, 'TEST 1') + set regexpengine=1 + exe search_cmd + call assert_equal(2, searchcount().total, 'TEST 1') + set regexpengine=2 + exe search_cmd + call assert_equal(4, searchcount().total, 'TEST 1') + + " Test 2: [[:upper:]].\+ + let search_cmd='norm /\<[[:upper:]].\+\>' .. "\<CR>" + set regexpengine=0 + exe search_cmd + call assert_equal(2, searchcount().total, 'TEST 2') + set regexpengine=1 + exe search_cmd + call assert_equal(1, searchcount().total, 'TEST 2') + set regexpengine=2 + exe search_cmd + call assert_equal(2, searchcount().total, 'TEST 2') + + " Test 3: [[:lower:]]\+ + let search_cmd='norm /\<[[:lower:]]\+\>' .. "\<CR>" + set regexpengine=0 + exe search_cmd + call assert_equal(4, searchcount().total, 'TEST 3 lower') + set regexpengine=1 + exe search_cmd + call assert_equal(2, searchcount().total, 'TEST 3 lower') + set regexpengine=2 + exe search_cmd + call assert_equal(4, searchcount().total, 'TEST 3 lower') + " clean up + let ®expengine=_engine + bwipe! +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 75d42b986b..b391663e0f 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -1177,13 +1177,28 @@ func Test_look_behind() bwipe! endfunc +func Test_search_visual_area_linewise() + new + call setline(1, ['aa', 'bb', 'cc']) + exe "normal 2GV\<Esc>" + for engine in [1, 2] + exe 'set regexpengine=' .. engine + exe "normal gg/\\%'<\<CR>>" + call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine) + exe "normal gg/\\%'>\<CR>" + call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine) + endfor + + bwipe! + set regexpengine& +endfunc + func Test_search_sentence() new " this used to cause a crash - call assert_fails("/\\%')", 'E486') - call assert_fails("/", 'E486') /\%'( / + bwipe endfunc " Test that there is no crash when there is a last search pattern but no last diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim index 6d55889641..570c4415c6 100644 --- a/src/nvim/testdir/test_sort.vim +++ b/src/nvim/testdir/test_sort.vim @@ -1,5 +1,7 @@ " Tests for the "sort()" function and for the ":sort" command. +source check.vim + func Compare1(a, b) abort call sort(range(3), 'Compare2') return a:a - a:b @@ -59,6 +61,7 @@ func Test_sort_numbers() endfunc func Test_sort_float() + CheckFeature float call assert_equal([0.28, 3, 13.5], sort([13.5, 0.28, 3], 'f')) endfunc @@ -68,6 +71,8 @@ func Test_sort_nested() endfunc func Test_sort_default() + CheckFeature float + " docs say omitted, empty or zero argument sorts on string representation. call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"])) call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], '')) @@ -1176,30 +1181,6 @@ func Test_sort_cmd() \ ] \ }, \ { - \ 'name' : 'float', - \ 'cmd' : 'sort f', - \ 'input' : [ - \ '1.234', - \ '0.88', - \ ' + 123.456', - \ '1.15e-6', - \ '-1.1e3', - \ '-1.01e3', - \ '', - \ '' - \ ], - \ 'expected' : [ - \ '', - \ '', - \ '-1.1e3', - \ '-1.01e3', - \ '1.15e-6', - \ '0.88', - \ '1.234', - \ ' + 123.456' - \ ] - \ }, - \ { \ 'name' : 'alphabetical, sorted input', \ 'cmd' : 'sort', \ 'input' : [ diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim index 84aca737ac..315ba188cb 100644 --- a/src/nvim/testdir/test_true_false.vim +++ b/src/nvim/testdir/test_true_false.vim @@ -1,5 +1,7 @@ " Test behavior of boolean-like values. +source check.vim + " Test what is explained at ":help TRUE" and ":help FALSE". func Test_if() if v:false @@ -41,7 +43,9 @@ func Test_if() call assert_fails('if [1]', 'E745') call assert_fails('if {1: 1}', 'E728') call assert_fails('if function("string")', 'E703') - call assert_fails('if 1.3")', 'E805') + if has('float') + call assert_fails('if 1.3")', 'E805') + endif endfunc function Try_arg_true_false(expr, false_val, true_val) @@ -113,6 +117,7 @@ func Test_true_false_arg() endfunc function Try_arg_non_zero(expr, false_val, true_val) + CheckFeature float for v in ['v:false', '0', '[1]', '{2:3}', '3.4'] let r = eval(substitute(a:expr, '%v%', v, '')) call assert_equal(a:false_val, r, 'result for ' . v . ' is not ' . a:false_val . ' but ' . r) diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim index e9e181ce3d..7dcd92a54b 100644 --- a/src/nvim/testdir/test_user_func.vim +++ b/src/nvim/testdir/test_user_func.vim @@ -113,9 +113,11 @@ func MakeBadFunc() endfunc func Test_default_arg() - call assert_equal(1.0, Log(10)) - call assert_equal(log(10), Log(10, exp(1))) - call assert_fails("call Log(1,2,3)", 'E118') + if has('float') + call assert_equal(1.0, Log(10)) + call assert_equal(log(10), Log(10, exp(1))) + call assert_fails("call Log(1,2,3)", 'E118') + endif let res = Args(1) call assert_equal(res.mandatory, 1) diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index 43907de1d9..5922660ef9 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -1271,8 +1271,10 @@ func Test_num64() call assert_equal(-9223372036854775807, -1 / 0) call assert_equal(-9223372036854775807 - 1, 0 / 0) - call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) - call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) + if has('float') + call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) + call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) + endif let rng = range(0xFFFFffff, 0x100000001) call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) @@ -1531,22 +1533,22 @@ func Test_compound_assignment_operators() call assert_equal('string', x) let x += 1 call assert_equal(1, x) - let x -= 1.5 - call assert_equal(-0.5, x) if has('float') - " Test for float - let x = 0.5 - let x += 4.5 - call assert_equal(5.0, x) - let x -= 1.5 - call assert_equal(3.5, x) - let x *= 3.0 - call assert_equal(10.5, x) - let x /= 2.5 - call assert_equal(4.2, x) - call assert_fails('let x %= 0.5', 'E734') - call assert_fails('let x .= "f"', 'E734') + " Test for float + let x -= 1.5 + call assert_equal(-0.5, x) + let x = 0.5 + let x += 4.5 + call assert_equal(5.0, x) + let x -= 1.5 + call assert_equal(3.5, x) + let x *= 3.0 + call assert_equal(10.5, x) + let x /= 2.5 + call assert_equal(4.2, x) + call assert_fails('let x %= 0.5', 'E734') + call assert_fails('let x .= "f"', 'E734') endif " Test for environment variable 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/legacy/mksession_spec.lua b/test/functional/legacy/mksession_spec.lua new file mode 100644 index 0000000000..a2af891107 --- /dev/null +++ b/test/functional/legacy/mksession_spec.lua @@ -0,0 +1,42 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local command = helpers.command +local funcs = helpers.funcs +local eq = helpers.eq + +describe('mksession', function() + before_each(clear) + + after_each(function() + os.remove('Xtest_mks.out') + end) + + it('supports "skiprtp" value', function() + command('set sessionoptions&vi') + command('set rtp+=$HOME') + command('set pp+=$HOME') + command('mksession! Xtest_mks.out') + local found_rtp = 0 + local found_pp = 0 + for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do + if line:find('set runtimepath') then + found_rtp = found_rtp + 1 + end + if line:find('set packpath') then + found_pp = found_pp + 1 + end + end + eq(1, found_rtp) + eq(1, found_pp) + + command('set sessionoptions+=skiprtp') + command('mksession! Xtest_mks.out') + local found_rtp_or_pp = 0 + for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do + if line:find('set runtimepath') or line:find('set packpath') then + found_rtp_or_pp = found_rtp_or_pp + 1 + end + end + eq(0, found_rtp_or_pp) + end) +end) 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 = "" } }} |