aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml2
-rw-r--r--.github/ISSUE_TEMPLATE/lsp_bug_report.yml2
-rw-r--r--.github/labeler.yml18
-rw-r--r--.github/workflows/labeler.yml3
-rw-r--r--runtime/doc/api.txt49
-rw-r--r--runtime/doc/eval.txt32
-rw-r--r--runtime/doc/lsp.txt16
-rw-r--r--runtime/doc/options.txt16
-rw-r--r--runtime/doc/quickref.txt1
-rw-r--r--runtime/doc/syntax.txt64
-rw-r--r--runtime/doc/vim_diff.txt8
-rw-r--r--runtime/lua/vim/lsp.lua10
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua47
-rw-r--r--runtime/lua/vim/lsp/handlers.lua4
-rw-r--r--runtime/optwin.vim3
-rw-r--r--runtime/syntax/syncolor.vim89
-rw-r--r--runtime/syntax/synload.vim5
-rw-r--r--src/nvim/api/buffer.c87
-rw-r--r--src/nvim/api/deprecated.c82
-rw-r--r--src/nvim/api/private/helpers.c36
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/decoration.c26
-rw-r--r--src/nvim/decoration.h13
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c44
-rw-r--r--src/nvim/eval/userfunc.c2
-rw-r--r--src/nvim/ex_cmds.c26
-rw-r--r--src/nvim/ex_cmds2.c2
-rw-r--r--src/nvim/ex_docmd.c57
-rw-r--r--src/nvim/ex_docmd.h2
-rw-r--r--src/nvim/ex_getln.c12
-rw-r--r--src/nvim/ex_session.c37
-rw-r--r--src/nvim/extmark.c2
-rw-r--r--src/nvim/fileio.c6
-rw-r--r--src/nvim/globals.h62
-rw-r--r--src/nvim/main.c11
-rw-r--r--src/nvim/mark.c8
-rw-r--r--src/nvim/mbyte.c3
-rw-r--r--src/nvim/memline.c7
-rw-r--r--src/nvim/message.c46
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/option.c13
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/options.lua7
-rw-r--r--src/nvim/quickfix.c102
-rw-r--r--src/nvim/screen.c166
-rw-r--r--src/nvim/search.c8
-rw-r--r--src/nvim/spellfile.c2
-rw-r--r--src/nvim/state.c3
-rw-r--r--src/nvim/syntax.c98
-rw-r--r--src/nvim/tag.c29
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_cd.vim20
-rw-r--r--src/nvim/testdir/test_cursorline.vim108
-rw-r--r--src/nvim/testdir/test_functions.vim22
-rw-r--r--src/nvim/testdir/test_mksession.vim23
-rw-r--r--src/nvim/testdir/test_quickfix.vim122
-rw-r--r--src/nvim/testdir/test_spellfile.vim46
-rw-r--r--src/nvim/testdir/test_swap.vim4
-rw-r--r--src/nvim/testdir/test_tagjump.vim13
-rw-r--r--src/nvim/window.c82
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua9
-rw-r--r--test/functional/ex_cmds/quickfix_commands_spec.lua10
-rw-r--r--test/functional/plugin/lsp_spec.lua4
-rw-r--r--test/functional/ui/bufhl_spec.lua22
-rw-r--r--test/functional/ui/cmdline_spec.lua4
-rw-r--r--test/functional/ui/decorations_spec.lua94
-rw-r--r--test/functional/ui/highlight_spec.lua2
-rw-r--r--test/functional/ui/sign_spec.lua28
-rw-r--r--test/unit/viml/expressions/parser_spec.lua58
71 files changed, 1266 insertions, 782 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index e5530a1511..474fce0167 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -54,7 +54,7 @@ body:
- type: textarea
attributes:
label: "Expected behavior"
+ description: "A description of the behavior you expected. May optionally include logs, images, or videos."
- type: textarea
attributes:
label: "Actual behavior"
- description: "A description of the behavior you expected. May optionally include logs, images, or videos."
diff --git a/.github/ISSUE_TEMPLATE/lsp_bug_report.yml b/.github/ISSUE_TEMPLATE/lsp_bug_report.yml
index ff25bb0a23..ba1905329b 100644
--- a/.github/ISSUE_TEMPLATE/lsp_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/lsp_bug_report.yml
@@ -47,10 +47,10 @@ body:
- type: textarea
attributes:
label: "Expected behavior"
+ description: "A description of the behavior you expected. May optionally include logs, images, or videos."
- type: textarea
attributes:
label: "Actual behavior"
- description: "A description of the behavior you expected. May optionally include logs, images, or videos."
- type: markdown
attributes:
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 282c6b1e7c..2de3904314 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -17,33 +17,33 @@
"dependencies":
- third-party/**/*
-"topic: spell":
+"spell":
- src/nvim/spell*
-"topic: :terminal":
+"terminal":
- src/nvim/terminal.*
-"topic: column":
+"column":
- src/nvim/mark.h
- src/nvim/mark.c
- src/nvim/sign*
-"topic: folds":
+"folds":
- src/nvim/fold*
-"topic: mouse":
+"mouse":
- src/nvim/mouse*
-"topic: documentation":
+"documentation":
- runtime/doc/*
-"topic: clipboard":
+"clipboard":
- runtime/autoload/provider/clipboard.vim
-"topic: diff":
+"diff":
- src/nvim/diff.*
-"topic: build":
+"build":
- CMakeLists.txt
- "**/CMakeLists.txt"
- "**/*.cmake"
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 909e197b57..67ad4c0552 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -1,6 +1,7 @@
name: "Pull Request Labeler"
on:
-- pull_request_target
+ pull_request_target:
+ types: opened
jobs:
triage:
runs-on: ubuntu-latest
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 4dcf5b7bbc..c525ea7a3a 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -2290,7 +2290,16 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
• hl_group : name of the highlight group used to
highlight this mark.
• virt_text : virtual text to link to this mark.
- • virt_text_pos : positioning of virtual text.
+ A list of [text, highlight] tuples, each
+ representing a text chunk with specified
+ highlight. `highlight` element can either be a
+ a single highlight group, or an array of
+ multiple highlight groups that will be stacked
+ (highest priority last). A highlight group can
+ be supplied either as a string or as an
+ integer, the latter which can be obtained
+ using |nvim_get_hl_id_by_name|.
+ • virt_text_pos : position of virtual text.
Possible values:
• "eol": right after eol character (default)
• "overlay": display over the specified
@@ -2427,44 +2436,6 @@ nvim_buf_set_var({buffer}, {name}, {value}) *nvim_buf_set_var()*
{name} Variable name
{value} Variable value
- *nvim_buf_set_virtual_text()*
-nvim_buf_set_virtual_text({buffer}, {src_id}, {line}, {chunks}, {opts})
- Set the virtual text (annotation) for a buffer line.
-
- By default (and currently the only option) the text will be
- placed after the buffer text. Virtual text will never cause
- reflow, rather virtual text will be truncated at the end of
- the screen line. The virtual text will begin one cell
- (|lcs-eol| or space) after the ordinary text.
-
- Namespaces are used to support batch deletion/updating of
- virtual text. To create a namespace, use
- |nvim_create_namespace()|. Virtual text is cleared using
- |nvim_buf_clear_namespace()|. The same `ns_id` can be used for
- both virtual text and highlights added by
- |nvim_buf_add_highlight()|, both can then be cleared with a
- single call to |nvim_buf_clear_namespace()|. If the virtual
- text never will be cleared by an API call, pass `ns_id = -1` .
-
- As a shorthand, `ns_id = 0` can be used to create a new
- namespace for the virtual text, the allocated id is then
- returned.
-
- Parameters: ~
- {buffer} Buffer handle, or 0 for current buffer
- {ns_id} Namespace to use or 0 to create a namespace, or
- -1 for a ungrouped annotation
- {line} Line to annotate with virtual text
- (zero-indexed)
- {chunks} A list of [text, hl_group] arrays, each
- representing a text chunk with specified
- highlight. `hl_group` element can be omitted for
- no highlight.
- {opts} Optional parameters. Currently not used.
-
- Return: ~
- The ns_id that was used
-
==============================================================================
Window Functions *api-window*
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index e32691dfb4..a76298c86c 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2203,9 +2203,11 @@ getbufline({expr}, {lnum} [, {end}])
getbufvar({expr}, {varname} [, {def}])
any variable {varname} in buffer {expr}
getchangelist({expr}) List list of change list items
-getchar([expr]) Number get one character from the user
+getchar([expr]) Number or String
+ get one character from the user
getcharmod() Number modifiers for the last typed character
getcharsearch() Dict last character search
+getcharstr([expr]) String get one character from the user
getcmdline() String return the current command-line
getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type
@@ -4308,6 +4310,7 @@ getchar([expr]) *getchar()*
Return zero otherwise.
If [expr] is 1, only check if a character is available, it is
not consumed. Return zero if no character available.
+ If you prefer always getting a string use |getcharstr()|.
Without [expr] and when [expr] is 0 a whole character or
special key is returned. If it is a single character, the
@@ -4399,6 +4402,20 @@ getcharsearch() *getcharsearch()*
:nnoremap <expr> , getcharsearch().forward ? ',' : ';'
< Also see |setcharsearch()|.
+
+getcharstr([expr]) *getcharstr()*
+ Get a single character from the user or input stream as a
+ string.
+ If [expr] is omitted, wait until a character is available.
+ If [expr] is 0 or false, only get a character when one is
+ available. Return an empty string otherwise.
+ If [expr] is 1 or true, only check if a character is
+ available, it is not consumed. Return an empty string
+ if no character is available.
+ Otherwise this works like |getchar()|, except that a number
+ result is converted to a string.
+
+
getcmdline() *getcmdline()*
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or
@@ -4742,7 +4759,10 @@ getqflist([{what}]) *getqflist()*
bufname() to get the name
module module name
lnum line number in the buffer (first line is 1)
+ end_lnum
+ end of line number if the item is multiline
col column number (first column is 1)
+ end_col end of column number if the item has range
vcol |TRUE|: "col" is visual column
|FALSE|: "col" is byte index
nr error number
@@ -6350,6 +6370,10 @@ mode([expr]) Return a string that indicates the current mode.
s Select by character
S Select by line
CTRL-S Select blockwise
+ vs Visual by character using |v_CTRL-O| from
+ Select mode
+ Vs Visual by line using |v_CTRL-O| from Select mode
+ CTRL-Vs Visual blockwise using |v_CTRL-O| from Select mode
i Insert
ic Insert mode completion |compl-generic|
ix Insert mode |i_CTRL-X| completion
@@ -9299,10 +9323,12 @@ win_gettype([{nr}]) *win_gettype()*
Return the type of the window:
"autocmd" autocommand window. Temporary window
used to execute autocommands.
- "popup" popup window |popup|
- "preview" preview window |preview-window|
"command" command-line window |cmdwin|
(empty) normal window
+ "loclist" |location-list-window|
+ "popup" popup window |popup|
+ "preview" preview window |preview-window|
+ "quickfix" |quickfix-window|
"unknown" window {nr} not found
When {nr} is omitted return the type of the current window.
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index c750a65c10..7daab4d6f1 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -1487,6 +1487,22 @@ on_publish_diagnostics({_}, {_}, {params}, {client_id}, {_}, {config})
• Sort diagnostics (and thus signs and virtual
text)
+redraw({bufnr}, {client_id}) *vim.lsp.diagnostic.redraw()*
+ Redraw diagnostics for the given buffer and client
+
+ This calls the "textDocument/publishDiagnostics" handler
+ manually using the cached diagnostics already received from
+ the server. This can be useful for redrawing diagnostics after
+ making changes in diagnostics configuration.
+ |lsp-handler-configuration|
+
+ Parameters: ~
+ {bufnr} (optional, number): Buffer handle, defaults
+ to current
+ {client_id} (optional, number): Redraw diagnostics for
+ the given client. The default is to redraw
+ diagnostics for all attached clients.
+
reset({client_id}, {buffer_client_map}) *vim.lsp.diagnostic.reset()*
Clear diagnotics and diagnostic cache
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index ab2230641d..5292847240 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1802,13 +1802,23 @@ A jump table for the options with a short description can be found at |Q_op|.
*'cursorline'* *'cul'* *'nocursorline'* *'nocul'*
'cursorline' 'cul' boolean (default off)
local to window
- Highlight the screen line of the cursor with CursorLine
- |hl-CursorLine|. Useful to easily spot the cursor. Will make screen
- redrawing slower.
+ Highlight the text line of the cursor with CursorLine |hl-CursorLine|.
+ Useful to easily spot the cursor. Will make screen redrawing slower.
When Visual mode is active the highlighting isn't used to make it
easier to see the selected text.
+ *'cursorlineopt'* *'culopt'*
+'cursorlineopt' 'culopt' string (default: "both")
+ local to window
+ Settings for how 'cursorline' is displayed. Valid values:
+ "line" Highlight the text line of the cursor with
+ CursorLine |hl-CursorLine|.
+ "number" Highlight the line number of the cursor with
+ CursorLineNr |hl-CursorLineNr|.
+ "both" Highlight as both "line" and "number" are set.
+
+
*'debug'*
'debug' string (default "")
global
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index c19b05f6c7..77e69a3eea 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -659,6 +659,7 @@ Short explanation of each option: *option-list*
'cursorbind' 'crb' move cursor in window as it moves in other windows
'cursorcolumn' 'cuc' highlight the screen column of the cursor
'cursorline' 'cul' highlight the screen line of the cursor
+'cursorlineopt' 'culopt' settings for 'cursorline'
'debug' set to "msg" to see all error messages
'define' 'def' pattern to be used to find a macro definition
'delcombine' 'deco' delete combining characters on their own
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 6c51f37ae5..0cd3aed7a2 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -25,11 +25,15 @@ In the User Manual:
==============================================================================
1. Quick start *:syn-qstart*
- *:syn-enable* *:syntax-enable*
+ *:syn-enable* *:syntax-enable* *:syn-on* *:syntax-on*
This command switches on syntax highlighting: >
:syntax enable
+Alternatively: >
+
+ :syntax on
+
What this command actually does is to execute the command >
:source $VIMRUNTIME/syntax/syntax.vim
@@ -42,19 +46,11 @@ are in the "/usr/vim/vim82/syntax" directory, set $VIMRUNTIME to
This command also sources the |menu.vim| script when the GUI is running or
will start soon. See |'go-M'| about avoiding that.
- *:syn-on* *:syntax-on*
-The `:syntax enable` command will keep most of your current color settings.
-This allows using `:highlight` commands to set your preferred colors before or
-after using this command. If you want Vim to overrule your settings with the
-defaults, use: >
- :syntax on
-<
*:hi-normal* *:highlight-normal*
If you are running in the GUI, you can get white text on a black background
with: >
:highlight Normal guibg=Black guifg=White
For a color terminal see |:hi-normal-cterm|.
-For setting up your own colors syntax highlighting see |syncolor|.
NOTE: The syntax files on MS-Windows have lines that end in <CR><NL>.
The files for Unix end in <NL>. This means you should use the right type of
@@ -277,12 +273,6 @@ located. This is used here as the variable |$VIMRUNTIME|.
|
+- Source first syntax/synload.vim in 'runtimepath'
| |
- | +- Setup the colors for syntax highlighting. If a color scheme is
- | | defined it is loaded again with ":colors {name}". Otherwise
- | | ":runtime! syntax/syncolor.vim" is used. ":syntax on" overrules
- | | existing colors, ":syntax enable" only sets groups that weren't
- | | set yet.
- | |
| +- Set up syntax autocmds to load the appropriate syntax file when
| | the 'syntax' option is set. *synload-1*
| |
@@ -5075,7 +5065,8 @@ Substitute |:substitute| replacement text highlighting
LineNr Line number for ":number" and ":#" commands, and when 'number'
or 'relativenumber' option is set.
*hl-CursorLineNr*
-CursorLineNr Like LineNr when 'cursorline' or 'relativenumber' is set for
+CursorLineNr Like LineNr when 'cursorline' is set and 'cursorlineopt' is
+ set to "number" or "both", or 'relativenumber' is set, for
the cursor line.
*hl-MatchParen*
MatchParen The character under the cursor or just before it, if it
@@ -5271,51 +5262,10 @@ back to their Vim default.
Note that if you are using a color scheme, the colors defined by the color
scheme for syntax highlighting will be lost.
-What this actually does is: >
-
- let g:syntax_cmd = "reset"
- runtime! syntax/syncolor.vim
-
-Note that this uses the 'runtimepath' option.
-
- *syncolor*
-If you want to use different colors for syntax highlighting, you can add a Vim
-script file to set these colors. Put this file in a directory in
-'runtimepath' which comes after $VIMRUNTIME, so that your settings overrule
-the default colors. This way these colors will be used after the ":syntax
-reset" command.
-
-For Unix you can use the file ~/.config/nvim/after/syntax/syncolor.vim.
-Example: >
-
- if &background == "light"
- highlight comment ctermfg=darkgreen guifg=darkgreen
- else
- highlight comment ctermfg=green guifg=green
- endif
-
- *E679*
-Do make sure this syncolor.vim script does not use a "syntax on", set the
-'background' option or uses a "colorscheme" command, because it results in an
-endless loop.
-
Note that when a color scheme is used, there might be some confusion whether
your defined colors are to be used or the colors from the scheme. This
depends on the color scheme file. See |:colorscheme|.
- *syntax_cmd*
-The "syntax_cmd" variable is set to one of these values when the
-syntax/syncolor.vim files are loaded:
- "on" ":syntax on" command. Highlight colors are overruled but
- links are kept
- "enable" ":syntax enable" command. Only define colors for groups that
- don't have highlighting yet. Use ":syntax default".
- "reset" ":syntax reset" command or loading a color scheme. Define all
- the colors.
- "skip" Don't define colors. Used to skip the default settings when a
- syncolor.vim file earlier in 'runtimepath' has already set
- them.
-
==============================================================================
16. Highlighting tags *tag-highlight*
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index a259afded0..2c53620049 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -358,6 +358,14 @@ Startup:
- works by default: "-" file is optional
- works in more cases: |-Es|, file args
+Syntax highlighting:
+ syncolor.vim has been removed. Nvim now sets up default highlighting groups
+ automatically for both light and dark backgrounds, regardless of whether or
+ not syntax highlighting is enabled. This means that |:syntax-on| and
+ |:syntax-enable| are now identical. Users who previously used an
+ after/syntax/syncolor.vim file should transition that file into a
+ colorscheme. |:colorscheme|
+
TUI:
*:set-termcap*
Start Nvim with 'verbose' level 3 to show terminal capabilities: >
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index f5aefc8260..87ecc3eeea 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -453,15 +453,7 @@ local function text_document_did_open_handler(bufnr, client)
-- Next chance we get, we should re-do the diagnostics
vim.schedule(function()
- vim.lsp.handlers["textDocument/publishDiagnostics"](
- nil,
- "textDocument/publishDiagnostics",
- {
- diagnostics = vim.lsp.diagnostic.get(bufnr, client.id),
- uri = vim.uri_from_bufnr(bufnr),
- },
- client.id
- )
+ vim.lsp.diagnostic.redraw(bufnr, client.id)
end)
end
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 246665602d..120320becc 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -1168,6 +1168,40 @@ function M.display(diagnostics, bufnr, client_id, config)
save_extmarks(bufnr, client_id)
end
+--- Redraw diagnostics for the given buffer and client
+---
+--- This calls the "textDocument/publishDiagnostics" handler manually using
+--- the cached diagnostics already received from the server. This can be useful
+--- for redrawing diagnostics after making changes in diagnostics
+--- configuration. |lsp-handler-configuration|
+---
+--- @param bufnr (optional, number): Buffer handle, defaults to current
+--- @param client_id (optional, number): Redraw diagnostics for the given
+--- client. The default is to redraw diagnostics for all attached
+--- clients.
+function M.redraw(bufnr, client_id)
+ bufnr = get_bufnr(bufnr)
+ if not client_id then
+ return vim.lsp.for_each_buffer_client(bufnr, function(client)
+ M.redraw(bufnr, client.id)
+ end)
+ end
+
+ -- We need to invoke the publishDiagnostics handler directly instead of just
+ -- calling M.display so that we can preserve any custom configuration options
+ -- the user may have set with vim.lsp.with.
+ vim.lsp.handlers["textDocument/publishDiagnostics"](
+ nil,
+ "textDocument/publishDiagnostics",
+ {
+ uri = vim.uri_from_bufnr(bufnr),
+ diagnostics = M.get(bufnr, client_id),
+ },
+ client_id,
+ bufnr
+ )
+end
+
-- }}}
-- Diagnostic User Functions {{{
@@ -1361,18 +1395,7 @@ function M.enable(bufnr, client_id)
diagnostic_disabled[bufnr][client_id] = nil
- -- We need to invoke the publishDiagnostics handler directly instead of just
- -- calling M.display so that we can preserve any custom configuration options
- -- the user may have set with vim.lsp.with.
- vim.lsp.handlers["textDocument/publishDiagnostics"](
- nil,
- "textDocument/publishDiagnostics",
- {
- diagnostics = M.get(bufnr, client_id),
- uri = vim.uri_from_bufnr(bufnr),
- },
- client_id
- )
+ M.redraw(bufnr, client_id)
end
-- }}}
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index a77c88e2dc..b7f1ea0ab6 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -457,12 +457,14 @@ for k, fn in pairs(M) do
})
if err then
+ local client = vim.lsp.get_client_by_id(client_id)
+ local client_name = client and client.name or string.format("client_id=%d", client_id)
-- LSP spec:
-- interface ResponseError:
-- code: integer;
-- message: string;
-- data?: string | number | boolean | array | object | null;
- return err_message(tostring(err.code) .. ': ' .. err.message)
+ return err_message(client_name .. ': ' .. tostring(err.code) .. ': ' .. err.message)
end
return fn(err, method, params, client_id, bufnr, config)
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 633cb9e509..d4c10f7afa 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -440,6 +440,9 @@ if has("syntax")
call append("$", "cursorline\thighlight the screen line of the cursor")
call append("$", "\t(local to window)")
call <SID>BinOptionL("cul")
+ call append("$", "cursorlineopt\tspecifies which area 'cursorline' highlights")
+ call append("$", "\t(local to window)")
+ call <SID>OptionL("culopt")
call append("$", "colorcolumn\tcolumns to highlight")
call append("$", "\t(local to window)")
call <SID>OptionL("cc")
diff --git a/runtime/syntax/syncolor.vim b/runtime/syntax/syncolor.vim
deleted file mode 100644
index 27cc3360c4..0000000000
--- a/runtime/syntax/syncolor.vim
+++ /dev/null
@@ -1,89 +0,0 @@
-" Vim syntax support file
-" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2020 Feb 13
-
-" This file sets up the default methods for highlighting.
-" It is loaded from "synload.vim" and from Vim for ":syntax reset".
-" Also used from init_highlight().
-
-if !exists("syntax_cmd") || syntax_cmd == "on"
- " ":syntax on" works like in Vim 5.7: set colors but keep links
- command -nargs=* SynColor hi <args>
- command -nargs=* SynLink hi link <args>
-else
- if syntax_cmd == "enable"
- " ":syntax enable" keeps any existing colors
- command -nargs=* SynColor hi def <args>
- command -nargs=* SynLink hi def link <args>
- elseif syntax_cmd == "reset"
- " ":syntax reset" resets all colors to the default
- command -nargs=* SynColor hi <args>
- command -nargs=* SynLink hi! link <args>
- else
- " User defined syncolor file has already set the colors.
- finish
- endif
-endif
-
-let did_syncolor = 1
-
-" Many terminals can only use six different colors (plus black and white).
-" Therefore the number of colors used is kept low. It doesn't look nice with
-" too many colors anyway.
-" Careful with "cterm=bold", it changes the color to bright for some terminals.
-" There are two sets of defaults: for a dark and a light background.
-if &background == "dark"
- SynColor Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE
- SynColor Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE
- SynColor Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE
- SynColor Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff guibg=NONE
- SynColor Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=bold guifg=#ffff60 guibg=NONE
- SynColor PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=#ff80ff guibg=NONE
- SynColor Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=bold guifg=#60ff60 guibg=NONE
- SynColor Underlined term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=#80a0ff
- SynColor Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=bg guibg=NONE
-else
- SynColor Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE
- SynColor Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE
- " #6a5acd is SlateBlue
- SynColor Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a5acd guibg=NONE
- SynColor Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE
- SynColor Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE
- " #6a0dad is Purple
- SynColor PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a0dad guibg=NONE
- SynColor Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=bold guifg=SeaGreen guibg=NONE
- SynColor Underlined term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=SlateBlue
- SynColor Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=bg guibg=NONE
-endif
-SynColor Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red
-SynColor Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow
-
-" Common groups that link to default highlighting.
-" You can specify other highlighting easily.
-SynLink String Constant
-SynLink Character Constant
-SynLink Number Constant
-SynLink Boolean Constant
-SynLink Float Number
-SynLink Function Identifier
-SynLink Conditional Statement
-SynLink Repeat Statement
-SynLink Label Statement
-SynLink Operator Statement
-SynLink Keyword Statement
-SynLink Exception Statement
-SynLink Include PreProc
-SynLink Define PreProc
-SynLink Macro PreProc
-SynLink PreCondit PreProc
-SynLink StorageClass Type
-SynLink Structure Type
-SynLink Typedef Type
-SynLink Tag Special
-SynLink SpecialChar Special
-SynLink Delimiter Special
-SynLink SpecialComment Special
-SynLink Debug Special
-
-delcommand SynColor
-delcommand SynLink
diff --git a/runtime/syntax/synload.vim b/runtime/syntax/synload.vim
index aee9ba8b8e..bfcd3b06da 100644
--- a/runtime/syntax/synload.vim
+++ b/runtime/syntax/synload.vim
@@ -14,11 +14,6 @@ endif
" let others know that syntax has been switched on
let syntax_on = 1
-" Set the default highlighting colors
-if !exists("colors_name") && !exists("did_syncolor")
- runtime! syntax/syncolor.vim
-endif
-
" Line continuation is used here, remove 'C' from 'cpoptions'
let s:cpo_save = &cpo
set cpo&vim
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 78e36e5ef0..77cff0cb4f 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1433,8 +1433,14 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// - hl_group : name of the highlight group used to highlight
/// this mark.
/// - virt_text : virtual text to link to this mark.
-/// - virt_text_pos : positioning of virtual text. Possible
-/// values:
+/// A list of [text, highlight] tuples, each representing a
+/// text chunk with specified highlight. `highlight` element
+/// can either be a a single highlight group, or an array of
+/// multiple highlight groups that will be stacked
+/// (highest priority last). A highlight group can be supplied
+/// either as a string or as an integer, the latter which
+/// can be obtained using |nvim_get_hl_id_by_name|.
+/// - virt_text_pos : position of virtual text. Possible values:
/// - "eol": right after eol character (default)
/// - "overlay": display over the specified column, without
/// shifting the underlying text.
@@ -1560,7 +1566,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
"virt_text is not an Array");
goto error;
}
- decor.virt_text = parse_virt_text(v->data.array, err);
+ decor.virt_text = parse_virt_text(v->data.array, err,
+ &decor.virt_text_width);
if (ERROR_SET(err)) {
goto error;
}
@@ -1892,80 +1899,6 @@ void nvim_buf_clear_namespace(Buffer buffer,
(int)line_end-1, MAXCOL);
}
-/// Set the virtual text (annotation) for a buffer line.
-///
-/// By default (and currently the only option) the text will be placed after
-/// the buffer text. Virtual text will never cause reflow, rather virtual
-/// text will be truncated at the end of the screen line. The virtual text will
-/// begin one cell (|lcs-eol| or space) after the ordinary text.
-///
-/// Namespaces are used to support batch deletion/updating of virtual text.
-/// To create a namespace, use |nvim_create_namespace()|. Virtual text is
-/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for
-/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both
-/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If
-/// the virtual text never will be cleared by an API call, pass `ns_id = -1`.
-///
-/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
-/// virtual text, the allocated id is then returned.
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param ns_id Namespace to use or 0 to create a namespace,
-/// or -1 for a ungrouped annotation
-/// @param line Line to annotate with virtual text (zero-indexed)
-/// @param chunks A list of [text, hl_group] arrays, each representing a
-/// text chunk with specified highlight. `hl_group` element
-/// can be omitted for no highlight.
-/// @param opts Optional parameters. Currently not used.
-/// @param[out] err Error details, if any
-/// @return The ns_id that was used
-Integer nvim_buf_set_virtual_text(Buffer buffer,
- Integer src_id,
- Integer line,
- Array chunks,
- Dictionary opts,
- Error *err)
- FUNC_API_SINCE(5)
-{
- buf_T *buf = find_buffer_by_handle(buffer, err);
- if (!buf) {
- return 0;
- }
-
- if (line < 0 || line >= MAXLNUM) {
- api_set_error(err, kErrorTypeValidation, "Line number outside range");
- return 0;
- }
-
- if (opts.size > 0) {
- api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
- return 0;
- }
-
- uint64_t ns_id = src2ns(&src_id);
-
- VirtText virt_text = parse_virt_text(chunks, err);
- if (ERROR_SET(err)) {
- return 0;
- }
-
-
- VirtText *existing = decor_find_virttext(buf, (int)line, ns_id);
-
- if (existing) {
- clear_virttext(existing);
- *existing = virt_text;
- return src_id;
- }
-
- Decoration *decor = xcalloc(1, sizeof(*decor));
- decor->virt_text = virt_text;
-
- extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true,
- false, kExtmarkNoUndo);
- return src_id;
-}
-
/// call a function with buffer as temporary current buffer
///
/// This temporarily switches current buffer to "buffer".
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index 3989386bb9..554966e266 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -12,6 +12,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/lua/executor.h"
+#include "nvim/extmark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/deprecated.c.generated.h"
@@ -80,6 +81,87 @@ void nvim_buf_clear_highlight(Buffer buffer,
}
+/// Set the virtual text (annotation) for a buffer line.
+///
+/// @deprecated use nvim_buf_set_extmark to use full virtual text
+/// functionality.
+///
+/// The text will be placed after the buffer text. Virtual text will never
+/// cause reflow, rather virtual text will be truncated at the end of the screen
+/// line. The virtual text will begin one cell (|lcs-eol| or space) after the
+/// ordinary text.
+///
+/// Namespaces are used to support batch deletion/updating of virtual text.
+/// To create a namespace, use |nvim_create_namespace()|. Virtual text is
+/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for
+/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both
+/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If
+/// the virtual text never will be cleared by an API call, pass `ns_id = -1`.
+///
+/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
+/// virtual text, the allocated id is then returned.
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param ns_id Namespace to use or 0 to create a namespace,
+/// or -1 for a ungrouped annotation
+/// @param line Line to annotate with virtual text (zero-indexed)
+/// @param chunks A list of [text, hl_group] arrays, each representing a
+/// text chunk with specified highlight. `hl_group` element
+/// can be omitted for no highlight.
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Error details, if any
+/// @return The ns_id that was used
+Integer nvim_buf_set_virtual_text(Buffer buffer,
+ Integer src_id,
+ Integer line,
+ Array chunks,
+ Dictionary opts,
+ Error *err)
+ FUNC_API_SINCE(5)
+ FUNC_API_DEPRECATED_SINCE(8)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ if (line < 0 || line >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
+ return 0;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return 0;
+ }
+
+ uint64_t ns_id = src2ns(&src_id);
+ int width;
+
+ VirtText virt_text = parse_virt_text(chunks, err, &width);
+ if (ERROR_SET(err)) {
+ return 0;
+ }
+
+
+ Decoration *existing = decor_find_virttext(buf, (int)line, ns_id);
+
+ if (existing) {
+ clear_virttext(&existing->virt_text);
+ existing->virt_text = virt_text;
+ existing->virt_text_width = width;
+ return src_id;
+ }
+
+ Decoration *decor = xcalloc(1, sizeof(*decor));
+ decor->virt_text = virt_text;
+ decor->virt_text_width = width;
+
+ extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true,
+ false, kExtmarkNoUndo);
+ return src_id;
+}
+
/// Inserts a sequence of lines to a buffer at a certain index
///
/// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines)
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 9f2e94f31e..3ec6151090 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1592,9 +1592,10 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
}
}
-VirtText parse_virt_text(Array chunks, Error *err)
+VirtText parse_virt_text(Array chunks, Error *err, int *width)
{
VirtText virt_text = KV_INITIAL_VALUE;
+ int w = 0;
for (size_t i = 0; i < chunks.size; i++) {
if (chunks.items[i].type != kObjectTypeArray) {
api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
@@ -1602,26 +1603,44 @@ VirtText parse_virt_text(Array chunks, Error *err)
}
Array chunk = chunks.items[i].data.array;
if (chunk.size == 0 || chunk.size > 2
- || chunk.items[0].type != kObjectTypeString
- || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
+ || chunk.items[0].type != kObjectTypeString) {
api_set_error(err, kErrorTypeValidation,
"Chunk is not an array with one or two strings");
goto free_exit;
}
String str = chunk.items[0].data.string;
- char *text = transstr(str.size > 0 ? str.data : ""); // allocates
int hl_id = 0;
if (chunk.size == 2) {
- String hl = chunk.items[1].data.string;
- if (hl.size > 0) {
- hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ Object hl = chunk.items[1];
+ if (hl.type == kObjectTypeArray) {
+ Array arr = hl.data.array;
+ for (size_t j = 0; j < arr.size; j++) {
+ hl_id = object_to_hl_id(arr.items[j], "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
+ if (j < arr.size-1) {
+ kv_push(virt_text, ((VirtTextChunk){ .text = NULL,
+ .hl_id = hl_id }));
+ }
+ }
+ } else {
+ hl_id = object_to_hl_id(hl, "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
}
}
+
+ char *text = transstr(str.size > 0 ? str.data : ""); // allocates
+ w += (int)mb_string2cells((char_u *)text);
+
kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
}
+ *width = w;
return virt_text;
free_exit:
@@ -1656,7 +1675,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
String str = obj.data.string;
return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0;
} else if (obj.type == kObjectTypeInteger) {
- return (int)obj.data.integer;
+ return MAX((int)obj.data.integer, 0);
} else {
api_set_error(err, kErrorTypeValidation,
"%s is not a valid highlight", what);
@@ -1687,6 +1706,7 @@ HlMessage parse_hl_msg(Array chunks, Error *err)
if (chunk.size == 2) {
String hl = chunk.items[1].data.string;
if (hl.size > 0) {
+ // TODO(bfredl): use object_to_hl_id and allow integer
int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 2fe85e0543..1099573f83 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -226,6 +226,8 @@ typedef struct {
# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
int wo_cul;
# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
+ char_u *wo_culopt;
+# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt'
char_u *wo_cc;
# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
char_u *wo_stl;
diff --git a/src/nvim/change.c b/src/nvim/change.c
index b30490deca..04552f6703 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -98,7 +98,7 @@ void changed(void)
if (curbuf->b_may_swap
&& !bt_dontwrite(curbuf)
) {
- int save_need_wait_return = need_wait_return;
+ bool save_need_wait_return = need_wait_return;
need_wait_return = false;
ml_open_file(curbuf);
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 9d969ada89..74cb9a26b7 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -119,7 +119,7 @@ void clear_virttext(VirtText *text)
*text = (VirtText)KV_INITIAL_VALUE;
}
-VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
+Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
{
MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, row, 0, itr);
@@ -132,7 +132,7 @@ VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
mark.id, false);
if (item && (ns_id == 0 || ns_id == item->ns_id)
&& item->decor && kv_size(item->decor->virt_text)) {
- return &item->decor->virt_text;
+ return item->decor;
}
marktree_itr_next(buf->b_marktree, itr);
}
@@ -218,6 +218,7 @@ bool decor_redraw_line(buf_T *buf, int row, DecorState *state)
}
state->row = row;
state->col_until = -1;
+ state->eol_col = -1;
return true; // TODO(bfredl): be more precise
}
@@ -230,10 +231,6 @@ static void decor_add(DecorState *state, int start_row, int start_col,
*decor, attr_id,
kv_size(decor->virt_text) && owned, -1 };
- if (decor->virt_text_pos == kVTEndOfLine) {
- range.win_col = -2; // handled separately
- }
-
kv_pushp(state->active);
size_t index;
for (index = kv_size(state->active)-1; index > 0; index--) {
@@ -345,29 +342,22 @@ void decor_redraw_end(DecorState *state)
state->buf = NULL;
}
-VirtText decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr,
- bool *aligned)
+bool decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, int eol_col)
{
decor_redraw_col(buf, MAXCOL, MAXCOL, false, state);
- VirtText text = VIRTTEXT_EMPTY;
+ state->eol_col = eol_col;
+ bool has_virttext = false;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange item = kv_A(state->active, i);
if (item.start_row == state->row && kv_size(item.decor.virt_text)) {
- if (!kv_size(text) && item.decor.virt_text_pos == kVTEndOfLine) {
- text = item.decor.virt_text;
- } else if (item.decor.virt_text_pos == kVTRightAlign
- || item.decor.virt_text_pos == kVTWinCol) {
- *aligned = true;
- }
+ has_virttext = true;
}
-
if (item.decor.hl_eol && item.start_row <= state->row) {
*eol_attr = hl_combine_attr(*eol_attr, item.attr_id);
}
}
-
- return text;
+ return has_virttext;
}
void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 4cebc0b731..28dabeeada 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -34,19 +34,20 @@ typedef enum {
struct Decoration
{
- int hl_id; // highlight group
VirtText virt_text;
+ int hl_id; // highlight group
VirtTextPos virt_text_pos;
- bool virt_text_hide;
HlMode hl_mode;
+ bool virt_text_hide;
bool hl_eol;
+ bool shared; // shared decoration, don't free
// TODO(bfredl): style, signs, etc
DecorPriority priority;
- bool shared; // shared decoration, don't free
int col; // fixed col value, like win_col
+ int virt_text_width; // width of virt_text
};
-#define DECORATION_INIT { 0, KV_INITIAL_VALUE, kVTEndOfLine, false, \
- kHlModeUnknown, false, DECOR_PRIORITY_BASE, false, 0 }
+#define DECORATION_INIT { KV_INITIAL_VALUE, 0, kVTEndOfLine, kHlModeUnknown, \
+ false, false, false, DECOR_PRIORITY_BASE, 0, 0 }
typedef struct {
int start_row;
@@ -67,6 +68,8 @@ typedef struct {
int row;
int col_until;
int current;
+
+ int eol_col;
VirtText *virt_text;
} DecorState;
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 33c6fae5cf..eb20cd1bc8 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -136,6 +136,7 @@ return {
getchar={args={0, 1}},
getcharmod={},
getcharsearch={},
+ getcharstr={args={0, 1}},
getcmdline={},
getcmdpos={},
getcmdtype={},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 3d7a440856..21c858373c 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -3028,10 +3028,9 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getchar()" function
- */
-static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+// "getchar()" and "getcharstr()" functions
+static void getchar_common(typval_T *argvars, typval_T *rettv)
+ FUNC_ATTR_NONNULL_ALL
{
varnumber_T n;
bool error = false;
@@ -3098,6 +3097,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
i += utf_char2bytes(n, temp + i);
}
+ assert(i < 10);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(temp);
@@ -3106,15 +3106,14 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int row = mouse_row;
int col = mouse_col;
int grid = mouse_grid;
- win_T *win;
linenr_T lnum;
win_T *wp;
int winnr = 1;
if (row >= 0 && col >= 0) {
- /* Find the window at the mouse coordinates and compute the
- * text position. */
- win = mouse_find_win(&grid, &row, &col);
+ // Find the window at the mouse coordinates and compute the
+ // text position.
+ win_T *const win = mouse_find_win(&grid, &row, &col);
if (win == NULL) {
return;
}
@@ -3130,6 +3129,32 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "getchar()" function
+static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getchar_common(argvars, rettv);
+}
+
+// "getcharstr()" function
+static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getchar_common(argvars, rettv);
+
+ if (rettv->v_type == VAR_NUMBER) {
+ char_u temp[7]; // mbyte-char: 6, NUL: 1
+ const varnumber_T n = rettv->vval.v_number;
+ int i = 0;
+
+ if (n != 0) {
+ i += utf_char2bytes(n, temp);
+ }
+ assert(i < 7);
+ temp[i++] = NUL;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(temp);
+ }
+}
+
/*
* "getcharmod()" function
*/
@@ -11367,6 +11392,9 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = vim_strsave((char_u *)"popup");
} else if (wp == curwin && cmdwin_type != 0) {
rettv->vval.v_string = vim_strsave((char_u *)"command");
+ } else if (bt_quickfix(wp->w_buffer)) {
+ rettv->vval.v_string = vim_strsave((char_u *)(wp->w_llist_ref != NULL ?
+ "loclist" : "quickfix"));
}
}
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index f14a93eb44..deddec413b 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -1902,7 +1902,7 @@ void ex_function(exarg_T *eap)
char_u *line_to_free = NULL;
int c;
int saved_did_emsg;
- int saved_wait_return = need_wait_return;
+ bool saved_wait_return = need_wait_return;
char_u *name = NULL;
char_u *p;
char_u *arg;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index dc096bdb93..3ad1fb1adc 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1635,14 +1635,14 @@ void print_line(linenr_T lnum, int use_number, int list)
msg_start();
silent_mode = FALSE;
- info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ info_message = true; // use mch_msg(), not mch_errmsg()
print_line_no_prefix(lnum, use_number, list);
if (save_silent) {
msg_putchar('\n');
ui_flush();
silent_mode = save_silent;
}
- info_message = FALSE;
+ info_message = false;
}
int rename_buffer(char_u *new_fname)
@@ -1892,7 +1892,7 @@ int do_write(exarg_T *eap)
if (eap->cmdidx == CMD_saveas) {
if (retval == OK) {
curbuf->b_p_ro = FALSE;
- redraw_tabline = TRUE;
+ redraw_tabline = true;
}
}
@@ -2812,8 +2812,9 @@ int do_ecmd(
redraw_curbuf_later(NOT_VALID); // redraw this buffer later
}
- if (p_im)
- need_start_insertmode = TRUE;
+ if (p_im) {
+ need_start_insertmode = true;
+ }
/* Change directories when the 'acd' option is set. */
do_autochdir();
@@ -2879,7 +2880,7 @@ void ex_append(exarg_T *eap)
for (;; ) {
msg_scroll = TRUE;
- need_wait_return = FALSE;
+ need_wait_return = false;
if (curbuf->b_p_ai) {
if (append_indent >= 0) {
indent = append_indent;
@@ -2967,8 +2968,8 @@ void ex_append(exarg_T *eap)
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
- need_wait_return = FALSE; /* don't use wait_return() now */
- ex_no_reprint = TRUE;
+ need_wait_return = false; // don't use wait_return() now
+ ex_no_reprint = true;
}
/*
@@ -3820,8 +3821,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
redraw_later(curwin, SOME_VALID);
curwin->w_p_fen = save_p_fen;
- if (msg_row == Rows - 1)
- msg_didout = FALSE; /* avoid a scroll-up */
+ if (msg_row == Rows - 1) {
+ msg_didout = false; // avoid a scroll-up
+ }
msg_starthere();
i = msg_scroll;
msg_scroll = 0; /* truncate msg when
@@ -3840,8 +3842,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
typed = plain_vgetc();
no_mapping--;
- /* clear the question */
- msg_didout = FALSE; /* don't scroll up */
+ // clear the question
+ msg_didout = false; // don't scroll up
msg_col = 0;
gotocmdline(true);
p_lz = save_p_lz;
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index f54b219299..a49b0c15e1 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -135,7 +135,7 @@ void do_debug(char_u *cmd)
const bool save_cmd_silent = cmd_silent;
int save_msg_silent = msg_silent;
int save_emsg_silent = emsg_silent;
- int save_redir_off = redir_off;
+ bool save_redir_off = redir_off;
tasave_T typeaheadbuf;
bool typeahead_saved = false;
int save_ignore_script = 0;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index c83c19fc35..d10ecf5c7f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -306,13 +306,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
void *cookie, /* argument for fgetline() */
int flags)
{
- char_u *next_cmdline; /* next cmd to execute */
- char_u *cmdline_copy = NULL; /* copy of cmd line */
- int used_getline = FALSE; /* used "fgetline" to obtain command */
- static int recursive = 0; /* recursive depth */
- int msg_didout_before_start = 0;
- int count = 0; /* line number count */
- int did_inc = FALSE; /* incremented RedrawingDisabled */
+ char_u *next_cmdline; // next cmd to execute
+ char_u *cmdline_copy = NULL; // copy of cmd line
+ bool used_getline = false; // used "fgetline" to obtain command
+ static int recursive = 0; // recursive depth
+ bool msg_didout_before_start = false;
+ int count = 0; // line number count
+ int did_inc = FALSE; // incremented RedrawingDisabled
int retval = OK;
cstack_T cstack = { // conditional stack
.cs_idx = -1,
@@ -532,7 +532,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
retval = FAIL;
break;
}
- used_getline = TRUE;
+ used_getline = true;
/*
* Keep the first typed line. Clear it when more lines are typed.
@@ -573,7 +573,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
if (!(flags & DOCMD_NOWAIT) && !recursive) {
msg_didout_before_start = msg_didout;
- msg_didany = FALSE; /* no output yet */
+ msg_didany = false; // no output yet
msg_start();
msg_scroll = TRUE; /* put messages below each other */
++no_wait_return; /* don't wait for return until finished */
@@ -753,7 +753,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
|| (flags & DOCMD_REPEAT)));
xfree(cmdline_copy);
- did_emsg_syntax = FALSE;
+ did_emsg_syntax = false;
GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD);
if (cstack.cs_idx >= 0) {
@@ -927,8 +927,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
if (retval == FAIL
|| (did_endif && KeyTyped && !did_emsg)
) {
- need_wait_return = FALSE;
- msg_didany = FALSE; /* don't wait when restarting edit */
+ need_wait_return = false;
+ msg_didany = false; // don't wait when restarting edit
} else if (need_wait_return) {
/*
* The msg_start() above clears msg_didout. The wait_return we do
@@ -6652,9 +6652,10 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
break;
}
- redraw_tabline = TRUE;
- if (h != tabline_height())
+ redraw_tabline = true;
+ if (h != tabline_height()) {
shell_new_rows();
+ }
}
/*
@@ -6798,7 +6799,7 @@ static void ex_print(exarg_T *eap)
beginline(BL_SOL | BL_FIX);
}
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
}
static void ex_goto(exarg_T *eap)
@@ -7314,7 +7315,7 @@ do_exedit(
RedrawingDisabled = 0;
no_wait_return = 0;
- need_wait_return = FALSE;
+ need_wait_return = false;
msg_scroll = 0;
redraw_all_later(NOT_VALID);
@@ -7410,7 +7411,7 @@ do_exedit(
&& !cmdmod.keepalt)
old_curwin->w_alt_fnum = curbuf->b_fnum;
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
}
/// ":gui" and ":gvim" when there is no GUI.
@@ -7909,8 +7910,8 @@ void ex_may_print(exarg_T *eap)
{
if (eap->flags != 0) {
print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
- (eap->flags & EXFLAG_LIST));
- ex_no_reprint = TRUE;
+ (eap->flags & EXFLAG_LIST));
+ ex_no_reprint = true;
}
}
@@ -7965,9 +7966,9 @@ static void ex_at(exarg_T *eap)
== FAIL) {
beep_flush();
} else {
- int save_efr = exec_from_reg;
+ bool save_efr = exec_from_reg;
- exec_from_reg = TRUE;
+ exec_from_reg = true;
/*
* Execute from the typeahead buffer.
@@ -8131,7 +8132,7 @@ static void ex_redir(exarg_T *eap)
if (redir_fd != NULL
|| redir_reg || redir_vname
)
- redir_off = FALSE;
+ redir_off = false;
}
/// ":redraw": force redraw
@@ -8158,12 +8159,12 @@ static void ex_redraw(exarg_T *eap)
RedrawingDisabled = r;
p_lz = p;
- /* Reset msg_didout, so that a message that's there is overwritten. */
- msg_didout = FALSE;
+ // Reset msg_didout, so that a message that's there is overwritten.
+ msg_didout = false;
msg_col = 0;
- /* No need to wait after an intentional redraw. */
- need_wait_return = FALSE;
+ // No need to wait after an intentional redraw.
+ need_wait_return = false;
ui_flush();
}
@@ -8346,7 +8347,9 @@ void restore_current_state(save_state_T *sst)
finish_op = sst->save_finish_op;
opcount = sst->save_opcount;
reg_executing = sst->save_reg_executing;
- msg_didout |= sst->save_msg_didout; // don't reset msg_didout now
+
+ // don't reset msg_didout now
+ msg_didout |= sst->save_msg_didout;
// Restore the state (needed when called from a function executed for
// 'indentexpr'). Update the mouse and cursor, they may have changed.
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index c8c5a0a3e2..292e01dd6b 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -21,7 +21,7 @@
typedef struct {
int save_msg_scroll;
int save_restart_edit;
- int save_msg_didout;
+ bool save_msg_didout;
int save_State;
int save_insertmode;
bool save_finish_op;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 855f71ca28..2b3d773ca4 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -2267,7 +2267,7 @@ static int command_line_changed(CommandLineState *s)
close_preview_windows();
update_screen(SOME_VALID); // Clear 'inccommand' preview.
} else {
- if (s->xpc.xp_context == EXPAND_NOTHING) {
+ if (s->xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL)) {
may_do_incsearch_highlighting(s->firstc, s->count, &s->is_state);
}
}
@@ -3455,7 +3455,7 @@ void redrawcmdline(void)
{
if (cmd_silent)
return;
- need_wait_return = FALSE;
+ need_wait_return = false;
compute_cmdrow();
redrawcmd();
cursorcmd();
@@ -4225,13 +4225,13 @@ static int showmatches(expand_T *xp, int wildmenu)
}
if (!wildmenu) {
- msg_didany = FALSE; /* lines_left will be set */
- msg_start(); /* prepare for paging */
+ msg_didany = false; // lines_left will be set
+ msg_start(); // prepare for paging
msg_putchar('\n');
ui_flush();
cmdline_row = msg_row;
- msg_didany = FALSE; /* lines_left will be set again */
- msg_start(); /* prepare for paging */
+ msg_didany = false; // lines_left will be set again
+ msg_start(); // prepare for paging
}
if (got_int) {
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index 67b8e7e92f..3038ed3947 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -583,22 +583,6 @@ static int makeopens(FILE *fd, char_u *dirnow)
return FAIL;
}
- // Now put the other buffers into the buffer list.
- FOR_ALL_BUFFERS(buf) {
- if (!(only_save_windows && buf->b_nwindows == 0)
- && !(buf->b_help && !(ssop_flags & SSOP_HELP))
- && buf->b_fname != NULL
- && buf->b_p_bl) {
- if (fprintf(fd, "badd +%" PRId64 " ",
- buf->b_wininfo == NULL
- ? (int64_t)1L
- : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
- || ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
- return FAIL;
- }
- }
- }
-
// the global argument list
if (ses_arglist(fd, "argglobal", &global_alist.al_ga,
!(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL) {
@@ -813,12 +797,31 @@ static int makeopens(FILE *fd, char_u *dirnow)
return FAIL;
}
+ // Now put the remaining buffers into the buffer list.
+ // This is near the end, so that when 'hidden' is set we don't create extra
+ // buffers. If the buffer was already created with another command the
+ // ":badd" will have no effect.
+ FOR_ALL_BUFFERS(buf) {
+ if (!(only_save_windows && buf->b_nwindows == 0)
+ && !(buf->b_help && !(ssop_flags & SSOP_HELP))
+ && buf->b_fname != NULL
+ && buf->b_p_bl) {
+ if (fprintf(fd, "badd +%" PRId64 " ",
+ buf->b_wininfo == NULL
+ ? (int64_t)1L
+ : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
+ || ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
+ return FAIL;
+ }
+ }
+ }
+
//
// Wipe out an empty unnamed buffer we started in.
//
if (fprintf(fd, "%s",
"if exists('s:wipebuf') "
- "&& len(win_findbuf(s:wipebuf)) == 0"
+ "&& len(win_findbuf(s:wipebuf)) == 0 "
"&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'\n"
" silent exe 'bwipe ' . s:wipebuf\n"
"endif\n"
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 60b7b024f1..4b2dccd8a4 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -268,7 +268,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
}
ExtmarkNs *my_ns = all_ns ? buf_ns_ref(buf, item.ns_id, false) : ns;
map_del(uint64_t, uint64_t)(my_ns->map, item.mark_id);
- map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark.id);
+ map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id);
marktree_del_itr(buf->b_marktree, itr, false);
} else {
marktree_itr_next(buf->b_marktree, itr);
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 9b89a4dd38..ee8be8429f 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -290,7 +290,7 @@ readfile(
/* After reading a file the cursor line changes but we don't want to
* display the line. */
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
// don't display the file info for another buffer now
need_fileinfo = false;
@@ -2237,7 +2237,7 @@ buf_write(
/* After writing a file changedtick changes but we don't want to display
* the line. */
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
/*
* If there is no file name yet, use the one for the written file.
@@ -4241,7 +4241,7 @@ void shorten_fnames(int force)
mf_fullname(buf->b_ml.ml_mfp);
}
status_redraw_all();
- redraw_tabline = TRUE;
+ redraw_tabline = true;
}
/// Get new filename ended by given extension.
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 55a912b417..96acca4ac7 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -138,14 +138,14 @@ EXTERN int mod_mask INIT(= 0x0); // current key modifiers
// update_screen().
EXTERN int cmdline_row;
-EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn
-EXTERN int clear_cmdline INIT(= false); // cmdline must be cleared
-EXTERN int mode_displayed INIT(= false); // mode is being displayed
+EXTERN bool redraw_cmdline INIT(= false); // cmdline must be redrawn
+EXTERN bool clear_cmdline INIT(= false); // cmdline must be cleared
+EXTERN bool mode_displayed INIT(= false); // mode is being displayed
EXTERN int cmdline_star INIT(= false); // cmdline is encrypted
EXTERN bool redrawing_cmdline INIT(= false); // cmdline is being redrawn
EXTERN bool cmdline_was_last_drawn INIT(= false); // cmdline was last drawn
-EXTERN int exec_from_reg INIT(= false); // executing register
+EXTERN bool exec_from_reg INIT(= false); // executing register
// When '$' is included in 'cpoptions' option set:
// When a change command is given that deletes only part of a line, a dollar
@@ -204,12 +204,12 @@ EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg
EXTERN bool keep_msg_more INIT(= false); // keep_msg was set by msgmore()
EXTERN bool need_fileinfo INIT(= false); // do fileinfo() after redraw
EXTERN int msg_scroll INIT(= false); // msg_start() will scroll
-EXTERN int msg_didout INIT(= false); // msg_outstr() was used in line
-EXTERN int msg_didany INIT(= false); // msg_outstr() was used at all
-EXTERN int msg_nowait INIT(= false); // don't wait for this msg
+EXTERN bool msg_didout INIT(= false); // msg_outstr() was used in line
+EXTERN bool msg_didany INIT(= false); // msg_outstr() was used at all
+EXTERN bool msg_nowait INIT(= false); // don't wait for this msg
EXTERN int emsg_off INIT(= 0); // don't display errors for now,
// unless 'debug' is set.
-EXTERN int info_message INIT(= false); // printing informative message
+EXTERN bool info_message INIT(= false); // printing informative message
EXTERN bool msg_hist_off INIT(= false); // don't add messages to history
EXTERN bool need_clr_eos INIT(= false); // need to clear text before
// displaying a message.
@@ -225,18 +225,18 @@ EXTERN dict_T globvardict; // Dictionary with g: variables
EXTERN int did_emsg; // set by emsg() when the message
// is displayed or thrown
EXTERN bool called_vim_beep; // set if vim_beep() is called
-EXTERN int did_emsg_syntax; // did_emsg set because of a
+EXTERN bool did_emsg_syntax; // did_emsg set because of a
// syntax error
EXTERN int called_emsg; // always set by emsg()
EXTERN int ex_exitval INIT(= 0); // exit value for ex mode
EXTERN bool emsg_on_display INIT(= false); // there is an error message
-EXTERN int rc_did_emsg INIT(= false); // vim_regcomp() called emsg()
+EXTERN bool rc_did_emsg INIT(= false); // vim_regcomp() called emsg()
-EXTERN int no_wait_return INIT(= 0); // don't wait for return for now
-EXTERN int need_wait_return INIT(= 0); // need to wait for return later
-EXTERN bool did_wait_return INIT(= false); // wait_return() was used and
- // nothing written since then
-EXTERN bool need_maketitle INIT(= true); // call maketitle() soon
+EXTERN int no_wait_return INIT(= 0); // don't wait for return for now
+EXTERN bool need_wait_return INIT(= false); // need to wait for return later
+EXTERN bool did_wait_return INIT(= false); // wait_return() was used and
+ // nothing written since then
+EXTERN bool need_maketitle INIT(= true); // call maketitle() soon
EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg
EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0
@@ -449,7 +449,7 @@ EXTERN frame_T *topframe; // top of the window frame tree
EXTERN tabpage_T *first_tabpage;
EXTERN tabpage_T *lastused_tabpage;
EXTERN tabpage_T *curtab;
-EXTERN int redraw_tabline INIT(= false); // need to redraw tabline
+EXTERN bool redraw_tabline INIT(= false); // need to redraw tabline
// Iterates over all tabs in the tab list
# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next)
@@ -501,7 +501,7 @@ EXTERN volatile int full_screen INIT(= false);
/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
/// .vimrc in current directory.
-EXTERN int secure INIT(= false);
+EXTERN int secure INIT(= 0);
/// Non-zero when changing text and jumping to another window/buffer is not
/// allowed.
@@ -524,6 +524,8 @@ EXTERN pos_T VIsual;
EXTERN int VIsual_active INIT(= false);
/// Whether Select mode is active.
EXTERN int VIsual_select INIT(= false);
+/// Restart Select mode when next cmd finished
+EXTERN int restart_VIsual_select INIT(= 0);
/// Whether to restart the selection after a Select-mode mapping or menu.
EXTERN int VIsual_reselect;
/// Type of Visual mode.
@@ -621,7 +623,7 @@ EXTERN int motion_force INIT(=0); // motion force for pending operator
// Ex Mode (Q) state
EXTERN bool exmode_active INIT(= false); // true if Ex mode is active
-EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p.
+EXTERN bool ex_no_reprint INIT(=false); // No need to print after z or p.
EXTERN int reg_recording INIT(= 0); // register for recording or zero
EXTERN int reg_executing INIT(= 0); // register being executed or zero
@@ -699,14 +701,14 @@ EXTERN bool do_redraw INIT(= false); // extra redraw once
EXTERN bool must_redraw_pum INIT(= false); // redraw pum. NB: must_redraw
// should also be set.
-EXTERN int need_highlight_changed INIT(= true);
+EXTERN bool need_highlight_changed INIT(= true);
EXTERN FILE *scriptout INIT(= NULL); ///< Stream to write script to.
// volatile because it is used in a signal handler.
EXTERN volatile int got_int INIT(= false); // set to true when interrupt
// signal occurred
-EXTERN int bangredo INIT(= false); // set to true with ! command
+EXTERN bool bangredo INIT(= false); // set to true with ! command
EXTERN int searchcmdlen; // length of previous search cmd
EXTERN int reg_do_extmatch INIT(= 0); // Used when compiling regexp:
// REX_SET to allow \z\(...\),
@@ -716,14 +718,14 @@ EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL);
// Set by vim_regexec() to store \z\(...\) matches
EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL);
-EXTERN int did_outofmem_msg INIT(= false);
+EXTERN bool did_outofmem_msg INIT(= false);
// set after out of memory msg
-EXTERN int did_swapwrite_msg INIT(= false);
+EXTERN bool did_swapwrite_msg INIT(= false);
// set after swap write error msg
EXTERN int global_busy INIT(= 0); // set when :global is executing
-EXTERN int listcmd_busy INIT(= false); // set when :argdo, :windo or
+EXTERN bool listcmd_busy INIT(= false); // set when :argdo, :windo or
// :bufdo is executing
-EXTERN int need_start_insertmode INIT(= false);
+EXTERN bool need_start_insertmode INIT(= false);
// start insert mode soon
EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":)
EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "."
@@ -738,9 +740,9 @@ EXTERN int postponed_split_flags INIT(= 0); // args for win_split()
EXTERN int postponed_split_tab INIT(= 0); // cmdmod.tab
EXTERN int g_do_tagpreview INIT(= 0); // for tag preview commands:
// height of preview window
-EXTERN int g_tag_at_cursor INIT(= false); // whether the tag command comes
- // from the command line (0) or was
- // invoked as a normal command (1)
+EXTERN bool g_tag_at_cursor INIT(= false); // whether the tag command comes
+ // from the command line (0) or was
+ // invoked as a normal command (1)
EXTERN int replace_offset INIT(= 0); // offset for replace_push()
@@ -754,7 +756,7 @@ EXTERN int keep_help_flag INIT(= false); // doing :ta from help file
// everywhere.
EXTERN char_u *empty_option INIT(= (char_u *)"");
-EXTERN int redir_off INIT(= false); // no redirection for a moment
+EXTERN bool redir_off INIT(= false); // no redirection for a moment
EXTERN FILE *redir_fd INIT(= NULL); // message redirection file
EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
@@ -788,8 +790,8 @@ extern char_u *compiled_sys;
EXTERN char_u *globaldir INIT(= NULL);
// Whether 'keymodel' contains "stopsel" and "startsel".
-EXTERN int km_stopsel INIT(= false);
-EXTERN int km_startsel INIT(= false);
+EXTERN bool km_stopsel INIT(= false);
+EXTERN bool km_startsel INIT(= false);
EXTERN int cedit_key INIT(= -1); ///< key value of 'cedit' option
EXTERN int cmdwin_type INIT(= 0); ///< type of cmdline window or 0
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 8b8be9cc39..252aa81825 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -372,11 +372,6 @@ int main(int argc, char **argv)
// If using the runtime (-u is not NONE), enable syntax & filetype plugins.
if (params.use_vimrc == NULL || !strequal(params.use_vimrc, "NONE")) {
- // Source syncolor.vim to set up default UI highlights if the user didn't
- // already enable a colorscheme
- if (!get_var_value("g:colors_name")) {
- source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL);
- }
// Does ":filetype plugin indent on".
filetype_maybe_enable();
// Sources syntax/syntax.vim, which calls `:filetype on`.
@@ -1448,7 +1443,7 @@ static void read_stdin(void)
// When getting the ATTENTION prompt here, use a dialog.
swap_exists_action = SEA_DIALOG;
no_wait_return = true;
- int save_msg_didany = msg_didany;
+ bool save_msg_didany = msg_didany;
set_buflisted(true);
// Create memfile and read from stdin.
(void)open_buffer(true, NULL, 0);
@@ -2005,10 +2000,10 @@ static void mainerr(const char *errstr, const char *str)
/// Prints version information for "nvim -v" or "nvim --version".
static void version(void)
{
- info_message = TRUE; // use mch_msg(), not mch_errmsg()
+ info_message = true; // use mch_msg(), not mch_errmsg()
list_version();
msg_putchar('\n');
- msg_didout = FALSE;
+ msg_didout = false;
}
/// Prints help message for "nvim -h" or "nvim --help".
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 9ce77fe928..0b14089550 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -346,10 +346,10 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
} else if (c == '{' || c == '}') { // to previous/next paragraph
pos_T pos;
oparg_T oa;
- int slcb = listcmd_busy;
+ bool slcb = listcmd_busy;
pos = curwin->w_cursor;
- listcmd_busy = TRUE; /* avoid that '' is changed */
+ listcmd_busy = true; // avoid that '' is changed
if (findpar(&oa.inclusive,
c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
pos_copy = curwin->w_cursor;
@@ -359,10 +359,10 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
listcmd_busy = slcb;
} else if (c == '(' || c == ')') { /* to previous/next sentence */
pos_T pos;
- int slcb = listcmd_busy;
+ bool slcb = listcmd_busy;
pos = curwin->w_cursor;
- listcmd_busy = TRUE; /* avoid that '' is changed */
+ listcmd_busy = true; // avoid that '' is changed
if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) {
pos_copy = curwin->w_cursor;
posp = &pos_copy;
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 9cd57affb9..cba372b9d3 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -73,9 +73,6 @@ struct interval {
# include "unicode_tables.generated.h"
#endif
-char_u e_loadlib[] = "E370: Could not load library %s";
-char_u e_loadfunc[] = "E448: Could not load library function %s";
-
// To speed up BYTELEN(); keep a lookup table to quickly get the length in
// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
// which are illegal when used as the first byte have a 1. The NUL byte has
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 2046e2f324..8229b8f6bc 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -3575,9 +3575,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
}
} else {
MSG_PUTS("\n");
- if (msg_silent == 0)
- /* call wait_return() later */
- need_wait_return = TRUE;
+ if (msg_silent == 0) {
+ // call wait_return() later
+ need_wait_return = true;
+ }
}
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 7ac846a553..bd26b8608f 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -79,12 +79,12 @@ static int verbose_did_open = FALSE;
/*
* When writing messages to the screen, there are many different situations.
* A number of variables is used to remember the current state:
- * msg_didany TRUE when messages were written since the last time the
+ * msg_didany true when messages were written since the last time the
* user reacted to a prompt.
* Reset: After hitting a key for the hit-return prompt,
* hitting <CR> for the command line or input().
* Set: When any message is written to the screen.
- * msg_didout TRUE when something was written to the current line.
+ * msg_didout true when something was written to the current line.
* Reset: When advancing to the next line, when the current
* text can be overwritten.
* Set: When any message is written to the screen.
@@ -102,7 +102,7 @@ static int verbose_did_open = FALSE;
* work without an extra prompt.
* lines_left Number of lines available for messages before the
* more-prompt is to be given. -1 when not set.
- * need_wait_return TRUE when the hit-return prompt is needed.
+ * need_wait_return true when the hit-return prompt is needed.
* Reset: After giving the hit-return prompt, when the user
* has answered some other prompt.
* Set: When the ruler or typeahead display is overwritten,
@@ -1097,14 +1097,14 @@ void wait_return(int redraw)
*/
if (vgetc_busy > 0)
return;
- need_wait_return = TRUE;
+ need_wait_return = true;
if (no_wait_return) {
if (!exmode_active)
cmdline_row = msg_row;
return;
}
- redir_off = TRUE; /* don't redirect this message */
+ redir_off = true; // don't redirect this message
oldState = State;
if (quit_more) {
c = CAR; /* just pretend CR was hit */
@@ -1165,11 +1165,11 @@ void wait_return(int redraw)
if (p_more) {
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|| c == K_UP || c == K_PAGEUP) {
- if (msg_scrolled > Rows)
- /* scroll back to show older messages */
+ if (msg_scrolled > Rows) {
+ // scroll back to show older messages
do_more_prompt(c);
- else {
- msg_didout = FALSE;
+ } else {
+ msg_didout = false;
c = K_IGNORE;
msg_col =
cmdmsg_rl ? Columns - 1 :
@@ -1353,7 +1353,7 @@ void msg_start(void)
void msg_starthere(void)
{
lines_left = cmdline_row;
- msg_didany = FALSE;
+ msg_didany = false;
}
void msg_putchar(int c)
@@ -2145,15 +2145,17 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
}
- if (*s == '\n') { /* go to next line */
- msg_didout = FALSE; /* remember that line is empty */
- if (cmdmsg_rl)
+ if (*s == '\n') { // go to next line
+ msg_didout = false; // remember that line is empty
+ if (cmdmsg_rl) {
msg_col = Columns - 1;
- else
+ } else {
msg_col = 0;
- if (++msg_row >= Rows) /* safety check */
+ }
+ if (++msg_row >= Rows) { // safety check
msg_row = Rows - 1;
- } else if (*s == '\r') { /* go to column 0 */
+ }
+ } else if (*s == '\r') { // go to column 0
msg_col = 0;
} else if (*s == '\b') { /* go to previous char */
if (msg_col)
@@ -2708,9 +2710,9 @@ static int do_more_prompt(int typed_char)
/* Since got_int is set all typeahead will be flushed, but we
* want to keep this ':', remember that in a special way. */
typeahead_noflush(':');
- cmdline_row = Rows - 1; /* put ':' on this line */
- skip_redraw = TRUE; /* skip redraw once */
- need_wait_return = FALSE; /* don't wait in main() */
+ cmdline_row = Rows - 1; // put ':' on this line
+ skip_redraw = true; // skip redraw once
+ need_wait_return = false; // don't wait in main()
}
FALLTHROUGH;
case 'q': // quit
@@ -2931,7 +2933,7 @@ void repeat_message(void)
/* Avoid drawing the "hit-enter" prompt below the previous one,
* overwrite it. Esp. useful when regaining focus and a
* FocusGained autocmd exists but didn't draw anything. */
- msg_didout = FALSE;
+ msg_didout = false;
msg_col = 0;
msg_clr_eos();
}
@@ -3095,8 +3097,8 @@ void msg_check(void)
return;
}
if (msg_row == Rows - 1 && msg_col >= sc_col) {
- need_wait_return = TRUE;
- redraw_cmdline = TRUE;
+ need_wait_return = true;
+ redraw_cmdline = true;
}
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 4213e6f946..9185062f94 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -92,8 +92,6 @@ static linenr_T resel_VIsual_line_count; /* number of lines */
static colnr_T resel_VIsual_vcol; /* nr of cols or end col */
static int VIsual_mode_orig = NUL; /* saved Visual mode */
-static int restart_VIsual_select = 0;
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "normal.c.generated.h"
diff --git a/src/nvim/option.c b/src/nvim/option.c
index f67cfd109b..b40ecd22c8 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -322,6 +322,7 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2",
"auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
+static char *(p_culopt_values[]) = { "line", "number", "both", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
@@ -769,7 +770,7 @@ void free_all_options(void)
}
} else if (options[i].var != VAR_WIN && (options[i].flags & P_STRING)) {
// buffer-local option: free global value
- free_string_option(*(char_u **)options[i].var);
+ clear_string_option((char_u **)options[i].var);
}
}
}
@@ -2411,6 +2412,12 @@ did_set_string_option(
os_setenv("VIMRUNTIME", "", 1);
didset_vimruntime = false;
}
+ } else if (varp == &curwin->w_p_culopt
+ || gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
+ if (**varp == NUL
+ || check_opt_strings(*varp, p_culopt_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
errmsg = check_colorcolumn(curwin);
} else if (varp == &p_hlg) { // 'helplang'
@@ -5652,6 +5659,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
case PV_CUL: return (char_u *)&(curwin->w_p_cul);
+ case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
case PV_CC: return (char_u *)&(curwin->w_p_cc);
case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
@@ -5799,6 +5807,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_spell = from->wo_spell;
to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
+ to->wo_culopt = vim_strsave(from->wo_culopt);
to->wo_cc = vim_strsave(from->wo_cc);
to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved;
@@ -5849,6 +5858,7 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
check_string_option(&wop->wo_stl);
+ check_string_option(&wop->wo_culopt);
check_string_option(&wop->wo_cc);
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
@@ -5871,6 +5881,7 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
clear_string_option(&wop->wo_stl);
+ clear_string_option(&wop->wo_culopt);
clear_string_option(&wop->wo_cc);
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 5e40bdd6ef..37e75a6cc7 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -870,6 +870,7 @@ enum {
, WV_SPELL
, WV_CUC
, WV_CUL
+ , WV_CULOPT
, WV_CC
, WV_STL
, WV_WFH
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 0830fb4638..7b8170094e 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -556,6 +556,13 @@ return {
defaults={if_true={vi=false}}
},
{
+ full_name='cursorlineopt', abbreviation='culopt',
+ short_desc=N_("settings for 'cursorline'"),
+ type='string', scope={'window'},
+ redraw={'current_window_only'},
+ defaults={if_true={vi="both"}}
+ },
+ {
full_name='debug',
short_desc=N_("to \"msg\" to see all error messages"),
type='string', scope={'global'},
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 7c7b790d5c..0cfb7c192f 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -54,20 +54,23 @@ struct dir_stack_T {
// For each error the next struct is allocated and linked in a list.
typedef struct qfline_S qfline_T;
struct qfline_S {
- qfline_T *qf_next; ///< pointer to next error in the list
- qfline_T *qf_prev; ///< pointer to previous error in the list
- linenr_T qf_lnum; ///< line number where the error occurred
- int qf_fnum; ///< file number for the line
- int qf_col; ///< column where the error occurred
- int qf_nr; ///< error number
- char_u *qf_module; ///< module name for this error
- char_u *qf_pattern; ///< search pattern for the error
- char_u *qf_text; ///< description of the error
- char_u qf_viscol; ///< set to TRUE if qf_col is screen column
- char_u qf_cleared; ///< set to TRUE if line has been deleted
- char_u qf_type; ///< type of the error (mostly 'E'); 1 for
- // :helpgrep
- char_u qf_valid; ///< valid error message detected
+ qfline_T *qf_next; ///< pointer to next error in the list
+ qfline_T *qf_prev; ///< pointer to previous error in the list
+ linenr_T qf_lnum; ///< line number where the error occurred
+ linenr_T qf_end_lnum; ///< line number when the error has range or zero
+
+ int qf_fnum; ///< file number for the line
+ int qf_col; ///< column where the error occurred
+ int qf_end_col; ///< column when the error has range or zero
+ int qf_nr; ///< error number
+ char_u *qf_module; ///< module name for this error
+ char_u *qf_pattern; ///< search pattern for the error
+ char_u *qf_text; ///< description of the error
+ char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is
+ // screen column
+ char_u qf_cleared; ///< set to TRUE if line has been deleted
+ char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep
+ char_u qf_valid; ///< valid error message detected
};
// There is a stack of error lists.
@@ -197,7 +200,9 @@ typedef struct {
char_u *errmsg;
size_t errmsglen;
long lnum;
+ long end_lnum;
int col;
+ int end_col;
bool use_viscol;
char_u *pattern;
int enr;
@@ -282,7 +287,9 @@ static int qf_init_process_nextline(qf_list_T *qfl,
0,
fields->errmsg,
fields->lnum,
+ fields->end_lnum,
fields->col,
+ fields->end_col,
fields->use_viscol,
fields->pattern,
fields->enr,
@@ -1561,7 +1568,9 @@ static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
fields->errmsg[0] = NUL;
}
fields->lnum = 0;
+ fields->end_lnum = 0;
fields->col = 0;
+ fields->end_col = 0;
fields->use_viscol = false;
fields->enr = -1;
fields->type = 0;
@@ -1799,7 +1808,9 @@ void check_quickfix_busy(void)
/// @param bufnum buffer number or zero
/// @param mesg message
/// @param lnum line number
+/// @param end_lnum line number for end
/// @param col column
+/// @param end_col column for end
/// @param vis_col using visual column
/// @param pattern search pattern
/// @param nr error number
@@ -1808,8 +1819,9 @@ void check_quickfix_busy(void)
///
/// @returns QF_OK or QF_FAIL.
static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
- char_u *module, int bufnum, char_u *mesg, long lnum,
- int col, char_u vis_col, char_u *pattern, int nr,
+ char_u *module, int bufnum, char_u *mesg,
+ long lnum, long end_lnum, int col, int end_col,
+ char_u vis_col, char_u *pattern, int nr,
char_u type, char_u valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
@@ -1828,7 +1840,9 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
}
qfp->qf_text = vim_strsave(mesg);
qfp->qf_lnum = lnum;
+ qfp->qf_end_lnum = end_lnum;
qfp->qf_col = col;
+ qfp->qf_end_col = end_col;
qfp->qf_viscol = vis_col;
if (pattern == NULL || *pattern == NUL) {
qfp->qf_pattern = NULL;
@@ -1957,7 +1971,9 @@ static int copy_loclist_entries(const qf_list_T *from_qfl, qf_list_T *to_qfl)
0,
from_qfp->qf_text,
from_qfp->qf_lnum,
+ from_qfp->qf_end_lnum,
from_qfp->qf_col,
+ from_qfp->qf_end_col,
from_qfp->qf_viscol,
from_qfp->qf_pattern,
from_qfp->qf_nr,
@@ -2998,6 +3014,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
}
qfl->qf_index = qf_index;
+ qfl->qf_ptr = qf_ptr;
if (qf_win_pos_update(qi, old_qf_index)) {
// No need to print the error message if it's visible in the error
// window
@@ -3108,11 +3125,8 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
}
if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
- } else if (qfp->qf_col == 0) {
- vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR, qfp->qf_lnum);
} else {
- vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR " col %d",
- qfp->qf_lnum, qfp->qf_col);
+ qf_range_text(qfp, IObuff, IOSIZE);
}
vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
@@ -3232,6 +3246,32 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf,
buf[i] = NUL;
}
+// Range information from lnum, col, end_lnum, and end_col.
+// Put the result in "buf[bufsize]".
+static void qf_range_text(const qfline_T *qfp, char_u *buf, int bufsize)
+{
+ vim_snprintf((char *)buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum);
+ int len = (int)STRLEN(buf);
+
+ if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ "-%" PRIdLINENR, qfp->qf_end_lnum);
+ len += (int)STRLEN(buf + len);
+ }
+ if (qfp->qf_col > 0) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ " col %d", qfp->qf_col);
+ len += (int)STRLEN(buf + len);
+ if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ "-%d", qfp->qf_end_col);
+ len += (int)STRLEN(buf + len);
+ }
+ }
+ buf[len] = NUL;
+}
+
+
/// Display information (list number, list size and the title) about a
/// quickfix/location list.
static void qf_msg(qf_info_T *qi, int which, char *lead)
@@ -4005,16 +4045,9 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
IObuff[len++] = '|';
}
if (qfp->qf_lnum > 0) {
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%" PRId64,
- (int64_t)qfp->qf_lnum);
+ qf_range_text(qfp, IObuff + len, IOSIZE - len);
len += (int)STRLEN(IObuff + len);
- if (qfp->qf_col > 0) {
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), " col %d",
- qfp->qf_col);
- len += (int)STRLEN(IObuff + len);
- }
-
snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
len += (int)STRLEN(IObuff + len);
@@ -5263,7 +5296,9 @@ static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf,
ml_get_buf(buf, regmatch->startpos[0].lnum + lnum,
false),
regmatch->startpos[0].lnum + lnum,
+ regmatch->endpos[0].lnum + lnum,
regmatch->startpos[0].col + 1,
+ regmatch->endpos[0].col + 1,
false, // vis_col
NULL, // search pattern
0, // nr
@@ -5765,7 +5800,11 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL
|| (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum)
== FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum)
+ == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col) == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col)
+ == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol)
== FAIL)
|| (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL)
@@ -6263,7 +6302,9 @@ static int qf_add_entry_from_dict(
char *const module = tv_dict_get_string(d, "module", true);
int bufnum = (int)tv_dict_get_number(d, "bufnr");
const long lnum = (long)tv_dict_get_number(d, "lnum");
+ const long end_lnum = (long)tv_dict_get_number(d, "end_lnum");
const int col = (int)tv_dict_get_number(d, "col");
+ const int end_col = (int)tv_dict_get_number(d, "end_col");
const char_u vcol = (char_u)tv_dict_get_number(d, "vcol");
const int nr = (int)tv_dict_get_number(d, "nr");
const char *const type = tv_dict_get_string(d, "type", false);
@@ -6301,7 +6342,9 @@ static int qf_add_entry_from_dict(
bufnum,
(char_u *)text,
lnum,
+ end_lnum,
col,
+ end_col,
vcol, // vis_col
(char_u *)pattern, // search pattern
nr,
@@ -7035,7 +7078,10 @@ static void hgr_search_file(
0,
line,
lnum,
+ 0,
(int)(p_regmatch->startp[0] - line) + 1, // col
+ (int)(p_regmatch->endp[0] - line)
+ + 1, // end_col
false, // vis_col
NULL, // search pattern
0, // nr
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ae785132bb..b048facfb7 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -165,7 +165,7 @@ static bool resizing = false;
#endif
#define SEARCH_HL_PRIORITY 0
-static char * provider_first_error = NULL;
+static char * provider_err = NULL;
static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
Array args, bool default_true)
@@ -187,10 +187,10 @@ static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
const char *ns_name = describe_ns(ns_id);
ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
bool verbose_errs = true; // TODO(bfredl):
- if (verbose_errs && provider_first_error == NULL) {
+ if (verbose_errs && provider_err == NULL) {
static char errbuf[IOSIZE];
snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
- provider_first_error = xstrdup(errbuf);
+ provider_err = xstrdup(errbuf);
}
}
@@ -437,8 +437,8 @@ int update_screen(int type)
}
}
}
- redraw_cmdline = TRUE;
- redraw_tabline = TRUE;
+ redraw_cmdline = true;
+ redraw_tabline = true;
}
msg_scrolled = 0;
msg_scrolled_at_flush = 0;
@@ -2103,7 +2103,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
bool search_attr_from_match = false; // if search_attr is from :match
bool has_decor = false; // this buffer has decoration
- bool do_virttext = false; // draw virtual text for this line
int win_col_offset = 0; // offset for window columns
char_u buf_fold[FOLD_TEXT_LEN + 1]; // Hold value returned by get_foldtext
@@ -2148,8 +2147,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
row = startrow;
- char *err_text = NULL;
-
buf_T *buf = wp->w_buffer;
if (!number_only) {
@@ -2194,14 +2191,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
- if (has_decor) {
- extra_check = true;
+ if (provider_err) {
+ Decoration err_decor = DECORATION_INIT;
+ int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
+ kv_push(err_decor.virt_text,
+ ((VirtTextChunk){ .text = provider_err,
+ .hl_id = hl_err }));
+ err_decor.virt_text_width = mb_string2cells((char_u *)provider_err);
+ decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
+ provider_err = NULL;
+ has_decor = true;
}
- if (provider_first_error) {
- err_text = provider_first_error;
- provider_first_error = NULL;
- do_virttext = true;
+ if (has_decor) {
+ extra_check = true;
}
// Check for columns to display for 'colorcolumn'.
@@ -2359,7 +2362,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (lnum == wp->w_cursor.lnum) {
// Do not show the cursor line when Visual mode is active, because it's
// not clear what is selected then.
- if (wp->w_p_cul && !(wp == curwin && VIsual_active)) {
+ if (wp->w_p_cul && !(wp == curwin && VIsual_active)
+ && *wp->w_p_culopt != 'n') {
int cul_attr = win_hl_attr(wp, HLF_CUL);
HlAttrs ae = syn_attr2entry(cul_attr);
@@ -2783,6 +2787,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// :sign defined with "numhl" highlight.
char_attr = num_sattr->sat_numhl;
} else if ((wp->w_p_cul || wp->w_p_rnu)
+ && *wp->w_p_culopt != 'l'
&& lnum == wp->w_cursor.lnum
&& filler_todo == 0) {
// When 'cursorline' is set highlight the line number of
@@ -2818,7 +2823,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (diff_hlf != (hlf_T)0) {
char_attr = win_hl_attr(wp, diff_hlf);
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && *wp->w_p_culopt != 'n') {
char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
@@ -2878,7 +2884,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (tocol == vcol)
tocol += n_extra;
// Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && *wp->w_p_culopt != 'n') {
char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), char_attr);
}
}
@@ -3113,7 +3120,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
line_attr = win_hl_attr(wp, diff_hlf);
// Overlay CursorLine onto diff-mode highlight.
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && *wp->w_p_culopt != 'n') {
line_attr = 0 != line_attr_lowprio // Low-priority CursorLine
? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL),
line_attr),
@@ -3921,7 +3929,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int eol_attr = char_attr;
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && *wp->w_p_culopt != 'n') {
eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
}
linebuf_attr[off] = eol_attr;
@@ -3953,19 +3962,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (draw_color_col)
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- VirtText virt_text = KV_INITIAL_VALUE;
- bool has_aligned = false;
- if (err_text) {
- int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
- kv_push(virt_text, ((VirtTextChunk){ .text = err_text,
- .hl_id = hl_err }));
- do_virttext = true;
- } else if (has_decor) {
- virt_text = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
- &has_aligned);
- if (kv_size(virt_text)) {
- do_virttext = true;
- }
+ bool has_virttext = false;
+ // Make sure alignment is the same regardless
+ // if listchars=eol:X is used or not.
+ int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0
+ ? 1 : 0);
+
+ if (has_decor) {
+ has_virttext = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
+ col + eol_skip);
}
if (((wp->w_p_cuc
@@ -3974,20 +3979,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
grid->Columns * (row - startrow + 1) + v
&& lnum != wp->w_cursor.lnum)
|| draw_color_col || line_attr_lowprio || line_attr
- || diff_hlf != (hlf_T)0 || do_virttext
- || has_aligned)) {
+ || diff_hlf != (hlf_T)0 || has_virttext)) {
int rightmost_vcol = 0;
int i;
- size_t virt_pos = 0;
- LineState s = LINE_STATE("");
- int virt_attr = 0;
-
- // Make sure alignment is the same regardless
- // if listchars=eol:X is used or not.
- bool delay_virttext = wp->w_p_lcs_chars.eol == lcs_eol_one
- && eol_hl_off == 0;
-
if (wp->w_p_cuc) {
rightmost_vcol = wp->w_virtcol;
}
@@ -4013,37 +4008,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr);
- if (base_attr || line_attr || has_aligned) {
+ if (base_attr || line_attr || has_virttext) {
rightmost_vcol = INT_MAX;
}
int col_stride = wp->w_p_rl ? -1 : 1;
while (wp->w_p_rl ? col >= 0 : col < grid->Columns) {
- int cells = -1;
- if (do_virttext && !delay_virttext) {
- if (*s.p == NUL) {
- if (virt_pos < virt_text.size) {
- s.p = kv_A(virt_text, virt_pos).text;
- int hl_id = kv_A(virt_text, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- } else {
- do_virttext = false;
- }
- }
- if (*s.p != NUL) {
- cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col,
- false);
- }
- }
- delay_virttext = false;
-
- if (cells == -1) {
- schar_from_ascii(linebuf_char[off], ' ');
- cells = 1;
- }
- col += cells * col_stride;
+ schar_from_ascii(linebuf_char[off], ' ');
+ col += col_stride;
if (draw_color_col) {
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
}
@@ -4056,24 +4029,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
col_attr = mc_attr;
}
- if (do_virttext) {
- col_attr = hl_combine_attr(col_attr, virt_attr);
- }
-
col_attr = hl_combine_attr(col_attr, line_attr);
linebuf_attr[off] = col_attr;
- if (cells == 2) {
- linebuf_attr[off+1] = col_attr;
- }
- off += cells * col_stride;
+ off += col_stride;
- if (VCOL_HLC >= rightmost_vcol && *s.p == NUL
- && virt_pos >= virt_text.size) {
+ if (VCOL_HLC >= rightmost_vcol) {
break;
}
- vcol += cells;
+ vcol += 1;
}
}
@@ -4392,7 +4357,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
xfree(p_extra_free);
- xfree(err_text);
return row;
}
@@ -4400,13 +4364,17 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
{
DecorState *state = &decor_state;
int right_pos = max_col;
+ bool do_eol = state->eol_col > -1;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
if (item->start_row == state->row && kv_size(item->decor.virt_text)) {
if (item->win_col == -1) {
if (item->decor.virt_text_pos == kVTRightAlign) {
- right_pos -= item->decor.col;
+ right_pos -= item->decor.virt_text_width;
item->win_col = right_pos;
+ } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ item->win_col = state->eol_col;
+ state->eol_col += item->decor.virt_text_width;
} else if (item->decor.virt_text_pos == kVTWinCol) {
item->win_col = MAX(item->decor.col+col_off, 0);
}
@@ -4424,14 +4392,20 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
while (col < max_col) {
if (!*s.p) {
- if (virt_pos == kv_size(vt)) {
+ if (virt_pos >= kv_size(vt)) {
+ break;
+ }
+ virt_attr = 0;
+ do {
+ s.p = kv_A(vt, virt_pos).text;
+ int hl_id = kv_A(vt, virt_pos).hl_id;
+ virt_attr = hl_combine_attr(virt_attr,
+ hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ virt_pos++;
+ } while (!s.p && virt_pos < kv_size(vt));
+ if (!s.p) {
break;
}
- s.p = kv_A(vt, virt_pos).text;
- int hl_id = kv_A(vt, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- continue;
}
int attr;
bool through = false;
@@ -6786,8 +6760,8 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
// Show the current mode and ruler.
//
-// If clear_cmdline is TRUE, clear the rest of the cmdline.
-// If clear_cmdline is FALSE there may be a message there that needs to be
+// If clear_cmdline is true, clear the rest of the cmdline.
+// If clear_cmdline is false there may be a message there that needs to be
// cleared only if a mode is shown.
// Return the length of the message (0 if no message).
int showmode(void)
@@ -6796,7 +6770,6 @@ int showmode(void)
int length = 0;
int do_mode;
int attr;
- int nwr_save;
int sub_attr;
if (ui_has(kUIMessages) && clear_cmdline) {
@@ -6818,11 +6791,11 @@ int showmode(void)
// Call char_avail() only when we are going to show something, because
// it takes a bit of time.
if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
return 0;
}
- nwr_save = need_wait_return;
+ bool nwr_save = need_wait_return;
/* wait a bit before overwriting an important message */
check_for_delay(FALSE);
@@ -6939,10 +6912,11 @@ int showmode(void)
need_clear = true;
}
- mode_displayed = TRUE;
- if (need_clear || clear_cmdline)
+ mode_displayed = true;
+ if (need_clear || clear_cmdline) {
msg_clr_eos();
- msg_didout = FALSE; /* overwrite this message */
+ }
+ msg_didout = false; // overwrite this message
length = msg_col;
msg_col = 0;
msg_no_more = false;
@@ -7198,7 +7172,7 @@ void draw_tabline(void)
/* Reset the flag here again, in case evaluating 'tabline' causes it to be
* set. */
- redraw_tabline = FALSE;
+ redraw_tabline = false;
}
void ui_ext_tabline_update(void)
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 4ec5f4f74d..e5d545b185 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -137,7 +137,7 @@ search_regcomp(
int magic;
int i;
- rc_did_emsg = FALSE;
+ rc_did_emsg = false;
magic = p_magic;
/*
@@ -153,7 +153,7 @@ search_regcomp(
EMSG(_(e_nopresub));
else
EMSG(_(e_noprevre));
- rc_did_emsg = TRUE;
+ rc_did_emsg = true;
return FAIL;
}
pat = spats[i].pat;
@@ -3110,7 +3110,7 @@ current_word(
inc_cursor();
if (VIsual_mode == 'V') {
VIsual_mode = 'v';
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
}
} else
oap->inclusive = inclusive;
@@ -4105,7 +4105,7 @@ bool current_quote(
}
if (VIsual_mode == 'V') {
VIsual_mode = 'v';
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
}
} else {
/* Set inclusive and other oap's flags. */
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 0597f392e7..15271e831c 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -3945,7 +3945,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
msg_start();
msg_puts(_(msg_compressing));
msg_clr_eos();
- msg_didout = FALSE;
+ msg_didout = false;
msg_col = 0;
ui_flush();
}
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 437cb0db47..02d63d8ab1 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -144,6 +144,9 @@ char *get_mode(void)
buf[0] = (char)(VIsual_mode + 's' - 'v');
} else {
buf[0] = (char)VIsual_mode;
+ if (restart_VIsual_select) {
+ buf[1] = 's';
+ }
}
} else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
|| State == CONFIRM) {
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 6347d83626..d9089eb821 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -3417,16 +3417,6 @@ static void syn_cmd_on(exarg_T *eap, int syncing)
}
/*
- * Handle ":syntax enable" command.
- */
-static void syn_cmd_enable(exarg_T *eap, int syncing)
-{
- set_internal_string_var("syntax_cmd", (char_u *)"enable");
- syn_cmd_onoff(eap, "syntax");
- do_unlet(S_LEN("g:syntax_cmd"), true);
-}
-
-/*
* Handle ":syntax reset" command.
* It actually resets highlighting, not syntax.
*/
@@ -3434,9 +3424,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing)
{
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
- set_internal_string_var("syntax_cmd", (char_u *)"reset");
- do_cmdline_cmd("runtime! syntax/syncolor.vim");
- do_unlet(S_LEN("g:syntax_cmd"), true);
+ init_highlight(true, true);
}
}
@@ -3475,7 +3463,7 @@ void syn_maybe_enable(void)
exarg_T ea;
ea.arg = (char_u *)"";
ea.skip = false;
- syn_cmd_enable(&ea, false);
+ syn_cmd_on(&ea, false);
}
}
@@ -5534,7 +5522,7 @@ static struct subcommand subcommands[] =
{ "clear", syn_cmd_clear },
{ "cluster", syn_cmd_cluster },
{ "conceal", syn_cmd_conceal },
- { "enable", syn_cmd_enable },
+ { "enable", syn_cmd_on },
{ "foldlevel", syn_cmd_foldlevel },
{ "include", syn_cmd_include },
{ "iskeyword", syn_cmd_iskeyword },
@@ -6057,6 +6045,34 @@ static const char *highlight_init_both[] = {
"RedrawDebugClear ctermbg=Yellow guibg=Yellow",
"RedrawDebugComposed ctermbg=Green guibg=Green",
"RedrawDebugRecompose ctermbg=Red guibg=Red",
+ "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE "
+ "guifg=White guibg=Red",
+ "Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE "
+ "guifg=Blue guibg=Yellow",
+ "default link String Constant",
+ "default link Character Constant",
+ "default link Number Constant",
+ "default link Boolean Constant",
+ "default link Float Number",
+ "default link Function Identifier",
+ "default link Conditional Statement",
+ "default link Repeat Statement",
+ "default link Label Statement",
+ "default link Operator Statement",
+ "default link Keyword Statement",
+ "default link Exception Statement",
+ "default link Include PreProc",
+ "default link Define PreProc",
+ "default link Macro PreProc",
+ "default link PreCondit PreProc",
+ "default link StorageClass Type",
+ "default link Structure Type",
+ "default link Typedef Type",
+ "default link Tag Special",
+ "default link SpecialChar Special",
+ "default link Delimiter Special",
+ "default link SpecialComment Special",
+ "default link Debug Special",
NULL
};
@@ -6090,6 +6106,24 @@ static const char *highlight_init_light[] = {
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
+ "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE "
+ "gui=NONE guifg=Blue guibg=NONE",
+ "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE "
+ "gui=NONE guifg=Magenta guibg=NONE",
+ "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE "
+ "gui=NONE guifg=#6a5acd guibg=NONE",
+ "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE "
+ "gui=NONE guifg=DarkCyan guibg=NONE",
+ "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE "
+ "gui=bold guifg=Brown guibg=NONE",
+ "PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE "
+ "gui=NONE guifg=#6a0dad guibg=NONE",
+ "Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE "
+ "gui=bold guifg=SeaGreen guibg=NONE",
+ "Underlined term=underline cterm=underline ctermfg=DarkMagenta "
+ "gui=underline guifg=SlateBlue",
+ "Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE "
+ "gui=NONE guifg=bg guibg=NONE",
NULL
};
@@ -6123,6 +6157,24 @@ static const char *highlight_init_dark[] = {
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
+ "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE "
+ "gui=NONE guifg=#80a0ff guibg=NONE",
+ "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE "
+ "gui=NONE guifg=#ffa0a0 guibg=NONE",
+ "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE "
+ "gui=NONE guifg=Orange guibg=NONE",
+ "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE "
+ "gui=NONE guifg=#40ffff guibg=NONE",
+ "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE "
+ "gui=bold guifg=#ffff60 guibg=NONE",
+ "PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE "
+ "gui=NONE guifg=#ff80ff guibg=NONE",
+ "Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE "
+ "gui=bold guifg=#60ff60 guibg=NONE",
+ "Underlined term=underline cterm=underline ctermfg=LightBlue "
+ "gui=underline guifg=#80a0ff",
+ "Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE "
+ "gui=NONE guifg=bg guibg=NONE",
NULL
};
@@ -6398,20 +6450,6 @@ void init_highlight(bool both, bool reset)
}
}
- /*
- * If syntax highlighting is enabled load the highlighting for it.
- */
- if (get_var_value("g:syntax_on") != NULL) {
- static int recursive = 0;
-
- if (recursive >= 5) {
- EMSG(_("E679: recursive loop loading syncolor.vim"));
- } else {
- recursive++;
- (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL);
- recursive--;
- }
- }
syn_init_cmdline_highlight(false, false);
}
@@ -7703,7 +7741,7 @@ void highlight_changed(void)
int id_SNC = 0;
int hlcnt;
- need_highlight_changed = FALSE;
+ need_highlight_changed = false;
/// Translate builtin highlight groups into attributes for quick lookup.
for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index a236adee06..d6c6b064b2 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -2611,7 +2611,6 @@ static int jumpto_tag(
int keep_help // keep help flag (FALSE for cscope)
)
{
- int save_secure;
int save_magic;
bool save_p_ws;
int save_p_scs, save_p_ic;
@@ -2766,9 +2765,6 @@ static int jumpto_tag(
curwin->w_set_curswant = true;
postponed_split = 0;
- save_secure = secure;
- secure = 1;
- ++sandbox;
save_magic = p_magic;
p_magic = false; // always execute with 'nomagic'
// Save value of no_hlsearch, jumping to a tag is not a real search
@@ -2866,21 +2862,26 @@ static int jumpto_tag(
* of the line. May need to correct that here. */
check_cursor();
} else {
- curwin->w_cursor.lnum = 1; /* start command in line 1 */
+ const int save_secure = secure;
+
+ // Setup the sandbox for executing the command from the tags file.
+ secure = 1;
+ sandbox++;
+ curwin->w_cursor.lnum = 1; // start command in line 1
do_cmdline_cmd((char *)pbuf);
retval = OK;
+
+ // When the command has done something that is not allowed make sure
+ // the error message can be seen.
+ if (secure == 2) {
+ wait_return(true);
+ }
+ secure = save_secure;
+ sandbox--;
}
- /*
- * When the command has done something that is not allowed make sure
- * the error message can be seen.
- */
- if (secure == 2)
- wait_return(TRUE);
- secure = save_secure;
p_magic = save_magic;
- --sandbox;
- /* restore no_hlsearch when keeping the old search pattern */
+ // restore no_hlsearch when keeping the old search pattern
if (search_options) {
set_no_hlsearch(save_no_hlsearch);
}
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index b5c50b5894..cc767a9bcf 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -7,6 +7,7 @@ source test_cd.vim
source test_changedtick.vim
source test_compiler.vim
source test_cursor_func.vim
+source test_cursorline.vim
source test_ex_equal.vim
source test_ex_undo.vim
source test_ex_z.vim
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
index 770ed55b8d..02a23bf82f 100644
--- a/src/nvim/testdir/test_cd.vim
+++ b/src/nvim/testdir/test_cd.vim
@@ -1,4 +1,7 @@
-" Test for :cd
+" Test for :cd and chdir()
+
+source shared.vim
+source check.vim
func Test_cd_large_path()
" This used to crash with a heap write overflow.
@@ -65,3 +68,18 @@ func Test_cd_with_cpo_chdir()
set cpo&
bw!
endfunc
+
+func Test_cd_from_non_existing_dir()
+ CheckNotMSWindows
+
+ let saveddir = getcwd()
+ call mkdir('Xdeleted_dir')
+ cd Xdeleted_dir
+ call delete(saveddir .. '/Xdeleted_dir', 'd')
+
+ " Expect E187 as the current directory was deleted.
+ call assert_fails('pwd', 'E187:')
+ call assert_equal('', getcwd())
+ cd -
+ call assert_equal(saveddir, getcwd())
+endfunc
diff --git a/src/nvim/testdir/test_cursorline.vim b/src/nvim/testdir/test_cursorline.vim
new file mode 100644
index 0000000000..46fbd0cd64
--- /dev/null
+++ b/src/nvim/testdir/test_cursorline.vim
@@ -0,0 +1,108 @@
+" Test for cursorline and cursorlineopt
+"
+source view_util.vim
+source check.vim
+
+function! s:screen_attr(lnum) abort
+ return map(range(1, 8), 'screenattr(a:lnum, v:val)')
+endfunction
+
+function! s:test_windows(h, w) abort
+ call NewWindow(a:h, a:w)
+endfunction
+
+function! s:close_windows() abort
+ call CloseWindow()
+endfunction
+
+function! s:new_hi() abort
+ redir => save_hi
+ silent! hi CursorLineNr
+ redir END
+ let save_hi = join(split(substitute(save_hi, '\s*xxx\s*', ' ', ''), "\n"), '')
+ exe 'hi' save_hi 'ctermbg=0 guibg=Black'
+ return save_hi
+endfunction
+
+func Test_cursorline_highlight1()
+ let save_hi = s:new_hi()
+ try
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10))
+ redraw
+ let attr01 = s:screen_attr(1)
+ call assert_equal(repeat([attr01[0]], 8), attr01)
+
+ setl number numberwidth=4
+ redraw
+ let attr11 = s:screen_attr(1)
+ call assert_equal(repeat([attr11[0]], 4), attr11[0:3])
+ call assert_equal(repeat([attr11[4]], 4), attr11[4:7])
+ call assert_notequal(attr11[0], attr11[4])
+
+ setl cursorline
+ redraw
+ let attr21 = s:screen_attr(1)
+ let attr22 = s:screen_attr(2)
+ call assert_equal(repeat([attr21[0]], 4), attr21[0:3])
+ call assert_equal(repeat([attr21[4]], 4), attr21[4:7])
+ call assert_equal(attr11, attr22)
+ call assert_notequal(attr22, attr21)
+
+ setl nocursorline relativenumber
+ redraw
+ let attr31 = s:screen_attr(1)
+ call assert_equal(attr21[0:3], attr31[0:3])
+ call assert_equal(attr11[4:7], attr31[4:7])
+
+ call s:close_windows()
+ finally
+ exe 'hi' save_hi
+ endtry
+endfunc
+
+func Test_cursorline_highlight2()
+ CheckOption cursorlineopt
+
+ let save_hi = s:new_hi()
+ try
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10))
+ redraw
+ let attr0 = s:screen_attr(1)
+ call assert_equal(repeat([attr0[0]], 8), attr0)
+
+ setl number
+ redraw
+ let attr1 = s:screen_attr(1)
+ call assert_notequal(attr0[0:3], attr1[0:3])
+ call assert_equal(attr0[0:3], attr1[4:7])
+
+ setl cursorline cursorlineopt=both
+ redraw
+ let attr2 = s:screen_attr(1)
+ call assert_notequal(attr1[0:3], attr2[0:3])
+ call assert_notequal(attr1[4:7], attr2[4:7])
+
+ setl cursorlineopt=line
+ redraw
+ let attr3 = s:screen_attr(1)
+ call assert_equal(attr1[0:3], attr3[0:3])
+ call assert_equal(attr2[4:7], attr3[4:7])
+
+ setl cursorlineopt=number
+ redraw
+ let attr4 = s:screen_attr(1)
+ call assert_equal(attr2[0:3], attr4[0:3])
+ call assert_equal(attr1[4:7], attr4[4:7])
+
+ setl nonumber
+ redraw
+ let attr5 = s:screen_attr(1)
+ call assert_equal(attr0, attr5)
+
+ call s:close_windows()
+ finally
+ exe 'hi' save_hi
+ endtry
+endfunc
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 224ca257ab..48f97be96b 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -534,6 +534,7 @@ func Test_mode()
set complete=.
inoremap <F2> <C-R>=Save_mode()<CR>
+ xnoremap <F2> <Cmd>call Save_mode()<CR>
normal! 3G
exe "normal i\<F2>\<Esc>"
@@ -645,6 +646,14 @@ func Test_mode()
call assert_equal("\<C-S>", mode(1))
call feedkeys("\<Esc>", 'xt')
+ " v_CTRL-O
+ exe "normal gh\<C-O>\<F2>\<Esc>"
+ call assert_equal("v-vs", g:current_modes)
+ exe "normal gH\<C-O>\<F2>\<Esc>"
+ call assert_equal("V-Vs", g:current_modes)
+ exe "normal g\<C-H>\<C-O>\<F2>\<Esc>"
+ call assert_equal("\<C-V>-\<C-V>s", g:current_modes)
+
call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt')
call assert_equal('c-c', g:current_modes)
call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt')
@@ -653,6 +662,7 @@ func Test_mode()
bwipe!
iunmap <F2>
+ xunmap <F2>
set complete&
endfunc
@@ -996,6 +1006,9 @@ func Test_Executable()
if catcmd =~ '\<sbin\>' && result =~ '\<bin\>'
call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result)
else
+ " /bin/cat and /usr/bin/cat may be hard linked, we could get either
+ let result = substitute(result, '/usr/bin/cat', '/bin/cat', '')
+ let catcmd = substitute(catcmd, 'usr/bin/cat', 'bin/cat', '')
call assert_equal('/' .. catcmd, result)
endif
bwipe
@@ -1315,7 +1328,15 @@ endfunc
func Test_getchar()
call feedkeys('a', '')
call assert_equal(char2nr('a'), getchar())
+ call assert_equal(0, getchar(0))
+ call assert_equal(0, getchar(1))
+
+ call feedkeys('a', '')
+ call assert_equal('a', getcharstr())
+ call assert_equal('', getcharstr(0))
+ call assert_equal('', getcharstr(1))
+ call setline(1, 'xxxx')
" call test_setmouse(1, 3)
" let v:mouse_win = 9
" let v:mouse_winid = 9
@@ -1328,6 +1349,7 @@ func Test_getchar()
call assert_equal(win_getid(1), v:mouse_winid)
call assert_equal(1, v:mouse_lnum)
call assert_equal(3, v:mouse_col)
+ enew!
endfunc
func Test_libcall_libcallnr()
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index 4026f2bf98..fbe764bbf2 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -287,6 +287,29 @@ func Test_mksession_blank_windows()
call delete('Xtest_mks.out')
endfunc
+func Test_mksession_buffer_count()
+ set hidden
+
+ " Edit exactly three files in the current session.
+ %bwipe!
+ e Xfoo | tabe Xbar | tabe Xbaz
+ tabdo write
+ mksession! Xtest_mks.out
+
+ " Verify that loading the session does not create additional buffers.
+ %bwipe!
+ source Xtest_mks.out
+ call assert_equal(3, len(getbufinfo()))
+
+ " Clean up.
+ call delete('Xfoo')
+ call delete('Xbar')
+ call delete('Xbaz')
+ call delete('Xtest_mks.out')
+ %bwipe!
+ set hidden&
+endfunc
+
if has('extra_search')
func Test_mksession_hlsearch()
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index c0b9dd7696..5090584e41 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -134,6 +134,21 @@ func XlistTests(cchar)
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+ " Ranged entries
+ call g:Xsetlist([{'lnum':10,'text':'Line1'},
+ \ {'lnum':20,'col':10,'text':'Line2'},
+ \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
+ \ {'lnum':40,'end_lnum':45,'text':'Line4'},
+ \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
+ \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
+ let l = split(execute('Xlist', ""), "\n")
+ call assert_equal([' 1:10: Line1',
+ \ ' 2:20 col 10: Line2',
+ \ ' 3:30 col 15-20: Line3',
+ \ ' 4:40-45: Line4',
+ \ ' 5:50-55 col 15: Line5',
+ \ ' 6:60-65 col 25-35: Line6'], l)
+
" Different types of errors
call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
\ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
@@ -599,6 +614,7 @@ func s:test_xhelpgrep(cchar)
call assert_true(&buftype == 'help')
call assert_true(winnr() == 1)
call assert_true(winnr('$') == 2)
+ call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
" This wipes out the buffer, make sure that doesn't cause trouble.
Xclose
@@ -1437,10 +1453,13 @@ func SetXlistTests(cchar, bnum)
call s:setup_commands(a:cchar)
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
- \ {'bufnr': a:bnum, 'lnum': 2}])
+ \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(2, l[1].lnum)
+ call assert_equal(3, l[1].end_lnum)
+ call assert_equal(4, l[1].col)
+ call assert_equal(5, l[1].end_col)
Xnext
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
@@ -2743,7 +2762,9 @@ func XvimgrepTests(cchar)
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(8, l[0].col)
+ call assert_equal(11, l[0].end_col)
call assert_equal(12, l[1].col)
+ call assert_equal(15, l[1].end_col)
1Xvimgrep ?Editor? Xtestfile*
let l = g:Xgetlist()
@@ -4850,7 +4871,42 @@ func Test_add_invalid_entry_with_qf_window()
call setqflist(['bb'], 'a')
call assert_equal(1, line('$'))
call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
- call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
cclose
endfunc
@@ -5001,15 +5057,21 @@ func Xtest_qftextfunc(cchar)
call assert_equal('Tqfexpr', &quickfixtextfunc)
call assert_equal('',
\ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
- Xexpr ['F1:10:2:green', 'F1:20:4:blue']
+ call g:Xsetlist([
+ \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
+ \ 'end_col': 7, 'text': 'green'},
+ \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
+ \ 'end_col': 8, 'text': 'blue'},
+ \ ])
+
Xwindow
call assert_equal('F1-L10C2-green', getline(1))
call assert_equal('F1-L20C4-blue', getline(2))
Xclose
set quickfixtextfunc&vim
Xwindow
- call assert_equal('F1|10 col 2| green', getline(1))
- call assert_equal('F1|20 col 4| blue', getline(2))
+ call assert_equal('F1|10 col 2-7| green', getline(1))
+ call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Xclose
set efm&
set quickfixtextfunc&
@@ -5196,4 +5258,54 @@ func Test_qftextfunc_other_loclist()
%bw!
endfunc
+func Test_locationlist_open_in_newtab()
+ call s:create_test_file('Xqftestfile1')
+ call s:create_test_file('Xqftestfile2')
+ call s:create_test_file('Xqftestfile3')
+
+ %bwipe!
+
+ lgetexpr ['Xqftestfile1:5:Line5',
+ \ 'Xqftestfile2:10:Line10',
+ \ 'Xqftestfile3:16:Line16']
+
+ silent! llast
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('Xqftestfile3', bufname())
+
+ set switchbuf=newtab
+
+ silent! lfirst
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal('Xqftestfile1', bufname())
+
+ silent! lnext
+ call assert_equal(3, tabpagenr('$'))
+ call assert_equal('Xqftestfile2', bufname())
+
+ call delete('Xqftestfile1')
+ call delete('Xqftestfile2')
+ call delete('Xqftestfile3')
+ set switchbuf&vim
+
+ %bwipe!
+endfunc
+
+" Test for win_gettype() in quickfix and location list windows
+func Test_win_gettype()
+ copen
+ call assert_equal("quickfix", win_gettype())
+ let wid = win_getid()
+ wincmd p
+ call assert_equal("quickfix", win_gettype(wid))
+ cclose
+ lexpr ''
+ lopen
+ call assert_equal("loclist", win_gettype())
+ let wid = win_getid()
+ wincmd p
+ call assert_equal("loclist", win_gettype(wid))
+ lclose
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_spellfile.vim b/src/nvim/testdir/test_spellfile.vim
index 729467b556..0f48ab8f6f 100644
--- a/src/nvim/testdir/test_spellfile.vim
+++ b/src/nvim/testdir/test_spellfile.vim
@@ -210,6 +210,52 @@ func Test_spellfile_CHECKCOMPOUNDPATTERN()
call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl')
endfunc
+" Test NOCOMPOUNDSUGS (see :help spell-NOCOMPOUNDSUGS)
+func Test_spellfile_NOCOMPOUNDSUGS()
+ call writefile(['3',
+ \ 'one/c',
+ \ 'two/c',
+ \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic')
+
+ " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS
+ for pass in [0, 1]
+ if pass == 0
+ call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
+ else
+ call writefile(['NOCOMPOUNDSUGS',
+ \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
+ endif
+
+ mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS
+ set spell spelllang=XtestNOCOMPOUNDSUGS-utf8.spl
+
+ for goodword in ['one', 'two', 'three',
+ \ 'oneone', 'onetwo', 'onethree',
+ \ 'twoone', 'twotwo', 'twothree',
+ \ 'threeone', 'threetwo', 'threethree',
+ \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
+ call assert_equal(['', ''], spellbadword(goodword), goodword)
+ endfor
+
+ for badword in ['four', 'onetwox', 'onexone']
+ call assert_equal([badword, 'bad'], spellbadword(badword))
+ endfor
+
+ if pass == 0
+ call assert_equal(['one', 'oneone'], spellsuggest('onne', 2))
+ call assert_equal(['onethree', 'one three'], spellsuggest('onethre', 2))
+ else
+ call assert_equal(['one', 'one one'], spellsuggest('onne', 2))
+ call assert_equal(['one three'], spellsuggest('onethre', 2))
+ endif
+ endfor
+
+ set spell& spelllang&
+ call delete('XtestNOCOMPOUNDSUGS.dic')
+ call delete('XtestNOCOMPOUNDSUGS.aff')
+ call delete('XtestNOCOMPOUNDSUGS-utf8.spl')
+endfunc
+
" Test COMMON (better suggestions with common words, see :help spell-COMMON)
func Test_spellfile_COMMON()
call writefile(['7',
diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim
index 3c191cd7c7..02bc297de1 100644
--- a/src/nvim/testdir/test_swap.vim
+++ b/src/nvim/testdir/test_swap.vim
@@ -376,4 +376,8 @@ func Test_swap_symlink()
call delete('Xswapdir', 'rf')
endfunc
+func Test_no_swap_file()
+ call assert_equal("\nNo swap file", execute('swapname'))
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index 9f02af7d8e..68dcfb6890 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -771,15 +771,16 @@ func Test_ltag()
ltag third
call assert_equal('Xfoo', bufname(''))
call assert_equal(3, line('.'))
- call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0,
- \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '',
- \ 'module': '', 'text': 'third'}], getloclist(0))
+ call assert_equal([{'lnum': 3, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+ \ 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0,
+ \ 'nr': 0, 'type': '', 'module': '', 'text': 'third'}], getloclist(0))
ltag second
call assert_equal(2, line('.'))
- call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0,
- \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0,
- \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0))
+ call assert_equal([{'lnum': 0, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+ \ 'col': 0, 'end_col': 0, 'pattern': '^\Vint second() {}\$',
+ \ 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'module': '',
+ \ 'text': 'second'}], getloclist(0))
call delete('Xtags')
call delete('Xfoo')
diff --git a/src/nvim/window.c b/src/nvim/window.c
index d0bee83db1..0856e75758 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2275,8 +2275,8 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
* Don't trigger autocommands yet, they may use wrong values, so do
* that below.
*/
- goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
- redraw_tabline = TRUE;
+ goto_tabpage_tp(alt_tabpage(), false, true);
+ redraw_tabline = true;
// save index for tabclosed event
char_u prev_idx[NUMBUFLEN];
@@ -3834,18 +3834,15 @@ int tabpage_index(tabpage_T *ftp)
return i;
}
-/*
- * Prepare for leaving the current tab page.
- * When autocommands change "curtab" we don't leave the tab page and return
- * FAIL.
- * Careful: When OK is returned need to get a new tab page very very soon!
- */
-static int
-leave_tabpage (
- buf_T *new_curbuf, /* what is going to be the new curbuf,
- NULL if unknown */
- int trigger_leave_autocmds
-)
+/// Prepare for leaving the current tab page.
+/// When autocommands change "curtab" we don't leave the tab page and return
+/// FAIL.
+/// Careful: When OK is returned need to get a new tab page very very soon!
+///
+/// @param new_curbuf what is going to be the new curbuf,
+/// NULL if unknown.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds)
{
tabpage_T *tp = curtab;
@@ -3874,13 +3871,14 @@ leave_tabpage (
return OK;
}
-/*
- * Start using tab page "tp".
- * Only to be used after leave_tabpage() or freeing the current tab page.
- * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
- * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
- */
-static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds)
+/// Start using tab page "tp".
+/// Only to be used after leave_tabpage() or freeing the current tab page.
+///
+/// @param trigger_enter_autocmds when true trigger *Enter autocommands.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf,
+ bool trigger_enter_autocmds,
+ bool trigger_leave_autocmds)
{
int old_off = tp->tp_firstwin->w_winrow;
win_T *next_prevwin = tp->tp_prevwin;
@@ -4023,17 +4021,16 @@ void goto_tabpage(int n)
}
}
- goto_tabpage_tp(tp, TRUE, TRUE);
-
+ goto_tabpage_tp(tp, true, true);
}
-/*
- * Go to tabpage "tp".
- * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
- * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
- * Note: doesn't update the GUI tab.
- */
-void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leave_autocmds)
+/// Go to tabpage "tp".
+/// Note: doesn't update the GUI tab.
+///
+/// @param trigger_enter_autocmds when true trigger *Enter autocommands.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds,
+ bool trigger_leave_autocmds)
{
/* Don't repeat a message in another tab page. */
set_keep_msg(NULL, 0);
@@ -4064,7 +4061,7 @@ void goto_tabpage_lastused(void)
*/
void goto_tabpage_win(tabpage_T *tp, win_T *wp)
{
- goto_tabpage_tp(tp, TRUE, TRUE);
+ goto_tabpage_tp(tp, true, true);
if (curtab == tp && win_valid(wp)) {
win_enter(wp, true);
}
@@ -4120,8 +4117,8 @@ void tabpage_move(int nr)
tp_dst->tp_next = curtab;
}
- /* Need to redraw the tabline. Tab page contents doesn't change. */
- redraw_tabline = TRUE;
+ // Need to redraw the tabline. Tab page contents doesn't change.
+ redraw_tabline = true;
}
@@ -4350,8 +4347,8 @@ void win_enter(win_T *wp, bool undo_sync)
* been closed and isn't valid.
*/
static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
- int trigger_new_autocmds, int trigger_enter_autocmds,
- int trigger_leave_autocmds)
+ int trigger_new_autocmds, bool trigger_enter_autocmds,
+ bool trigger_leave_autocmds)
{
int other_buffer = FALSE;
@@ -4665,6 +4662,7 @@ win_free (
// If there already is an entry with "wi_win" set to NULL it
// must be removed, it would never be used.
+ // Skip "wip" itself, otherwise Coverity complains.
for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) {
// `wip2 != wip` to satisfy Coverity. #14884
if (wip2 != wip && wip2->wi_win == NULL) {
@@ -5907,13 +5905,13 @@ void command_height(void)
grid_fill(&default_grid, cmdline_row, Rows, 0, Columns, ' ', ' ', 0);
}
msg_row = cmdline_row;
- redraw_cmdline = TRUE;
+ redraw_cmdline = true;
return;
}
if (msg_row < cmdline_row)
msg_row = cmdline_row;
- redraw_cmdline = TRUE;
+ redraw_cmdline = true;
}
frame_add_height(frp, (int)(old_p_ch - p_ch));
@@ -6434,8 +6432,9 @@ int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab,
curtab = tp;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
- } else
- goto_tabpage_tp(tp, FALSE, FALSE);
+ } else {
+ goto_tabpage_tp(tp, false, false);
+ }
}
if (!win_valid(win)) {
return FAIL;
@@ -6465,8 +6464,9 @@ void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab,
curtab = save_curtab;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
- } else
- goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ } else {
+ goto_tabpage_tp(save_curtab, false, false);
+ }
}
if (win_valid(save_curwin)) {
curwin = save_curwin;
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index 949724bb53..09eaa36686 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -43,7 +43,7 @@ describe(':mksession', function()
-- Restore session.
command('source '..session_file)
- eq({3,3,2},
+ eq({2,2,4},
{funcs.winbufnr(1), funcs.winbufnr(2), funcs.winbufnr(3)})
end)
@@ -91,7 +91,12 @@ describe(':mksession', function()
command('tabnext 1')
eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', funcs.expand('%:p'))
command('tabnext 2')
- eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p'))
+ -- :mksession stores paths using unix slashes, but Nvim doesn't adjust these
+ -- for absolute paths in all cases yet. Absolute paths are used in the
+ -- session file after :tcd, so we need to expect unix slashes here for now
+ -- eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p'))
+ eq(cwd_dir:gsub([[\]], '/') .. '/' .. tmpfile_base .. '2',
+ funcs.expand('%:p'))
end)
it('restores CWD for :terminal buffers #11288', function()
diff --git a/test/functional/ex_cmds/quickfix_commands_spec.lua b/test/functional/ex_cmds/quickfix_commands_spec.lua
index 3392a90270..06dafa9ab9 100644
--- a/test/functional/ex_cmds/quickfix_commands_spec.lua
+++ b/test/functional/ex_cmds/quickfix_commands_spec.lua
@@ -37,9 +37,9 @@ for _, c in ipairs({'l', 'c'}) do
-- Second line of each entry (i.e. `nr=-1, …`) was obtained from actual
-- results. First line (i.e. `{lnum=…`) was obtained from legacy test.
local list = {
- {lnum=700, col=10, text='Line 700', module='',
+ {lnum=700, end_lnum=0, col=10, end_col=0, text='Line 700', module='',
nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''},
- {lnum=800, col=15, text='Line 800', module='',
+ {lnum=800, end_lnum=0, col=15, end_col=0, text='Line 800', module='',
nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''},
}
eq(list, getlist())
@@ -58,7 +58,7 @@ for _, c in ipairs({'l', 'c'}) do
]]):format(file))
command(('%s %s'):format(addfcmd, file))
list[#list + 1] = {
- lnum=900, col=30, text='Line 900', module='',
+ lnum=900, end_lnum=0, col=30, end_col=0, text='Line 900', module='',
nr=-1, bufnr=5, valid=1, pattern='', vcol=0, ['type']='',
}
eq(list, getlist())
@@ -71,9 +71,9 @@ for _, c in ipairs({'l', 'c'}) do
command('enew!')
command(('%s %s'):format(getfcmd, file))
list = {
- {lnum=222, col=77, text='Line 222', module='',
+ {lnum=222, end_lnum=0, col=77, end_col=0, text='Line 222', module='',
nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''},
- {lnum=333, col=88, text='Line 333', module='',
+ {lnum=333, end_lnum=0, col=88, end_col=0, text='Line 333', module='',
nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''},
}
eq(list, getlist())
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index e5533af73b..b77a285379 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -2026,7 +2026,9 @@ describe('LSP', function()
local expected = { {
bufnr = 2,
col = 5,
+ end_col = 0,
lnum = 4,
+ end_lnum = 0,
module = "",
nr = 0,
pattern = "",
@@ -2098,7 +2100,9 @@ describe('LSP', function()
local expected = { {
bufnr = 2,
col = 5,
+ end_col = 0,
lnum = 4,
+ end_lnum = 0,
module = "",
nr = 0,
pattern = "",
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
index af709cd521..16ed3b9486 100644
--- a/test/functional/ui/bufhl_spec.lua
+++ b/test/functional/ui/bufhl_spec.lua
@@ -858,8 +858,8 @@ describe('Buffer highlighting', function()
it('works with cursorline', function()
command("set cursorline")
- screen:expect([[
- {14:^1 + 2 }{15:=}{16: 3}{14: }|
+ screen:expect{grid=[[
+ {14:^1 + 2 }{3:=}{2: 3}{14: }|
3 + {11:ERROR:} invalid syntax |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5|
, 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s|
@@ -867,32 +867,32 @@ describe('Buffer highlighting', function()
{1:~ }|
{1:~ }|
|
- ]])
+ ]]}
feed('j')
- screen:expect([[
+ screen:expect{grid=[[
1 + 2 {3:=}{2: 3} |
- {14:^3 + }{11:ERROR:}{14: invalid syntax }|
+ {14:^3 + }{11:ERROR:} invalid syntax{14: }|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5|
, 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s|
x = 4 |
{1:~ }|
{1:~ }|
|
- ]])
+ ]]}
feed('j')
- screen:expect([[
+ screen:expect{grid=[[
1 + 2 {3:=}{2: 3} |
3 + {11:ERROR:} invalid syntax |
{14:^5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}|
- {14:, 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s}|
+ {14:, 5, 5, 5, 5, 5, 5, }Lorem ipsum dolor s|
x = 4 |
{1:~ }|
{1:~ }|
|
- ]])
+ ]]}
end)
it('works with color column', function()
@@ -910,11 +910,11 @@ describe('Buffer highlighting', function()
command("set colorcolumn=9")
screen:expect{grid=[[
- ^1 + 2 {3:=}{2: }{17:3} |
+ ^1 + 2 {3:=}{2: 3} |
3 + {11:ERROR:} invalid syntax |
5, 5, 5,{18: }5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5|
, 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s|
- x = 4 {12:暗}{19:x}{12:事} |
+ x = 4 {12:暗x事} |
{1:~ }|
{1:~ }|
|
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 0ea8bab957..ad23402ff9 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -14,6 +14,8 @@ local function new_screen(opt)
[3] = {bold = true, reverse = true},
[4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
[5] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [6] = {foreground = Screen.colors.Magenta},
+ [7] = {bold = true, foreground = Screen.colors.Brown},
})
return screen
end
@@ -267,7 +269,7 @@ local function test_cmdline(linegrid)
special = {'"', true},
}, {
firstc = "=",
- content = {{"1"}, {"+"}, {"2"}},
+ content = {{"1", 6}, {"+", 7}, {"2", 6}},
pos = 3,
}}
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 98aafd8757..4373d17890 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -562,7 +562,7 @@ end]]
{5:l}{8:blen}{7:dy}{10:e}{7:text}{10:h}{7:-}{10:_}{7:here}ell, count = unpack(item) |
{5:i}{12:c}{11:ombining color} {13:nil} {5:then} |
{11:replacing color}d_cell |
- {5:e}{8:bl}{14:endy}{15:i}{14:text}{15:o}{14:-}{15:o}{14:h}{7:ere} |
+ {5:e}{8:bl}{7:endy}{10: }{7:text}{10: }{7:-}{10: }{7:here} |
{5:f}{12:co}{11:mbini}{16:n}{11:g color}t {5:or} {13:1}) {5:do} |
{11:replacing color} line[colpos] |
cell.text = text |
@@ -697,4 +697,96 @@ end]]
|
]]}
end)
+
+ it('can have virtual text which combines foreground and backround groups', function()
+ screen:set_default_attr_ids {
+ [1] = {bold=true, foreground=Screen.colors.Blue};
+ [2] = {background = tonumber('0x123456'), foreground = tonumber('0xbbbbbb')};
+ [3] = {background = tonumber('0x123456'), foreground = tonumber('0xcccccc')};
+ [4] = {background = tonumber('0x234567'), foreground = tonumber('0xbbbbbb')};
+ [5] = {background = tonumber('0x234567'), foreground = tonumber('0xcccccc')};
+ [6] = {bold = true, foreground = tonumber('0xcccccc'), background = tonumber('0x234567')};
+ }
+
+ exec [[
+ hi BgOne guibg=#123456
+ hi BgTwo guibg=#234567
+ hi FgEin guifg=#bbbbbb
+ hi FgZwei guifg=#cccccc
+ hi VeryBold gui=bold
+ ]]
+
+ meths.buf_set_extmark(0, ns, 0, 0, { virt_text={
+ {'a', {'BgOne', 'FgEin'}};
+ {'b', {'BgOne', 'FgZwei'}};
+ {'c', {'BgTwo', 'FgEin'}};
+ {'d', {'BgTwo', 'FgZwei'}};
+ {'X', {'BgTwo', 'FgZwei', 'VeryBold'}};
+ }})
+
+ screen:expect{grid=[[
+ ^ {2:a}{3:b}{4:c}{5:d}{6:X} |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('does not crash when deleting a cleared buffer #15212', function()
+ exec_lua [[
+ ns = vim.api.nvim_create_namespace("myplugin")
+ vim.api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_text = {{"a"}}, end_col = 0})
+ ]]
+ screen:expect{grid=[[
+ ^ a |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ exec_lua [[
+ vim.api.nvim_buf_clear_namespace(0, ns, 0, -1)
+ vim.cmd("bdelete")
+ ]]
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ helpers.assert_alive()
+ end)
end)
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 8992ee27ce..7471255345 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -789,7 +789,7 @@ describe("'listchars' highlight", function()
[0] = {bold=true, foreground=Screen.colors.Blue},
[1] = {background=Screen.colors.Grey90},
[2] = {foreground=Screen.colors.Red},
- [3] = {foreground=Screen.colors.Green1},
+ [3] = {foreground=Screen.colors.X11Green, background=Screen.colors.Red1},
})
feed_command('highlight clear ModeMsg')
feed_command('highlight Whitespace guifg=#FF0000')
diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua
index 06c92a4b10..741b93043d 100644
--- a/test/functional/ui/sign_spec.lua
+++ b/test/functional/ui/sign_spec.lua
@@ -176,8 +176,8 @@ describe('Signs', function()
command('sign place 5 line=3 name=pietWarn buffer=1')
command('sign place 3 line=3 name=pietError buffer=1')
screen:expect([[
- {1:>>}XX{6: 1 }a |
- XX{1:>>}{6: 2 }b |
+ {1:>>}{8:XX}{6: 1 }a |
+ {8:XX}{1:>>}{6: 2 }b |
{1:>>}WW{6: 3 }c |
{2: }{6: 4 }^ |
{0:~ }|
@@ -194,7 +194,7 @@ describe('Signs', function()
-- With the default setting, we get the sign with the top id.
command('set signcolumn=yes:1')
screen:expect([[
- XX{6: 1 }a |
+ {8:XX}{6: 1 }a |
{1:>>}{6: 2 }b |
WW{6: 3 }c |
{2: }{6: 4 }^ |
@@ -212,9 +212,9 @@ describe('Signs', function()
-- "auto:3" accommodates all the signs we defined so far.
command('set signcolumn=auto:3')
screen:expect([[
- {1:>>}XX{2: }{6: 1 }a |
- XX{1:>>}{2: }{6: 2 }b |
- XX{1:>>}WW{6: 3 }c |
+ {1:>>}{8:XX}{2: }{6: 1 }a |
+ {8:XX}{1:>>}{2: }{6: 2 }b |
+ {8:XX}{1:>>}WW{6: 3 }c |
{2: }{6: 4 }^ |
{0:~ }|
{0:~ }|
@@ -230,9 +230,9 @@ describe('Signs', function()
-- Check "yes:9".
command('set signcolumn=yes:9')
screen:expect([[
- {1:>>}XX{2: }{6: 1 }a |
- XX{1:>>}{2: }{6: 2 }b |
- XX{1:>>}WW{2: }{6: 3 }c |
+ {1:>>}{8:XX}{2: }{6: 1 }a |
+ {8:XX}{1:>>}{2: }{6: 2 }b |
+ {8:XX}{1:>>}WW{2: }{6: 3 }c |
{2: }{6: 4 }^ |
{0:~ }|
{0:~ }|
@@ -249,9 +249,9 @@ describe('Signs', function()
-- a single line (same result as "auto:3").
command('set signcolumn=auto:4')
screen:expect{grid=[[
- {1:>>}XX{2: }{6: 1 }a |
- XX{1:>>}{2: }{6: 2 }b |
- XX{1:>>}WW{6: 3 }c |
+ {1:>>}{8:XX}{2: }{6: 1 }a |
+ {8:XX}{1:>>}{2: }{6: 2 }b |
+ {8:XX}{1:>>}WW{6: 3 }c |
{2: }{6: 4 }^ |
{0:~ }|
{0:~ }|
@@ -267,8 +267,8 @@ describe('Signs', function()
-- line deletion deletes signs.
command('2d')
screen:expect([[
- {1:>>}XX{2: }{6: 1 }a |
- XX{1:>>}WW{6: 2 }^c |
+ {1:>>}{8:XX}{2: }{6: 1 }a |
+ {8:XX}{1:>>}WW{6: 2 }^c |
{2: }{6: 3 } |
{0:~ }|
{0:~ }|
diff --git a/test/unit/viml/expressions/parser_spec.lua b/test/unit/viml/expressions/parser_spec.lua
index 032baf6578..8342044b5e 100644
--- a/test/unit/viml/expressions/parser_spec.lua
+++ b/test/unit/viml/expressions/parser_spec.lua
@@ -52,6 +52,32 @@ local predefined_hl_defs = {
QuickFixLine=true,
Substitute=true,
Whitespace=true,
+ Error=true,
+ Todo=true,
+ String=true,
+ Character=true,
+ Number=true,
+ Boolean=true,
+ Float=true,
+ Function=true,
+ Conditional=true,
+ Repeat=true,
+ Label=true,
+ Operator=true,
+ Keyword=true,
+ Exception=true,
+ Include=true,
+ Define=true,
+ Macro=true,
+ PreCondit=true,
+ StorageClass=true,
+ Structure=true,
+ Typedef=true,
+ Tag=true,
+ SpecialChar=true,
+ Delimiter=true,
+ SpecialComment=true,
+ Debug=true,
-- From highlight_init_(dark|light)
ColorColumn=true,
@@ -83,8 +109,6 @@ local predefined_hl_defs = {
Visual=true,
WarningMsg=true,
Normal=true,
-
- -- From syncolor.vim, if &background
Comment=true,
Constant=true,
Special=true,
@@ -94,36 +118,6 @@ local predefined_hl_defs = {
Type=true,
Underlined=true,
Ignore=true,
-
- -- From syncolor.vim, below if &background
- Error=true,
- Todo=true,
-
- -- From syncolor.vim, links at the bottom
- String=true,
- Character=true,
- Number=true,
- Boolean=true,
- Float=true,
- Function=true,
- Conditional=true,
- Repeat=true,
- Label=true,
- Operator=true,
- Keyword=true,
- Exception=true,
- Include=true,
- Define=true,
- Macro=true,
- PreCondit=true,
- StorageClass=true,
- Structure=true,
- Typedef=true,
- Tag=true,
- SpecialChar=true,
- Delimiter=true,
- SpecialComment=true,
- Debug=true,
}
local nvim_hl_defs = {}