mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 02:34:59 -07:00
Compare commits
43 Commits
89c36f3b49
...
0905c34291
Author | SHA1 | Date | |
---|---|---|---|
|
0905c34291 | ||
|
738320188f | ||
|
38f554e9c4 | ||
|
f7c42433c5 | ||
|
51c380238c | ||
|
b7da54aa9e | ||
|
2f7b385f2e | ||
|
c830901e8c | ||
|
0dd933265f | ||
|
df367cf91c | ||
|
6bf2a6fc5b | ||
|
b03e790cdd | ||
|
15153c4cd5 | ||
|
137308a3c9 | ||
|
7d082d4816 | ||
|
59f38ef3c4 | ||
|
98e3610316 | ||
|
022449b522 | ||
|
fb8372adb3 | ||
|
47f2769b46 | ||
|
b5c0290803 | ||
|
6c975515c5 | ||
|
798f928479 | ||
|
167a2383b9 | ||
|
2d6f57b289 | ||
|
9c6a3703bb | ||
|
01a97d2ad7 | ||
|
cc38630d39 | ||
|
6c2c77b128 | ||
|
820984daea | ||
|
852b6a6bce | ||
|
805b84c619 | ||
|
3406b00911 | ||
|
caa93b5e1e | ||
|
433b342baa | ||
|
f9dd682621 | ||
|
65b1733405 | ||
|
9c20342297 | ||
|
7940ec6913 | ||
|
c0ae39ee53 | ||
|
1386d36e76 | ||
|
8a0b203875 | ||
|
1724a6e259 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -89,7 +89,9 @@ jobs:
|
||||
for d in *; do (cd "$d"; rm -rf ./autom4te.cache; make clean || true; make distclean || true); done
|
||||
|
||||
- name: Re-build bundled dependencies with no network access
|
||||
run: unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
run: |
|
||||
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||
unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
|
||||
- name: Build
|
||||
run: make CMAKE_FLAGS="-D CI_BUILD=ON"
|
||||
|
@ -1,8 +1,8 @@
|
||||
LIBUV_URL https://github.com/libuv/libuv/archive/v1.49.2.tar.gz
|
||||
LIBUV_SHA256 388ffcf3370d4cf7c4b3a3205504eea06c4be5f9e80d2ab32d19f8235accc1cf
|
||||
|
||||
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/19878ec05c239ccaf5f3d17af27670a963e25b8b.tar.gz
|
||||
LUAJIT_SHA256 e91acbe181cf6ffa3ef15870b8e620131002240ba24c5c779fd0131db021517f
|
||||
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/f73e649a954b599fc184726c376476e7a5c439ca.tar.gz
|
||||
LUAJIT_SHA256 bc992b3ae0a8f5f0ebbf141626b7c99fac794c94ec6896d973582525c7ef868d
|
||||
|
||||
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
|
||||
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||
@ -50,8 +50,8 @@ TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/a
|
||||
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
|
||||
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.3.2.tar.gz
|
||||
TREESITTER_MARKDOWN_SHA256 5dac48a6d971eb545aab665d59a18180d21963afc781bbf40f9077c06cb82ae5
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/e3c82633389256ccc2c5ab2e509046cbf20453d3.tar.gz
|
||||
TREESITTER_SHA256 61a21f5d83cfe256472bfa941123a6941fb45073784ee7ec0bc32fdd52f7a4e4
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.24.5.tar.gz
|
||||
TREESITTER_SHA256 b5ac48acf5a04fd82ccd4246ad46354d9c434be26c9606233917549711e4252c
|
||||
|
||||
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v25.0.2.tar.gz
|
||||
WASMTIME_SHA256 6d1c17c756b83f29f629963228e5fa208ba9d6578421ba2cd07132b6a120accb
|
||||
|
@ -60,6 +60,7 @@ hi('PmenuMatch', { link = 'Pmenu' })
|
||||
hi('PmenuMatchSel', { link = 'PmenuSel' })
|
||||
hi('PmenuExtra', { link = 'Pmenu' })
|
||||
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
||||
hi('ComplMatchIns', { link = 'Normal' })
|
||||
hi('Substitute', { link = 'Search' })
|
||||
hi('Whitespace', { link = 'NonText' })
|
||||
hi('MsgSeparator', { link = 'StatusLine' })
|
||||
|
@ -1647,11 +1647,9 @@ nvim_command({command}) *nvim_command()*
|
||||
|
||||
On execution error: fails with Vimscript error, updates v:errmsg.
|
||||
|
||||
Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate
|
||||
multiple lines of Vim script or an Ex command directly, use
|
||||
|nvim_exec2()|. To construct an Ex command using a structured format and
|
||||
then execute it, use |nvim_cmd()|. To modify an Ex command before
|
||||
evaluating it, use |nvim_parse_cmd()| in conjunction with |nvim_cmd()|.
|
||||
Prefer |nvim_cmd()| or |nvim_exec2()| instead. To modify an Ex command in
|
||||
a structured way before executing it, modify the result of
|
||||
|nvim_parse_cmd()| then pass it to |nvim_cmd()|.
|
||||
|
||||
Parameters: ~
|
||||
• {command} Ex command string
|
||||
|
24
runtime/doc/builtin.txt
generated
24
runtime/doc/builtin.txt
generated
@ -1305,10 +1305,10 @@ copy({expr}) *copy()*
|
||||
Also see |deepcopy()|.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {expr} (`T`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
cos({expr}) *cos()*
|
||||
Return the cosine of {expr}, measured in radians, as a |Float|.
|
||||
@ -1490,11 +1490,11 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E69
|
||||
Also see |copy()|.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {expr} (`T`)
|
||||
• {noref} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
delete({fname} [, {flags}]) *delete()*
|
||||
Without {flags} or with {flags} empty: Deletes the file by the
|
||||
@ -5281,7 +5281,7 @@ items({dict}) *items()*
|
||||
the index.
|
||||
|
||||
Parameters: ~
|
||||
• {dict} (`any`)
|
||||
• {dict} (`table`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -6567,7 +6567,7 @@ max({expr}) *max()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
menu_get({path} [, {modes}]) *menu_get()*
|
||||
Returns a |List| of |Dictionaries| describing |menus| (defined
|
||||
@ -7733,11 +7733,11 @@ reduce({object}, {func} [, {initial}]) *reduce()* *E99
|
||||
|
||||
Parameters: ~
|
||||
• {object} (`any`)
|
||||
• {func} (`function`)
|
||||
• {func} (`fun(accumulator: T, current: any): any`)
|
||||
• {initial} (`any?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
reg_executing() *reg_executing()*
|
||||
Returns the single letter name of the register being executed.
|
||||
@ -7951,10 +7951,10 @@ reverse({object}) *reverse()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {object} (`any`)
|
||||
• {object} (`T[]`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T[]`)
|
||||
|
||||
round({expr}) *round()*
|
||||
Round off {expr} to the nearest integral value and return it
|
||||
@ -9952,12 +9952,12 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E70
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {list} (`any`)
|
||||
• {list} (`T[]`)
|
||||
• {how} (`string|function?`)
|
||||
• {dict} (`any?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T[]`)
|
||||
|
||||
soundfold({word}) *soundfold()*
|
||||
Return the sound-folded equivalent of {word}. Uses the first
|
||||
|
@ -1443,18 +1443,17 @@ since formatting is highly dependent on the type of file. It makes
|
||||
sense to use an |autoload| script, so the corresponding script is only loaded
|
||||
when actually needed and the script should be called <filetype>format.vim.
|
||||
|
||||
For example, the XML filetype plugin distributed with Vim in the $VIMRUNTIME
|
||||
directory, sets the 'formatexpr' option to: >
|
||||
For example, the XML filetype plugin distributed with Vim in the
|
||||
$VIMRUNTIME/ftplugin directory, sets the 'formatexpr' option to: >
|
||||
|
||||
setlocal formatexpr=xmlformat#Format()
|
||||
|
||||
That means, you will find the corresponding script, defining the
|
||||
xmlformat#Format() function, in the directory:
|
||||
`$VIMRUNTIME/autoload/xmlformat.vim`
|
||||
xmlformat#Format() function, in the file `$VIMRUNTIME/autoload/xmlformat.vim`
|
||||
|
||||
Here is an example script that removes trailing whitespace from the selected
|
||||
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim: >
|
||||
|
||||
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim:
|
||||
>vim
|
||||
func! format#Format()
|
||||
" only reformat on explicit gq command
|
||||
if mode() != 'n'
|
||||
@ -1487,7 +1486,7 @@ debugging it helps to set the 'debug' option.
|
||||
|
||||
*right-justify*
|
||||
There is no command in Vim to right justify text. You can do it with
|
||||
an external command, like "par" (e.g.: "!}par" to format until the end of the
|
||||
an external command, like "par" (e.g.: `:.,}!par` to format until the end of the
|
||||
paragraph) or set 'formatprg' to "par".
|
||||
|
||||
*format-comments*
|
||||
@ -1553,7 +1552,7 @@ type of comment string. A part consists of:
|
||||
some indent for the start or end part that can be removed.
|
||||
|
||||
When a string has none of the 'f', 's', 'm' or 'e' flags, Vim assumes the
|
||||
comment string repeats at the start of each line. The flags field may be
|
||||
comment string repeats at the start of each line. The {flags} field may be
|
||||
empty.
|
||||
|
||||
Any blank space in the text before and after the {string} is part of the
|
||||
|
@ -38,6 +38,10 @@ DIAGNOSTICS
|
||||
- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to
|
||||
"pos"
|
||||
|
||||
HIGHLIGHTS
|
||||
• *TermCursorNC* As of Nvim 0.11, unfocused |terminal| windows no
|
||||
longer have any cursor.
|
||||
|
||||
TREESITTER
|
||||
• *TSNode:child_containing_descendant()* Use
|
||||
|TSNode:child_with_descendant()| instead; it is identical except that it can
|
||||
|
@ -82,9 +82,11 @@ The most efficient is to call a function without arguments: >
|
||||
The function must use v:lnum. See |expr-option-function|.
|
||||
|
||||
These are the conditions with which the expression is evaluated:
|
||||
|
||||
- The current buffer and window are set for the line.
|
||||
- The variable "v:lnum" is set to the line number.
|
||||
- The result is used for the fold level in this way:
|
||||
|
||||
The result of foldexpr then determines the fold level as follows:
|
||||
value meaning ~
|
||||
0 the line is not in a fold
|
||||
1, 2, .. the line is in a fold with this level
|
||||
@ -99,6 +101,9 @@ These are the conditions with which the expression is evaluated:
|
||||
"<1", "<2", .. a fold with this level ends at this line
|
||||
">1", ">2", .. a fold with this level starts at this line
|
||||
|
||||
The result values "=", "s" and "a" are more expensive, please see
|
||||
|fold-expr-slow|.
|
||||
|
||||
It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
|
||||
will also start (end) when the fold level is higher (lower) than the fold
|
||||
level of the previous line.
|
||||
@ -112,14 +117,8 @@ recognized, there is no error message and the fold level will be zero.
|
||||
For debugging the 'debug' option can be set to "msg", the error messages will
|
||||
be visible then.
|
||||
|
||||
Note: Since the expression has to be evaluated for every line, this fold
|
||||
method can be very slow!
|
||||
|
||||
Try to avoid the "=", "a" and "s" return values, since Vim often has to search
|
||||
backwards for a line for which the fold level is defined. This can be slow.
|
||||
|
||||
If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced
|
||||
with the script ID (|local-function|). Examples: >
|
||||
with the script ID (|local-function|). Examples: >
|
||||
set foldexpr=s:MyFoldExpr()
|
||||
set foldexpr=<SID>SomeFoldExpr()
|
||||
<
|
||||
@ -143,6 +142,37 @@ end in that line.
|
||||
It may happen that folds are not updated properly. You can use |zx| or |zX|
|
||||
to force updating folds.
|
||||
|
||||
MINIMIZING COMPUTATIONAL COST *fold-expr-slow*
|
||||
|
||||
Due to its computational cost, this fold method can make Vim unresponsive,
|
||||
especially when the fold level of all lines have to be initially computed.
|
||||
Afterwards, after each change, Vim restricts the computation of foldlevels
|
||||
to those lines whose fold level was affected by it (and reuses the known
|
||||
foldlevels of all the others).
|
||||
|
||||
The fold expression should therefore strive to minimize the number of
|
||||
dependent lines needed for the computation of a given line: For example, try
|
||||
to avoid the "=", "a" and "s" return values, because these will require the
|
||||
evaluation of the fold levels on previous lines until an independent fold
|
||||
level is found.
|
||||
|
||||
If this proves difficult, the next best thing could be to cache all fold
|
||||
levels in a buffer-local variable (b:foldlevels) that is only updated on
|
||||
|b:changedtick|:
|
||||
>vim
|
||||
func MyFoldFunc()
|
||||
if b:lasttick == b:changedtick
|
||||
return b:foldlevels[v:lnum - 1]
|
||||
endif
|
||||
let b:lasttick = b:changedtick
|
||||
let b:foldlevels = []
|
||||
" compute foldlevels ...
|
||||
return b:foldlevels[v:lnum - 1]
|
||||
enddef
|
||||
set foldexpr=s:MyFoldFunc()
|
||||
<
|
||||
In above example further speedup was gained by using a function without
|
||||
arguments (that must still use v:lnum). See |expr-option-function|.
|
||||
|
||||
SYNTAX *fold-syntax*
|
||||
|
||||
@ -379,8 +409,8 @@ zX Undo manually opened and closed folds: re-apply 'foldlevel'.
|
||||
Also forces recomputing folds, like |zx|.
|
||||
|
||||
*zm*
|
||||
zm Fold more: Subtract |v:count1| from 'foldlevel'. If 'foldlevel' was
|
||||
already zero nothing happens.
|
||||
zm Fold more: Subtract |v:count1| from 'foldlevel'. If
|
||||
'foldlevel' was already zero nothing happens.
|
||||
'foldenable' will be set.
|
||||
|
||||
*zM*
|
||||
@ -444,7 +474,7 @@ zk Move upwards to the end of the previous fold. A closed fold
|
||||
|
||||
EXECUTING COMMANDS ON FOLDS ~
|
||||
|
||||
:[range]foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
|
||||
:[range]foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
|
||||
Execute {cmd} on all lines that are not in a closed fold.
|
||||
When [range] is given, only these lines are used.
|
||||
Each time {cmd} is executed the cursor is positioned on the
|
||||
@ -532,7 +562,7 @@ When there is room after the text, it is filled with the character specified
|
||||
by 'fillchars'.
|
||||
|
||||
If the 'foldtext' expression starts with s: or |<SID>|, then it is replaced
|
||||
with the script ID (|local-function|). Examples: >
|
||||
with the script ID (|local-function|). Examples: >
|
||||
set foldtext=s:MyFoldText()
|
||||
set foldtext=<SID>SomeFoldText()
|
||||
<
|
||||
|
@ -1472,6 +1472,7 @@ tag command action ~
|
||||
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|
||||
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|
||||
|:packloadall| :packl[oadall] load all packages under 'packpath'
|
||||
|:pbuffer| :pb[uffer] edit buffer in the preview window
|
||||
|:pclose| :pc[lose] close preview window
|
||||
|:pedit| :ped[it] edit file in the preview window
|
||||
|:perl| :pe[rl] execute perl command
|
||||
|
@ -115,6 +115,12 @@ This cannot be repeated: >
|
||||
endif<CR>
|
||||
Note that when using ":" any motion becomes charwise exclusive.
|
||||
|
||||
*inclusive-motion-selection-exclusive*
|
||||
When 'selection' is "exclusive", |Visual| mode is active and an inclusive
|
||||
motion has been used, the cursor position will be adjusted by another
|
||||
character to the right, so that the Visual selection includes the expected
|
||||
text and can be acted upon.
|
||||
|
||||
*forced-motion*
|
||||
FORCING A MOTION TO BE LINEWISE, CHARWISE OR BLOCKWISE
|
||||
|
||||
|
@ -87,6 +87,11 @@ EVENTS
|
||||
• |vim.ui_attach()| callbacks for |ui-messages| `msg_show` events are executed in
|
||||
|api-fast| context.
|
||||
|
||||
HIGHLIGHTS
|
||||
|
||||
• |TermCursorNC| is removed and no longer supported. Unfocused terminals no
|
||||
longer have a cursor.
|
||||
|
||||
LSP
|
||||
|
||||
• Improved rendering of LSP hover docs. |K-lsp-default|
|
||||
@ -211,6 +216,7 @@ EDITOR
|
||||
• On Windows, filename arguments on the command-line prefixed with "~\" or
|
||||
"~/" are now expanded to the user's profile directory, not a relative path
|
||||
to a literal "~" directory.
|
||||
• |hl-ComplMatchIns| shows matched text of the currently inserted completion.
|
||||
• |hl-PmenuMatch| and |hl-PmenuMatchSel| show matched text in completion popup.
|
||||
|
||||
EVENTS
|
||||
@ -281,6 +287,12 @@ TERMINAL
|
||||
'scrollback' are not reflown.
|
||||
• The |terminal| now supports OSC 8 escape sequences and will display
|
||||
hyperlinks in supporting host terminals.
|
||||
• The |terminal| now uses the actual cursor, rather than a "virtual" cursor.
|
||||
This means that escape codes sent by applications running in a terminal
|
||||
buffer can change the cursor shape and visibility. However, it also
|
||||
means that the |TermCursorNC| highlight group is no longer supported: an
|
||||
unfocused terminal window will have no cursor at all (so there is nothing to
|
||||
highlight).
|
||||
|
||||
TREESITTER
|
||||
|
||||
@ -307,7 +319,7 @@ UI
|
||||
which controls the tool used to open the given path or URL. If you want to
|
||||
globally set this, you can override vim.ui.open using the same approach
|
||||
described at |vim.paste()|.
|
||||
- `vim.ui.open()` now supports
|
||||
• `vim.ui.open()` now supports
|
||||
[lemonade](https://github.com/lemonade-command/lemonade) as an option for
|
||||
opening urls/files. This is handy if you are in an ssh connection and use
|
||||
`lemonade`.
|
||||
@ -317,7 +329,6 @@ UI
|
||||
|hl-PmenuMatch|.
|
||||
• |vim.diagnostic.setqflist()| updates an existing quickfix list with the
|
||||
given title if found
|
||||
|
||||
• |ui-messages| content chunks now also contain the highlight group ID.
|
||||
|
||||
==============================================================================
|
||||
@ -339,9 +350,9 @@ These existing features changed their behavior.
|
||||
more emoji characters than before, including those encoded with multiple
|
||||
emoji codepoints combined with ZWJ (zero width joiner) codepoints.
|
||||
|
||||
• Text in the 'statusline', 'tabline', and 'winbar' now inherits highlights
|
||||
from the respective |hl-StatusLine|, |hl-TabLine|, and |hl-WinBar| highlight
|
||||
groups.
|
||||
• Custom highlights in 'rulerformat', 'statuscolumn', 'statusline', 'tabline',
|
||||
'winbar' and the number column (through |:sign-define| `numhl`) now combine
|
||||
with their respective highlight groups, as opposed to |hl-Normal|.
|
||||
|
||||
• |vim.on_key()| callbacks won't be invoked recursively when a callback itself
|
||||
consumes input.
|
||||
|
@ -2977,7 +2977,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
An |OptionSet| autocmd can be used to set it up to match automatically.
|
||||
|
||||
*'guicursor'* *'gcr'* *E545* *E546* *E548* *E549*
|
||||
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20")
|
||||
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor")
|
||||
global
|
||||
Configures the cursor style for each mode. Works in the GUI and many
|
||||
terminals. See |tui-cursor-shape|.
|
||||
@ -3005,6 +3005,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
ci Command-line Insert mode
|
||||
cr Command-line Replace mode
|
||||
sm showmatch in Insert mode
|
||||
t Terminal mode
|
||||
a all modes
|
||||
The argument-list is a dash separated list of these arguments:
|
||||
hor{N} horizontal bar, {N} percent of the character height
|
||||
@ -3021,7 +3022,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
cursor is not shown. Times are in msec. When one of
|
||||
the numbers is zero, there is no blinking. E.g.: >vim
|
||||
set guicursor=n:blinkon0
|
||||
< - Default is "blinkon0" for each mode.
|
||||
<
|
||||
Default is "blinkon0" for each mode.
|
||||
{group-name}
|
||||
Highlight group that decides the color and font of the
|
||||
cursor.
|
||||
@ -4982,6 +4984,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
selection.
|
||||
When "old" is used and 'virtualedit' allows the cursor to move past
|
||||
the end of line the line break still isn't included.
|
||||
When "exclusive" is used, cursor position in visual mode will be
|
||||
adjusted for inclusive motions |inclusive-motion-selection-exclusive|.
|
||||
Note that when "exclusive" is used and selecting from the end
|
||||
backwards, you cannot include the last character of a line, when
|
||||
starting in Normal mode and 'virtualedit' empty.
|
||||
|
@ -5162,8 +5162,6 @@ EndOfBuffer Filler lines (~) after the end of the buffer.
|
||||
By default, this is highlighted like |hl-NonText|.
|
||||
*hl-TermCursor*
|
||||
TermCursor Cursor in a focused terminal.
|
||||
*hl-TermCursorNC*
|
||||
TermCursorNC Cursor in an unfocused terminal.
|
||||
*hl-ErrorMsg*
|
||||
ErrorMsg Error messages on the command line.
|
||||
*hl-WinSeparator*
|
||||
@ -5245,6 +5243,8 @@ PmenuMatch Popup menu: Matched text in normal item. Combined with
|
||||
*hl-PmenuMatchSel*
|
||||
PmenuMatchSel Popup menu: Matched text in selected item. Combined with
|
||||
|hl-PmenuMatch| and |hl-PmenuSel|.
|
||||
*hl-ComplMatchIns*
|
||||
ComplMatchIns Matched text of the currently inserted completion.
|
||||
*hl-Question*
|
||||
Question |hit-enter| prompt and yes/no questions.
|
||||
*hl-QuickFixLine*
|
||||
|
@ -101,7 +101,7 @@ Configuration *terminal-config*
|
||||
|
||||
Options: 'modified', 'scrollback'
|
||||
Events: |TermOpen|, |TermEnter|, |TermLeave|, |TermClose|
|
||||
Highlight groups: |hl-TermCursor|, |hl-TermCursorNC|
|
||||
Highlight groups: |hl-TermCursor|
|
||||
|
||||
Terminal sets local defaults for some options, which may differ from your
|
||||
global configuration.
|
||||
|
@ -805,6 +805,7 @@ must handle.
|
||||
"quickfix" Quickfix navigation message
|
||||
"search_cmd" Entered search command
|
||||
"search_count" Search count message ("S" flag of 'shortmess')
|
||||
"undo" |:undo| and |:redo| message
|
||||
"wildlist" 'wildmode' "list" message
|
||||
"wmsg" Warning ("search hit BOTTOM", |W10|, …)
|
||||
New kinds may be added in the future; clients should treat unknown
|
||||
|
@ -325,7 +325,6 @@ Highlight groups:
|
||||
- |hl-MsgSeparator| highlights separator for scrolled messages
|
||||
- |hl-Substitute|
|
||||
- |hl-TermCursor|
|
||||
- |hl-TermCursorNC|
|
||||
- |hl-WinSeparator| highlights window separators
|
||||
- |hl-Whitespace| highlights 'listchars' whitespace
|
||||
- |hl-WinBar| highlights 'winbar'
|
||||
|
@ -978,6 +978,13 @@ CTRL-W g } *CTRL-W_g}*
|
||||
it. Make the new Preview window (if required) N high. If N is
|
||||
not given, 'previewheight' is used.
|
||||
|
||||
*:pb* *:pbuffer*
|
||||
:[N]pb[uffer][!] [+cmd] [N]
|
||||
Edit buffer [N] from the buffer list in the preview window.
|
||||
If [N] is not given, the current buffer remains being edited.
|
||||
See |:buffer-!| for [!]. This will also edit a buffer that is
|
||||
not in the buffer list, without setting the 'buflisted' flag.
|
||||
|
||||
*:ped* *:pedit*
|
||||
:ped[it][!] [++opt] [+cmd] {file}
|
||||
Edit {file} in the preview window. The preview window is
|
||||
@ -985,6 +992,8 @@ CTRL-W g } *CTRL-W_g}*
|
||||
position isn't changed. Useful example: >
|
||||
:pedit +/fputc /usr/include/stdio.h
|
||||
<
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
*:ps* *:psearch*
|
||||
:[range]ps[earch][!] [count] [/]pattern[/]
|
||||
Works like |:ijump| but shows the found match in the preview
|
||||
|
@ -151,7 +151,7 @@ function properties.trim_trailing_whitespace(bufnr, val)
|
||||
)
|
||||
if val == 'true' then
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
group = 'editorconfig',
|
||||
group = 'nvim_editorconfig',
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
local view = vim.fn.winsaveview()
|
||||
@ -163,7 +163,7 @@ function properties.trim_trailing_whitespace(bufnr, val)
|
||||
else
|
||||
vim.api.nvim_clear_autocmds({
|
||||
event = 'BufWritePre',
|
||||
group = 'editorconfig',
|
||||
group = 'nvim_editorconfig',
|
||||
buffer = bufnr,
|
||||
})
|
||||
end
|
||||
@ -180,7 +180,7 @@ function properties.insert_final_newline(bufnr, val)
|
||||
local endofline = val == 'true'
|
||||
if vim.bo[bufnr].endofline ~= endofline then
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
group = 'editorconfig',
|
||||
group = 'nvim_editorconfig',
|
||||
buffer = bufnr,
|
||||
once = true,
|
||||
callback = function()
|
||||
|
@ -21,9 +21,12 @@ end
|
||||
local function system(cmd, silent, env)
|
||||
local r = vim.system(cmd, { env = env, timeout = 10000 }):wait()
|
||||
|
||||
if r.code ~= 0 and not silent then
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
|
||||
if not silent then
|
||||
if r.code ~= 0 then
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
|
||||
end
|
||||
assert(r.stdout ~= '')
|
||||
end
|
||||
|
||||
return assert(r.stdout)
|
||||
|
6
runtime/lua/vim/_meta/api.lua
generated
6
runtime/lua/vim/_meta/api.lua
generated
@ -885,10 +885,8 @@ function vim.api.nvim_cmd(cmd, opts) end
|
||||
---
|
||||
--- On execution error: fails with Vimscript error, updates v:errmsg.
|
||||
---
|
||||
--- Prefer using `nvim_cmd()` or `nvim_exec2()` over this. To evaluate multiple lines of Vim script
|
||||
--- or an Ex command directly, use `nvim_exec2()`. To construct an Ex command using a structured
|
||||
--- format and then execute it, use `nvim_cmd()`. To modify an Ex command before evaluating it, use
|
||||
--- `nvim_parse_cmd()` in conjunction with `nvim_cmd()`.
|
||||
--- Prefer `nvim_cmd()` or `nvim_exec2()` instead. To modify an Ex command in a structured way
|
||||
--- before executing it, modify the result of `nvim_parse_cmd()` then pass it to `nvim_cmd()`.
|
||||
---
|
||||
--- @param command string Ex command string
|
||||
function vim.api.nvim_command(command) end
|
||||
|
8
runtime/lua/vim/_meta/options.lua
generated
8
runtime/lua/vim/_meta/options.lua
generated
@ -2783,6 +2783,7 @@ vim.go.gp = vim.go.grepprg
|
||||
--- ci Command-line Insert mode
|
||||
--- cr Command-line Replace mode
|
||||
--- sm showmatch in Insert mode
|
||||
--- t Terminal mode
|
||||
--- a all modes
|
||||
--- The argument-list is a dash separated list of these arguments:
|
||||
--- hor{N} horizontal bar, {N} percent of the character height
|
||||
@ -2802,7 +2803,8 @@ vim.go.gp = vim.go.grepprg
|
||||
--- ```vim
|
||||
--- set guicursor=n:blinkon0
|
||||
--- ```
|
||||
--- - Default is "blinkon0" for each mode.
|
||||
---
|
||||
--- Default is "blinkon0" for each mode.
|
||||
--- {group-name}
|
||||
--- Highlight group that decides the color and font of the
|
||||
--- cursor.
|
||||
@ -2848,7 +2850,7 @@ vim.go.gp = vim.go.grepprg
|
||||
---
|
||||
---
|
||||
--- @type string
|
||||
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"
|
||||
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor"
|
||||
vim.o.gcr = vim.o.guicursor
|
||||
vim.go.guicursor = vim.o.guicursor
|
||||
vim.go.gcr = vim.go.guicursor
|
||||
@ -5214,6 +5216,8 @@ vim.go.sect = vim.go.sections
|
||||
--- selection.
|
||||
--- When "old" is used and 'virtualedit' allows the cursor to move past
|
||||
--- the end of line the line break still isn't included.
|
||||
--- When "exclusive" is used, cursor position in visual mode will be
|
||||
--- adjusted for inclusive motions `inclusive-motion-selection-exclusive`.
|
||||
--- Note that when "exclusive" is used and selecting from the end
|
||||
--- backwards, you cannot include the last character of a line, when
|
||||
--- starting in Normal mode and 'virtualedit' empty.
|
||||
|
29
runtime/lua/vim/_meta/vimfn.lua
generated
29
runtime/lua/vim/_meta/vimfn.lua
generated
@ -1147,8 +1147,9 @@ function vim.fn.confirm(msg, choices, default, type) end
|
||||
--- A |Dictionary| is copied in a similar way as a |List|.
|
||||
--- Also see |deepcopy()|.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @generic T
|
||||
--- @param expr T
|
||||
--- @return T
|
||||
function vim.fn.copy(expr) end
|
||||
|
||||
--- Return the cosine of {expr}, measured in radians, as a |Float|.
|
||||
@ -1308,9 +1309,10 @@ function vim.fn.debugbreak(pid) end
|
||||
--- {noref} set to 1 will fail.
|
||||
--- Also see |copy()|.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @generic T
|
||||
--- @param expr T
|
||||
--- @param noref? boolean
|
||||
--- @return any
|
||||
--- @return T
|
||||
function vim.fn.deepcopy(expr, noref) end
|
||||
|
||||
--- Without {flags} or with {flags} empty: Deletes the file by the
|
||||
@ -4769,7 +4771,7 @@ function vim.fn.isnan(expr) end
|
||||
--- cases, items() returns a List with the index and the value at
|
||||
--- the index.
|
||||
---
|
||||
--- @param dict any
|
||||
--- @param dict table
|
||||
--- @return any
|
||||
function vim.fn.items(dict) end
|
||||
|
||||
@ -5952,7 +5954,7 @@ function vim.fn.matchstrpos(expr, pat, start, count) end
|
||||
--- an error. An empty |List| or |Dictionary| results in zero.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.max(expr) end
|
||||
|
||||
--- Returns a |List| of |Dictionaries| describing |menus| (defined
|
||||
@ -7016,10 +7018,11 @@ function vim.fn.readfile(fname, type, max) end
|
||||
--- echo reduce('xyz', { acc, val -> acc .. ',' .. val })
|
||||
--- <
|
||||
---
|
||||
--- @generic T
|
||||
--- @param object any
|
||||
--- @param func function
|
||||
--- @param func fun(accumulator: T, current: any): any
|
||||
--- @param initial? any
|
||||
--- @return any
|
||||
--- @return T
|
||||
function vim.fn.reduce(object, func, initial) end
|
||||
|
||||
--- Returns the single letter name of the register being executed.
|
||||
@ -7215,8 +7218,9 @@ function vim.fn.resolve(filename) end
|
||||
--- let revlist = reverse(copy(mylist))
|
||||
--- <
|
||||
---
|
||||
--- @param object any
|
||||
--- @return any
|
||||
--- @generic T
|
||||
--- @param object T[]
|
||||
--- @return T[]
|
||||
function vim.fn.reverse(object) end
|
||||
|
||||
--- Round off {expr} to the nearest integral value and return it
|
||||
@ -9079,10 +9083,11 @@ function vim.fn.sockconnect(mode, address, opts) end
|
||||
--- eval mylist->sort({i1, i2 -> i1 - i2})
|
||||
--- <
|
||||
---
|
||||
--- @param list any
|
||||
--- @generic T
|
||||
--- @param list T[]
|
||||
--- @param how? string|function
|
||||
--- @param dict? any
|
||||
--- @return any
|
||||
--- @return T[]
|
||||
function vim.fn.sort(list, how, dict) end
|
||||
|
||||
--- Return the sound-folded equivalent of {word}. Uses the first
|
||||
|
@ -871,7 +871,7 @@ local function set_list(loclist, opts)
|
||||
end
|
||||
|
||||
if open then
|
||||
if qf_id then
|
||||
if not loclist then
|
||||
-- First navigate to the diagnostics quickfix list.
|
||||
local nr = vim.fn.getqflist({ id = qf_id, nr = 0 }).nr
|
||||
api.nvim_command(nr .. 'chistory')
|
||||
|
@ -672,6 +672,7 @@ local extension = {
|
||||
k = 'kwt',
|
||||
ACE = 'lace',
|
||||
ace = 'lace',
|
||||
lalrpop = 'lalrpop',
|
||||
latte = 'latte',
|
||||
lte = 'latte',
|
||||
ld = 'ld',
|
||||
@ -1874,6 +1875,7 @@ local filename = {
|
||||
['.clangd'] = 'yaml',
|
||||
['.clang-format'] = 'yaml',
|
||||
['.clang-tidy'] = 'yaml',
|
||||
['pixi.lock'] = 'yaml',
|
||||
['yarn.lock'] = 'yaml',
|
||||
matplotlibrc = 'yaml',
|
||||
['.condarc'] = 'yaml',
|
||||
|
@ -201,23 +201,28 @@ local function reuse_client_default(client, config)
|
||||
end
|
||||
|
||||
local config_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir)
|
||||
or {}
|
||||
local config_folders_included = 0
|
||||
|
||||
if not next(config_folders) then
|
||||
return false
|
||||
if not config_folders or not next(config_folders) then
|
||||
-- Reuse if the client was configured with no workspace folders
|
||||
local client_config_folders =
|
||||
lsp._get_workspace_folders(client.config.workspace_folders or client.config.root_dir)
|
||||
return not client_config_folders or not next(client_config_folders)
|
||||
end
|
||||
|
||||
for _, config_folder in ipairs(config_folders) do
|
||||
local found = false
|
||||
for _, client_folder in ipairs(client.workspace_folders) do
|
||||
if config_folder.uri == client_folder.uri then
|
||||
config_folders_included = config_folders_included + 1
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return config_folders_included == #config_folders
|
||||
return true
|
||||
end
|
||||
|
||||
--- Reset defaults set by `set_defaults`.
|
||||
|
@ -1,4 +1,4 @@
|
||||
local group = vim.api.nvim_create_augroup('editorconfig', {})
|
||||
local group = vim.api.nvim_create_augroup('nvim_editorconfig', {})
|
||||
vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead', 'BufFilePost' }, {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
|
@ -63,7 +63,7 @@ syn keyword vimGroup contained Comment Constant String Character Number Boolean
|
||||
syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit DiffText PmenuSbar TabLineSel TabLineFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen StatusLineTerm StatusLineTermNC CursorIM LineNrAbove LineNrBelow
|
||||
syn match vimHLGroup contained "\<Conceal\>"
|
||||
syn keyword vimOnlyHLGroup contained Menu Scrollbar ToolbarButton ToolbarLine Tooltip VisualNOS
|
||||
syn keyword nvimHLGroup contained FloatBorder FloatFooter FloatTitle MsgSeparator NormalFloat NormalNC Substitute TermCursor TermCursorNC VisualNC Whitespace WinBar WinBarNC WinSeparator
|
||||
syn keyword nvimHLGroup contained FloatBorder FloatFooter FloatTitle MsgSeparator NormalFloat NormalNC Substitute TermCursor VisualNC Whitespace WinBar WinBarNC WinSeparator
|
||||
"}}}2
|
||||
syn case match
|
||||
|
||||
|
@ -496,6 +496,10 @@ local function render_eval_meta(f, fun, write)
|
||||
end
|
||||
end
|
||||
|
||||
for _, text in ipairs(vim.fn.reverse(fun.generics or {})) do
|
||||
write(fmt('--- @generic %s', text))
|
||||
end
|
||||
|
||||
local req_args = type(fun.args) == 'table' and fun.args[1] or fun.args or 0
|
||||
|
||||
for i, param in ipairs(params) do
|
||||
|
@ -135,6 +135,10 @@
|
||||
: 0UL)), \
|
||||
&(v).items[(i)]))
|
||||
|
||||
#define kv_shift(v, i, n) ((v).size -= (n), (i) < (v).size \
|
||||
&& memmove(&kv_A(v, (i)), &kv_A(v, (i)+(n)), \
|
||||
((v).size-(i))*sizeof(kv_A(v, i))))
|
||||
|
||||
#define kv_printf(v, ...) kv_do_printf(&(v), __VA_ARGS__)
|
||||
|
||||
/// Type of a vector with a few first members allocated on stack
|
||||
|
@ -360,93 +360,91 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
|
||||
memchrsub(lines[i], NUL, NL, l.size);
|
||||
}
|
||||
|
||||
try_start();
|
||||
|
||||
if (!MODIFIABLE(buf)) {
|
||||
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (u_save_buf(buf, (linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
bcount_t deleted_bytes = get_region_bytecount(buf, (linenr_T)start, (linenr_T)end, 0, 0);
|
||||
|
||||
// If the size of the range is reducing (ie, new_len < old_len) we
|
||||
// need to delete some old_len. We do this at the start, by
|
||||
// repeatedly deleting line "start".
|
||||
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
|
||||
for (size_t i = 0; i < to_delete; i++) {
|
||||
if (ml_delete_buf(buf, (linenr_T)start, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to delete line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (to_delete > 0) {
|
||||
extra -= (ptrdiff_t)to_delete;
|
||||
}
|
||||
|
||||
// For as long as possible, replace the existing old_len with the
|
||||
// new old_len. This is a more efficient operation, as it requires
|
||||
// less memory allocation and freeing.
|
||||
size_t to_replace = old_len < new_len ? old_len : new_len;
|
||||
bcount_t inserted_bytes = 0;
|
||||
for (size_t i = 0; i < to_replace; i++) {
|
||||
int64_t lnum = start + (int64_t)i;
|
||||
|
||||
VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false, true) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to replace line");
|
||||
TRY_WRAP(err, {
|
||||
if (!MODIFIABLE(buf)) {
|
||||
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
|
||||
goto end;
|
||||
}
|
||||
|
||||
inserted_bytes += (bcount_t)strlen(lines[i]) + 1;
|
||||
}
|
||||
|
||||
// Now we may need to insert the remaining new old_len
|
||||
for (size_t i = to_replace; i < new_len; i++) {
|
||||
int64_t lnum = start + (int64_t)i - 1;
|
||||
|
||||
VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to insert line");
|
||||
if (u_save_buf(buf, (linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
inserted_bytes += (bcount_t)strlen(lines[i]) + 1;
|
||||
bcount_t deleted_bytes = get_region_bytecount(buf, (linenr_T)start, (linenr_T)end, 0, 0);
|
||||
|
||||
extra++;
|
||||
}
|
||||
|
||||
// Adjust marks. Invalidate any which lie in the
|
||||
// changed range, and move any in the remainder of the buffer.
|
||||
linenr_T adjust = end > start ? MAXLNUM : 0;
|
||||
mark_adjust_buf(buf, (linenr_T)start, (linenr_T)(end - 1), adjust, (linenr_T)extra,
|
||||
true, true, kExtmarkNOOP);
|
||||
|
||||
extmark_splice(buf, (int)start - 1, 0, (int)(end - start), 0,
|
||||
deleted_bytes, (int)new_len, 0, inserted_bytes,
|
||||
kExtmarkUndo);
|
||||
|
||||
changed_lines(buf, (linenr_T)start, 0, (linenr_T)end, (linenr_T)extra, true);
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, win) {
|
||||
if (win->w_buffer == buf) {
|
||||
fix_cursor(win, (linenr_T)start, (linenr_T)end, (linenr_T)extra);
|
||||
// If the size of the range is reducing (ie, new_len < old_len) we
|
||||
// need to delete some old_len. We do this at the start, by
|
||||
// repeatedly deleting line "start".
|
||||
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
|
||||
for (size_t i = 0; i < to_delete; i++) {
|
||||
if (ml_delete_buf(buf, (linenr_T)start, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to delete line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
try_end(err);
|
||||
if (to_delete > 0) {
|
||||
extra -= (ptrdiff_t)to_delete;
|
||||
}
|
||||
|
||||
// For as long as possible, replace the existing old_len with the
|
||||
// new old_len. This is a more efficient operation, as it requires
|
||||
// less memory allocation and freeing.
|
||||
size_t to_replace = old_len < new_len ? old_len : new_len;
|
||||
bcount_t inserted_bytes = 0;
|
||||
for (size_t i = 0; i < to_replace; i++) {
|
||||
int64_t lnum = start + (int64_t)i;
|
||||
|
||||
VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false, true) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to replace line");
|
||||
goto end;
|
||||
}
|
||||
|
||||
inserted_bytes += (bcount_t)strlen(lines[i]) + 1;
|
||||
}
|
||||
|
||||
// Now we may need to insert the remaining new old_len
|
||||
for (size_t i = to_replace; i < new_len; i++) {
|
||||
int64_t lnum = start + (int64_t)i - 1;
|
||||
|
||||
VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to insert line");
|
||||
goto end;
|
||||
}
|
||||
|
||||
inserted_bytes += (bcount_t)strlen(lines[i]) + 1;
|
||||
|
||||
extra++;
|
||||
}
|
||||
|
||||
// Adjust marks. Invalidate any which lie in the
|
||||
// changed range, and move any in the remainder of the buffer.
|
||||
linenr_T adjust = end > start ? MAXLNUM : 0;
|
||||
mark_adjust_buf(buf, (linenr_T)start, (linenr_T)(end - 1), adjust, (linenr_T)extra,
|
||||
true, true, kExtmarkNOOP);
|
||||
|
||||
extmark_splice(buf, (int)start - 1, 0, (int)(end - start), 0,
|
||||
deleted_bytes, (int)new_len, 0, inserted_bytes,
|
||||
kExtmarkUndo);
|
||||
|
||||
changed_lines(buf, (linenr_T)start, 0, (linenr_T)end, (linenr_T)extra, true);
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, win) {
|
||||
if (win->w_buffer == buf) {
|
||||
fix_cursor(win, (linenr_T)start, (linenr_T)end, (linenr_T)extra);
|
||||
}
|
||||
}
|
||||
end:;
|
||||
});
|
||||
}
|
||||
|
||||
/// Sets (replaces) a range in the buffer
|
||||
@ -593,101 +591,99 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
|
||||
new_byte += (bcount_t)(last_item.size) + 1;
|
||||
}
|
||||
|
||||
try_start();
|
||||
|
||||
if (!MODIFIABLE(buf)) {
|
||||
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Small note about undo states: unlike set_lines, we want to save the
|
||||
// undo state of one past the end_row, since end_row is inclusive.
|
||||
if (u_save_buf(buf, (linenr_T)start_row - 1, (linenr_T)end_row + 1) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ptrdiff_t extra = 0; // lines added to text, can be negative
|
||||
size_t old_len = (size_t)(end_row - start_row + 1);
|
||||
|
||||
// If the size of the range is reducing (ie, new_len < old_len) we
|
||||
// need to delete some old_len. We do this at the start, by
|
||||
// repeatedly deleting line "start".
|
||||
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
|
||||
for (size_t i = 0; i < to_delete; i++) {
|
||||
if (ml_delete_buf(buf, (linenr_T)start_row, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to delete line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (to_delete > 0) {
|
||||
extra -= (ptrdiff_t)to_delete;
|
||||
}
|
||||
|
||||
// For as long as possible, replace the existing old_len with the
|
||||
// new old_len. This is a more efficient operation, as it requires
|
||||
// less memory allocation and freeing.
|
||||
size_t to_replace = old_len < new_len ? old_len : new_len;
|
||||
for (size_t i = 0; i < to_replace; i++) {
|
||||
int64_t lnum = start_row + (int64_t)i;
|
||||
|
||||
VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false, true) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to replace line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we may need to insert the remaining new old_len
|
||||
for (size_t i = to_replace; i < new_len; i++) {
|
||||
int64_t lnum = start_row + (int64_t)i - 1;
|
||||
|
||||
VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to insert line");
|
||||
TRY_WRAP(err, {
|
||||
if (!MODIFIABLE(buf)) {
|
||||
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
|
||||
goto end;
|
||||
}
|
||||
|
||||
extra++;
|
||||
}
|
||||
// Small note about undo states: unlike set_lines, we want to save the
|
||||
// undo state of one past the end_row, since end_row is inclusive.
|
||||
if (u_save_buf(buf, (linenr_T)start_row - 1, (linenr_T)end_row + 1) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
colnr_T col_extent = (colnr_T)(end_col
|
||||
- ((end_row == start_row) ? start_col : 0));
|
||||
ptrdiff_t extra = 0; // lines added to text, can be negative
|
||||
size_t old_len = (size_t)(end_row - start_row + 1);
|
||||
|
||||
// Adjust marks. Invalidate any which lie in the
|
||||
// changed range, and move any in the remainder of the buffer.
|
||||
// Do not adjust any cursors. need to use column-aware logic (below)
|
||||
linenr_T adjust = end_row >= start_row ? MAXLNUM : 0;
|
||||
mark_adjust_buf(buf, (linenr_T)start_row, (linenr_T)end_row, adjust, (linenr_T)extra,
|
||||
true, true, kExtmarkNOOP);
|
||||
|
||||
extmark_splice(buf, (int)start_row - 1, (colnr_T)start_col,
|
||||
(int)(end_row - start_row), col_extent, old_byte,
|
||||
(int)new_len - 1, (colnr_T)last_item.size, new_byte,
|
||||
kExtmarkUndo);
|
||||
|
||||
changed_lines(buf, (linenr_T)start_row, 0, (linenr_T)end_row + 1, (linenr_T)extra, true);
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, win) {
|
||||
if (win->w_buffer == buf) {
|
||||
if (win->w_cursor.lnum >= start_row && win->w_cursor.lnum <= end_row) {
|
||||
fix_cursor_cols(win, (linenr_T)start_row, (colnr_T)start_col, (linenr_T)end_row,
|
||||
(colnr_T)end_col, (linenr_T)new_len, (colnr_T)last_item.size);
|
||||
} else {
|
||||
fix_cursor(win, (linenr_T)start_row, (linenr_T)end_row, (linenr_T)extra);
|
||||
// If the size of the range is reducing (ie, new_len < old_len) we
|
||||
// need to delete some old_len. We do this at the start, by
|
||||
// repeatedly deleting line "start".
|
||||
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
|
||||
for (size_t i = 0; i < to_delete; i++) {
|
||||
if (ml_delete_buf(buf, (linenr_T)start_row, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to delete line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
try_end(err);
|
||||
if (to_delete > 0) {
|
||||
extra -= (ptrdiff_t)to_delete;
|
||||
}
|
||||
|
||||
// For as long as possible, replace the existing old_len with the
|
||||
// new old_len. This is a more efficient operation, as it requires
|
||||
// less memory allocation and freeing.
|
||||
size_t to_replace = old_len < new_len ? old_len : new_len;
|
||||
for (size_t i = 0; i < to_replace; i++) {
|
||||
int64_t lnum = start_row + (int64_t)i;
|
||||
|
||||
VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false, true) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to replace line");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we may need to insert the remaining new old_len
|
||||
for (size_t i = to_replace; i < new_len; i++) {
|
||||
int64_t lnum = start_row + (int64_t)i - 1;
|
||||
|
||||
VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", {
|
||||
goto end;
|
||||
});
|
||||
|
||||
if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to insert line");
|
||||
goto end;
|
||||
}
|
||||
|
||||
extra++;
|
||||
}
|
||||
|
||||
colnr_T col_extent = (colnr_T)(end_col
|
||||
- ((end_row == start_row) ? start_col : 0));
|
||||
|
||||
// Adjust marks. Invalidate any which lie in the
|
||||
// changed range, and move any in the remainder of the buffer.
|
||||
// Do not adjust any cursors. need to use column-aware logic (below)
|
||||
linenr_T adjust = end_row >= start_row ? MAXLNUM : 0;
|
||||
mark_adjust_buf(buf, (linenr_T)start_row, (linenr_T)end_row, adjust, (linenr_T)extra,
|
||||
true, true, kExtmarkNOOP);
|
||||
|
||||
extmark_splice(buf, (int)start_row - 1, (colnr_T)start_col,
|
||||
(int)(end_row - start_row), col_extent, old_byte,
|
||||
(int)new_len - 1, (colnr_T)last_item.size, new_byte,
|
||||
kExtmarkUndo);
|
||||
|
||||
changed_lines(buf, (linenr_T)start_row, 0, (linenr_T)end_row + 1, (linenr_T)extra, true);
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, win) {
|
||||
if (win->w_buffer == buf) {
|
||||
if (win->w_cursor.lnum >= start_row && win->w_cursor.lnum <= end_row) {
|
||||
fix_cursor_cols(win, (linenr_T)start_row, (colnr_T)start_col, (linenr_T)end_row,
|
||||
(colnr_T)end_col, (linenr_T)new_len, (colnr_T)last_item.size);
|
||||
} else {
|
||||
fix_cursor(win, (linenr_T)start_row, (linenr_T)end_row, (linenr_T)extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
end:;
|
||||
});
|
||||
}
|
||||
|
||||
/// Gets a range from the buffer.
|
||||
@ -965,26 +961,27 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
int ren_ret = OK;
|
||||
TRY_WRAP(err, {
|
||||
const bool is_curbuf = buf == curbuf;
|
||||
const int save_acd = p_acd;
|
||||
if (!is_curbuf) {
|
||||
// Temporarily disable 'autochdir' when setting file name for another buffer.
|
||||
p_acd = false;
|
||||
}
|
||||
|
||||
const bool is_curbuf = buf == curbuf;
|
||||
const int save_acd = p_acd;
|
||||
if (!is_curbuf) {
|
||||
// Temporarily disable 'autochdir' when setting file name for another buffer.
|
||||
p_acd = false;
|
||||
}
|
||||
// Using aucmd_*: autocommands will be executed by rename_buffer
|
||||
aco_save_T aco;
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
ren_ret = rename_buffer(name.data);
|
||||
aucmd_restbuf(&aco);
|
||||
|
||||
// Using aucmd_*: autocommands will be executed by rename_buffer
|
||||
aco_save_T aco;
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
int ren_ret = rename_buffer(name.data);
|
||||
aucmd_restbuf(&aco);
|
||||
if (!is_curbuf) {
|
||||
p_acd = save_acd;
|
||||
}
|
||||
});
|
||||
|
||||
if (!is_curbuf) {
|
||||
p_acd = save_acd;
|
||||
}
|
||||
|
||||
if (try_end(err)) {
|
||||
if (ERROR_SET(err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1204,15 +1201,18 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err)
|
||||
if (!buf) {
|
||||
return NIL;
|
||||
}
|
||||
try_start();
|
||||
aco_save_T aco;
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
Object res = nlua_call_ref(fun, NULL, args, kRetLuaref, NULL, err);
|
||||
Object res = OBJECT_INIT;
|
||||
TRY_WRAP(err, {
|
||||
aco_save_T aco;
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
res = nlua_call_ref(fun, NULL, args, kRetLuaref, NULL, err);
|
||||
|
||||
aucmd_restbuf(&aco);
|
||||
});
|
||||
|
||||
aucmd_restbuf(&aco);
|
||||
try_end(err);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,10 @@
|
||||
|
||||
/// Start block that may cause Vimscript exceptions while evaluating another code
|
||||
///
|
||||
/// Used when caller is supposed to be operating when other Vimscript code is being
|
||||
/// processed and that “other Vimscript code” must not be affected.
|
||||
/// Used just in case caller is supposed to be operating when other Vimscript code
|
||||
/// is being processed and that “other Vimscript code” must not be affected.
|
||||
///
|
||||
/// @warning Avoid calling directly; use TRY_WRAP instead.
|
||||
///
|
||||
/// @param[out] tstate Location where try state should be saved.
|
||||
void try_enter(TryState *const tstate)
|
||||
@ -55,74 +57,33 @@ void try_enter(TryState *const tstate)
|
||||
.current_exception = current_exception,
|
||||
.msg_list = (const msglist_T *const *)msg_list,
|
||||
.private_msg_list = NULL,
|
||||
.trylevel = trylevel,
|
||||
.got_int = got_int,
|
||||
.did_throw = did_throw,
|
||||
.need_rethrow = need_rethrow,
|
||||
.did_emsg = did_emsg,
|
||||
};
|
||||
// `msg_list` controls the collection of abort-causing non-exception errors,
|
||||
// which would otherwise be ignored. This pattern is from do_cmdline().
|
||||
msg_list = &tstate->private_msg_list;
|
||||
current_exception = NULL;
|
||||
trylevel = 1;
|
||||
got_int = false;
|
||||
did_throw = false;
|
||||
need_rethrow = false;
|
||||
did_emsg = false;
|
||||
}
|
||||
|
||||
/// End try block, set the error message if any and restore previous state
|
||||
///
|
||||
/// @warning Return is consistent with most functions (false on error), not with
|
||||
/// try_end (true on error).
|
||||
///
|
||||
/// @param[in] tstate Previous state to restore.
|
||||
/// @param[out] err Location where error should be saved.
|
||||
///
|
||||
/// @return false if error occurred, true otherwise.
|
||||
bool try_leave(const TryState *const tstate, Error *const err)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
const bool ret = !try_end(err);
|
||||
assert(trylevel == 0);
|
||||
assert(!need_rethrow);
|
||||
assert(!got_int);
|
||||
assert(!did_throw);
|
||||
assert(!did_emsg);
|
||||
assert(msg_list == &tstate->private_msg_list);
|
||||
assert(*msg_list == NULL);
|
||||
assert(current_exception == NULL);
|
||||
msg_list = (msglist_T **)tstate->msg_list;
|
||||
current_exception = tstate->current_exception;
|
||||
trylevel = tstate->trylevel;
|
||||
got_int = tstate->got_int;
|
||||
did_throw = tstate->did_throw;
|
||||
need_rethrow = tstate->need_rethrow;
|
||||
did_emsg = tstate->did_emsg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Start block that may cause vimscript exceptions
|
||||
///
|
||||
/// Each try_start() call should be mirrored by try_end() call.
|
||||
///
|
||||
/// To be used as a replacement of `:try … catch … endtry` in C code, in cases
|
||||
/// when error flag could not already be set. If there may be pending error
|
||||
/// state at the time try_start() is executed which needs to be preserved,
|
||||
/// try_enter()/try_leave() pair should be used instead.
|
||||
void try_start(void)
|
||||
{
|
||||
trylevel++;
|
||||
}
|
||||
|
||||
/// End try block, set the error message if any and return true if an error
|
||||
/// occurred.
|
||||
/// Ends a `try_enter` block; sets error message if any.
|
||||
///
|
||||
/// @param err Pointer to the stack-allocated error object
|
||||
/// @return true if an error occurred
|
||||
bool try_end(Error *err)
|
||||
/// @warning Avoid calling directly; use TRY_WRAP instead.
|
||||
///
|
||||
/// @param[out] err Pointer to the stack-allocated error object
|
||||
void try_leave(const TryState *const tstate, Error *const err)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
// Note: all globals manipulated here should be saved/restored in
|
||||
// try_enter/try_leave.
|
||||
assert(trylevel > 0);
|
||||
trylevel--;
|
||||
|
||||
// Set by emsg(), affects aborting(). See also enter_cleanup().
|
||||
@ -165,7 +126,20 @@ bool try_end(Error *err)
|
||||
discard_current_exception();
|
||||
}
|
||||
|
||||
return ERROR_SET(err);
|
||||
assert(msg_list == &tstate->private_msg_list);
|
||||
assert(*msg_list == NULL);
|
||||
assert(current_exception == NULL);
|
||||
assert(!got_int);
|
||||
assert(!did_throw);
|
||||
assert(!need_rethrow);
|
||||
assert(!did_emsg);
|
||||
// Restore the exception context.
|
||||
msg_list = (msglist_T **)tstate->msg_list;
|
||||
current_exception = tstate->current_exception;
|
||||
got_int = tstate->got_int;
|
||||
did_throw = tstate->did_throw;
|
||||
need_rethrow = tstate->need_rethrow;
|
||||
did_emsg = tstate->did_emsg;
|
||||
}
|
||||
|
||||
/// Recursively expands a vimscript value in a dict
|
||||
|
@ -147,27 +147,19 @@ typedef struct {
|
||||
except_T *current_exception;
|
||||
msglist_T *private_msg_list;
|
||||
const msglist_T *const *msg_list;
|
||||
int trylevel;
|
||||
int got_int;
|
||||
bool did_throw;
|
||||
int need_rethrow;
|
||||
int did_emsg;
|
||||
} TryState;
|
||||
|
||||
// `msg_list` controls the collection of abort-causing non-exception errors,
|
||||
// which would otherwise be ignored. This pattern is from do_cmdline().
|
||||
//
|
||||
// TODO(bfredl): prepare error-handling at "top level" (nv_event).
|
||||
#define TRY_WRAP(err, code) \
|
||||
do { \
|
||||
msglist_T **saved_msg_list = msg_list; \
|
||||
msglist_T *private_msg_list; \
|
||||
msg_list = &private_msg_list; \
|
||||
private_msg_list = NULL; \
|
||||
try_start(); \
|
||||
TryState tstate; \
|
||||
try_enter(&tstate); \
|
||||
code; \
|
||||
try_end(err); \
|
||||
msg_list = saved_msg_list; /* Restore the exception context. */ \
|
||||
try_leave(&tstate, err); \
|
||||
} while (0)
|
||||
|
||||
// Execute code with cursor position saved and restored and textlock active.
|
||||
|
@ -146,11 +146,9 @@ void nvim_tabpage_set_win(Tabpage tabpage, Window win, Error *err)
|
||||
}
|
||||
|
||||
if (tp == curtab) {
|
||||
try_start();
|
||||
win_goto(wp);
|
||||
if (!try_end(err) && curwin != wp) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to switch to window %d", win);
|
||||
}
|
||||
TRY_WRAP(err, {
|
||||
win_goto(wp);
|
||||
});
|
||||
} else if (tp->tp_curwin != wp) {
|
||||
tp->tp_prevwin = tp->tp_curwin;
|
||||
tp->tp_curwin = wp;
|
||||
|
@ -594,11 +594,10 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Er
|
||||
kvi_init(cookie.rv);
|
||||
|
||||
int flags = DIP_DIRFILE | (all ? DIP_ALL : 0);
|
||||
TryState tstate;
|
||||
|
||||
try_enter(&tstate);
|
||||
do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie);
|
||||
vim_ignored = try_leave(&tstate, err);
|
||||
TRY_WRAP(err, {
|
||||
do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie);
|
||||
});
|
||||
|
||||
return arena_take_arraybuilder(arena, &cookie.rv);
|
||||
}
|
||||
@ -668,16 +667,9 @@ void nvim_set_current_dir(String dir, Error *err)
|
||||
memcpy(string, dir.data, dir.size);
|
||||
string[dir.size] = NUL;
|
||||
|
||||
try_start();
|
||||
|
||||
if (!changedir_func(string, kCdScopeGlobal)) {
|
||||
if (!try_end(err)) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to change directory");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try_end(err);
|
||||
TRY_WRAP(err, {
|
||||
changedir_func(string, kCdScopeGlobal);
|
||||
});
|
||||
}
|
||||
|
||||
/// Gets the current line.
|
||||
@ -892,19 +884,9 @@ void nvim_set_current_buf(Buffer buffer, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
if (curwin->w_p_wfb) {
|
||||
api_set_error(err, kErrorTypeException, "%s", e_winfixbuf_cannot_go_to_buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
|
||||
if (!try_end(err) && result == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to buffer %d",
|
||||
buffer);
|
||||
}
|
||||
TRY_WRAP(err, {
|
||||
do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
|
||||
});
|
||||
}
|
||||
|
||||
/// Gets the current list of window handles.
|
||||
@ -951,14 +933,9 @@ void nvim_set_current_win(Window window, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
goto_tabpage_win(win_find_tabpage(win), win);
|
||||
if (!try_end(err) && win != curwin) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to window %d",
|
||||
window);
|
||||
}
|
||||
TRY_WRAP(err, {
|
||||
goto_tabpage_win(win_find_tabpage(win), win);
|
||||
});
|
||||
}
|
||||
|
||||
/// Creates a new, empty, unnamed buffer.
|
||||
@ -973,68 +950,70 @@ void nvim_set_current_win(Window window, Error *err)
|
||||
Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
|
||||
FUNC_API_SINCE(6)
|
||||
{
|
||||
try_start();
|
||||
// Block autocommands for now so they don't mess with the buffer before we
|
||||
// finish configuring it.
|
||||
block_autocmds();
|
||||
Buffer ret = 0;
|
||||
|
||||
TRY_WRAP(err, {
|
||||
// Block autocommands for now so they don't mess with the buffer before we
|
||||
// finish configuring it.
|
||||
block_autocmds();
|
||||
|
||||
buf_T *buf = buflist_new(NULL, NULL, 0,
|
||||
BLN_NOOPT | BLN_NEW | (listed ? BLN_LISTED : 0));
|
||||
if (buf == NULL) {
|
||||
unblock_autocmds();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Open the memline for the buffer. This will avoid spurious autocmds when
|
||||
// a later nvim_buf_set_lines call would have needed to "open" the buffer.
|
||||
if (ml_open(buf) == FAIL) {
|
||||
unblock_autocmds();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Set last_changedtick to avoid triggering a TextChanged autocommand right
|
||||
// after it was added.
|
||||
buf->b_last_changedtick = buf_get_changedtick(buf);
|
||||
buf->b_last_changedtick_i = buf_get_changedtick(buf);
|
||||
buf->b_last_changedtick_pum = buf_get_changedtick(buf);
|
||||
|
||||
// Only strictly needed for scratch, but could just as well be consistent
|
||||
// and do this now. Buffer is created NOW, not when it later first happens
|
||||
// to reach a window or aucmd_prepbuf() ..
|
||||
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
|
||||
|
||||
if (scratch) {
|
||||
set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0,
|
||||
kOptScopeBuf, buf);
|
||||
set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0,
|
||||
kOptScopeBuf, buf);
|
||||
assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already
|
||||
buf->b_p_swf = false;
|
||||
buf->b_p_ml = false;
|
||||
}
|
||||
|
||||
buf_T *buf = buflist_new(NULL, NULL, 0,
|
||||
BLN_NOOPT | BLN_NEW | (listed ? BLN_LISTED : 0));
|
||||
if (buf == NULL) {
|
||||
unblock_autocmds();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Open the memline for the buffer. This will avoid spurious autocmds when
|
||||
// a later nvim_buf_set_lines call would have needed to "open" the buffer.
|
||||
if (ml_open(buf) == FAIL) {
|
||||
unblock_autocmds();
|
||||
goto fail;
|
||||
}
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
goto fail;
|
||||
}
|
||||
if (listed
|
||||
&& apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Set last_changedtick to avoid triggering a TextChanged autocommand right
|
||||
// after it was added.
|
||||
buf->b_last_changedtick = buf_get_changedtick(buf);
|
||||
buf->b_last_changedtick_i = buf_get_changedtick(buf);
|
||||
buf->b_last_changedtick_pum = buf_get_changedtick(buf);
|
||||
ret = buf->b_fnum;
|
||||
fail:;
|
||||
});
|
||||
|
||||
// Only strictly needed for scratch, but could just as well be consistent
|
||||
// and do this now. Buffer is created NOW, not when it later first happens
|
||||
// to reach a window or aucmd_prepbuf() ..
|
||||
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
|
||||
|
||||
if (scratch) {
|
||||
set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0,
|
||||
kOptScopeBuf, buf);
|
||||
set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0,
|
||||
kOptScopeBuf, buf);
|
||||
assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already
|
||||
buf->b_p_swf = false;
|
||||
buf->b_p_ml = false;
|
||||
}
|
||||
|
||||
unblock_autocmds();
|
||||
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
goto fail;
|
||||
}
|
||||
if (listed
|
||||
&& apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
try_end(err);
|
||||
return buf->b_fnum;
|
||||
|
||||
fail:
|
||||
if (!try_end(err)) {
|
||||
if (ret == 0 && !ERROR_SET(err)) {
|
||||
api_set_error(err, kErrorTypeException, "Failed to create buffer");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Open a terminal instance in a buffer
|
||||
@ -1217,14 +1196,9 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
goto_tabpage_tp(tp, true, true);
|
||||
if (!try_end(err) && tp != curtab) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to tabpage %d",
|
||||
tabpage);
|
||||
}
|
||||
TRY_WRAP(err, {
|
||||
goto_tabpage_tp(tp, true, true);
|
||||
});
|
||||
}
|
||||
|
||||
/// Pastes at cursor (in any mode), and sets "redo" so dot (|.|) will repeat the input. UIs call
|
||||
|
@ -78,24 +78,24 @@ String exec_impl(uint64_t channel_id, String src, Dict(exec_opts) *opts, Error *
|
||||
capture_ga = &capture_local;
|
||||
}
|
||||
|
||||
try_start();
|
||||
if (opts->output) {
|
||||
msg_silent++;
|
||||
msg_col = 0; // prevent leading spaces
|
||||
}
|
||||
TRY_WRAP(err, {
|
||||
if (opts->output) {
|
||||
msg_silent++;
|
||||
msg_col = 0; // prevent leading spaces
|
||||
}
|
||||
|
||||
const sctx_T save_current_sctx = api_set_sctx(channel_id);
|
||||
const sctx_T save_current_sctx = api_set_sctx(channel_id);
|
||||
|
||||
do_source_str(src.data, "nvim_exec2()");
|
||||
if (opts->output) {
|
||||
capture_ga = save_capture_ga;
|
||||
msg_silent = save_msg_silent;
|
||||
// Put msg_col back where it was, since nothing should have been written.
|
||||
msg_col = save_msg_col;
|
||||
}
|
||||
do_source_str(src.data, "nvim_exec2()");
|
||||
if (opts->output) {
|
||||
capture_ga = save_capture_ga;
|
||||
msg_silent = save_msg_silent;
|
||||
// Put msg_col back where it was, since nothing should have been written.
|
||||
msg_col = save_msg_col;
|
||||
}
|
||||
|
||||
current_sctx = save_current_sctx;
|
||||
try_end(err);
|
||||
current_sctx = save_current_sctx;
|
||||
});
|
||||
|
||||
if (ERROR_SET(err)) {
|
||||
goto theend;
|
||||
@ -125,19 +125,17 @@ theend:
|
||||
///
|
||||
/// On execution error: fails with Vimscript error, updates v:errmsg.
|
||||
///
|
||||
/// Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate multiple lines of Vim script
|
||||
/// or an Ex command directly, use |nvim_exec2()|. To construct an Ex command using a structured
|
||||
/// format and then execute it, use |nvim_cmd()|. To modify an Ex command before evaluating it, use
|
||||
/// |nvim_parse_cmd()| in conjunction with |nvim_cmd()|.
|
||||
/// Prefer |nvim_cmd()| or |nvim_exec2()| instead. To modify an Ex command in a structured way
|
||||
/// before executing it, modify the result of |nvim_parse_cmd()| then pass it to |nvim_cmd()|.
|
||||
///
|
||||
/// @param command Ex command string
|
||||
/// @param[out] err Error details (Vim error), if any
|
||||
void nvim_command(String command, Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
{
|
||||
try_start();
|
||||
do_cmdline_cmd(command.data);
|
||||
try_end(err);
|
||||
TRY_WRAP(err, {
|
||||
do_cmdline_cmd(command.data);
|
||||
});
|
||||
}
|
||||
|
||||
/// Evaluates a Vimscript |expression|. Dicts and Lists are recursively expanded.
|
||||
@ -283,13 +281,11 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Arena *arena,
|
||||
bool mustfree = false;
|
||||
switch (dict.type) {
|
||||
case kObjectTypeString:
|
||||
try_start();
|
||||
if (eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE) == FAIL) {
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Failed to evaluate dict expression");
|
||||
}
|
||||
clear_evalarg(&EVALARG_EVALUATE, NULL);
|
||||
if (try_end(err)) {
|
||||
TRY_WRAP(err, {
|
||||
eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE);
|
||||
clear_evalarg(&EVALARG_EVALUATE, NULL);
|
||||
});
|
||||
if (ERROR_SET(err)) {
|
||||
return rv;
|
||||
}
|
||||
// Evaluation of the string arg created a new dict or increased the
|
||||
|
@ -63,11 +63,6 @@ void nvim_win_set_buf(Window window, Buffer buffer, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
if (win->w_p_wfb) {
|
||||
api_set_error(err, kErrorTypeException, "%s", e_winfixbuf_cannot_go_to_buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (win == cmdwin_win || win == cmdwin_old_curwin || buf == cmdwin_buf) {
|
||||
api_set_error(err, kErrorTypeException, "%s", e_cmdwin);
|
||||
return;
|
||||
@ -187,14 +182,9 @@ void nvim_win_set_height(Window window, Integer height, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
if (height > INT_MAX || height < INT_MIN) {
|
||||
api_set_error(err, kErrorTypeValidation, "Height value outside range");
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
win_setheight_win((int)height, win);
|
||||
try_end(err);
|
||||
TRY_WRAP(err, {
|
||||
win_setheight_win((int)height, win);
|
||||
});
|
||||
}
|
||||
|
||||
/// Gets the window width
|
||||
@ -229,14 +219,9 @@ void nvim_win_set_width(Window window, Integer width, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
if (width > INT_MAX || width < INT_MIN) {
|
||||
api_set_error(err, kErrorTypeValidation, "Width value outside range");
|
||||
return;
|
||||
}
|
||||
|
||||
try_start();
|
||||
win_setwidth_win((int)width, win);
|
||||
try_end(err);
|
||||
TRY_WRAP(err, {
|
||||
win_setwidth_win((int)width, win);
|
||||
});
|
||||
}
|
||||
|
||||
/// Gets a window-scoped (w:) variable
|
||||
@ -383,19 +368,16 @@ void nvim_win_hide(Window window, Error *err)
|
||||
}
|
||||
|
||||
tabpage_T *tabpage = win_find_tabpage(win);
|
||||
TryState tstate;
|
||||
try_enter(&tstate);
|
||||
|
||||
// Never close the autocommand window.
|
||||
if (is_aucmd_win(win)) {
|
||||
emsg(_(e_autocmd_close));
|
||||
} else if (tabpage == curtab) {
|
||||
win_close(win, false, false);
|
||||
} else {
|
||||
win_close_othertab(win, false, tabpage);
|
||||
}
|
||||
|
||||
vim_ignored = try_leave(&tstate, err);
|
||||
TRY_WRAP(err, {
|
||||
// Never close the autocommand window.
|
||||
if (is_aucmd_win(win)) {
|
||||
emsg(_(e_autocmd_close));
|
||||
} else if (tabpage == curtab) {
|
||||
win_close(win, false, false);
|
||||
} else {
|
||||
win_close_othertab(win, false, tabpage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Closes the window (like |:close| with a |window-ID|).
|
||||
@ -415,10 +397,9 @@ void nvim_win_close(Window window, Boolean force, Error *err)
|
||||
}
|
||||
|
||||
tabpage_T *tabpage = win_find_tabpage(win);
|
||||
TryState tstate;
|
||||
try_enter(&tstate);
|
||||
ex_win_close(force, win, tabpage == curtab ? NULL : tabpage);
|
||||
vim_ignored = try_leave(&tstate, err);
|
||||
TRY_WRAP(err, {
|
||||
ex_win_close(force, win, tabpage == curtab ? NULL : tabpage);
|
||||
});
|
||||
}
|
||||
|
||||
/// Calls a function with window as temporary current window.
|
||||
@ -441,15 +422,15 @@ Object nvim_win_call(Window window, LuaRef fun, Error *err)
|
||||
}
|
||||
tabpage_T *tabpage = win_find_tabpage(win);
|
||||
|
||||
try_start();
|
||||
Object res = OBJECT_INIT;
|
||||
win_execute_T win_execute_args;
|
||||
if (win_execute_before(&win_execute_args, win, tabpage)) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
res = nlua_call_ref(fun, NULL, args, kRetLuaref, NULL, err);
|
||||
}
|
||||
win_execute_after(&win_execute_args);
|
||||
try_end(err);
|
||||
TRY_WRAP(err, {
|
||||
win_execute_T win_execute_args;
|
||||
if (win_execute_before(&win_execute_args, win, tabpage)) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
res = nlua_call_ref(fun, NULL, args, kRetLuaref, NULL, err);
|
||||
}
|
||||
win_execute_after(&win_execute_args);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -875,6 +875,7 @@ static void free_buffer(buf_T *buf)
|
||||
aubuflocal_remove(buf);
|
||||
xfree(buf->additional_data);
|
||||
xfree(buf->b_prompt_text);
|
||||
kv_destroy(buf->b_wininfo);
|
||||
callback_free(&buf->b_prompt_callback);
|
||||
callback_free(&buf->b_prompt_interrupt);
|
||||
clear_fmark(&buf->b_last_cursor, 0);
|
||||
@ -901,13 +902,10 @@ static void free_buffer(buf_T *buf)
|
||||
/// Free the b_wininfo list for buffer "buf".
|
||||
static void clear_wininfo(buf_T *buf)
|
||||
{
|
||||
wininfo_T *wip;
|
||||
|
||||
while (buf->b_wininfo != NULL) {
|
||||
wip = buf->b_wininfo;
|
||||
buf->b_wininfo = wip->wi_next;
|
||||
free_wininfo(wip, buf);
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
free_wininfo(kv_A(buf->b_wininfo, i), buf);
|
||||
}
|
||||
kv_size(buf->b_wininfo) = 0;
|
||||
}
|
||||
|
||||
/// Free stuff in the buffer for ":bdel" and when wiping out the buffer.
|
||||
@ -1926,7 +1924,8 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags)
|
||||
}
|
||||
|
||||
clear_wininfo(buf);
|
||||
buf->b_wininfo = xcalloc(1, sizeof(wininfo_T));
|
||||
WinInfo *curwin_info = xcalloc(1, sizeof(WinInfo));
|
||||
kv_push(buf->b_wininfo, curwin_info);
|
||||
|
||||
if (buf == curbuf) {
|
||||
free_buffer_stuff(buf, kBffInitChangedtick); // delete local vars et al.
|
||||
@ -1964,9 +1963,9 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags)
|
||||
buf_copy_options(buf, BCO_ALWAYS);
|
||||
}
|
||||
|
||||
buf->b_wininfo->wi_mark = (fmark_T)INIT_FMARK;
|
||||
buf->b_wininfo->wi_mark.mark.lnum = lnum;
|
||||
buf->b_wininfo->wi_win = curwin;
|
||||
curwin_info->wi_mark = (fmark_T)INIT_FMARK;
|
||||
curwin_info->wi_mark.mark.lnum = lnum;
|
||||
curwin_info->wi_win = curwin;
|
||||
|
||||
hash_init(&buf->b_s.b_keywtab);
|
||||
hash_init(&buf->b_s.b_keywtab_ic);
|
||||
@ -2631,30 +2630,26 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T
|
||||
bool copy_options)
|
||||
FUNC_ATTR_NONNULL_ARG(1)
|
||||
{
|
||||
wininfo_T *wip;
|
||||
WinInfo *wip;
|
||||
|
||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
|
||||
size_t i;
|
||||
for (i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
wip = kv_A(buf->b_wininfo, i);
|
||||
if (wip->wi_win == win) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wip == NULL) {
|
||||
|
||||
if (i == kv_size(buf->b_wininfo)) {
|
||||
// allocate a new entry
|
||||
wip = xcalloc(1, sizeof(wininfo_T));
|
||||
wip = xcalloc(1, sizeof(WinInfo));
|
||||
wip->wi_win = win;
|
||||
if (lnum == 0) { // set lnum even when it's 0
|
||||
lnum = 1;
|
||||
}
|
||||
} else {
|
||||
// remove the entry from the list
|
||||
if (wip->wi_prev) {
|
||||
wip->wi_prev->wi_next = wip->wi_next;
|
||||
} else {
|
||||
buf->b_wininfo = wip->wi_next;
|
||||
}
|
||||
if (wip->wi_next) {
|
||||
wip->wi_next->wi_prev = wip->wi_prev;
|
||||
}
|
||||
kv_shift(buf->b_wininfo, i, 1);
|
||||
if (copy_options && wip->wi_optset) {
|
||||
clear_winopt(&wip->wi_opt);
|
||||
deleteFoldRecurse(buf, &wip->wi_folds);
|
||||
@ -2679,17 +2674,15 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T
|
||||
}
|
||||
|
||||
// insert the entry in front of the list
|
||||
wip->wi_next = buf->b_wininfo;
|
||||
buf->b_wininfo = wip;
|
||||
wip->wi_prev = NULL;
|
||||
if (wip->wi_next) {
|
||||
wip->wi_next->wi_prev = wip;
|
||||
}
|
||||
kv_pushp(buf->b_wininfo);
|
||||
memmove(&kv_A(buf->b_wininfo, 1), &kv_A(buf->b_wininfo, 0),
|
||||
(kv_size(buf->b_wininfo) - 1) * sizeof(kv_A(buf->b_wininfo, 0)));
|
||||
kv_A(buf->b_wininfo, 0) = wip;
|
||||
}
|
||||
|
||||
/// Check that "wip" has 'diff' set and the diff is only for another tab page.
|
||||
/// That's because a diff is local to a tab page.
|
||||
static bool wininfo_other_tab_diff(wininfo_T *wip)
|
||||
static bool wininfo_other_tab_diff(WinInfo *wip)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (!wip->wi_opt.wo_diff) {
|
||||
@ -2713,42 +2706,38 @@ static bool wininfo_other_tab_diff(wininfo_T *wip)
|
||||
/// @param skip_diff_buffer when true, avoid windows with 'diff' set that is in another tab page.
|
||||
///
|
||||
/// @return NULL when there isn't any info.
|
||||
static wininfo_T *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buffer)
|
||||
static WinInfo *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buffer)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
||||
{
|
||||
wininfo_T *wip;
|
||||
|
||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||
if (wip->wi_win == curwin
|
||||
&& (!skip_diff_buffer || !wininfo_other_tab_diff(wip))
|
||||
&& (!need_options || wip->wi_optset)) {
|
||||
break;
|
||||
return wip;
|
||||
}
|
||||
}
|
||||
|
||||
if (wip != NULL) {
|
||||
return wip;
|
||||
}
|
||||
|
||||
// If no wininfo for curwin, use the first in the list (that doesn't have
|
||||
// 'diff' set and is in another tab page).
|
||||
// If "need_options" is true skip entries that don't have options set,
|
||||
// unless the window is editing "buf", so we can copy from the window
|
||||
// itself.
|
||||
if (skip_diff_buffer) {
|
||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||
if (!wininfo_other_tab_diff(wip)
|
||||
&& (!need_options
|
||||
|| wip->wi_optset
|
||||
|| (wip->wi_win != NULL
|
||||
&& wip->wi_win->w_buffer == buf))) {
|
||||
break;
|
||||
return wip;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wip = buf->b_wininfo;
|
||||
} else if (kv_size(buf->b_wininfo)) {
|
||||
return kv_A(buf->b_wininfo, 0);
|
||||
}
|
||||
return wip;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Reset the local window options to the values last used in this window.
|
||||
@ -2760,7 +2749,7 @@ void get_winopts(buf_T *buf)
|
||||
clear_winopt(&curwin->w_onebuf_opt);
|
||||
clearFolding(curwin);
|
||||
|
||||
wininfo_T *const wip = find_wininfo(buf, true, true);
|
||||
WinInfo *const wip = find_wininfo(buf, true, true);
|
||||
if (wip != NULL && wip->wi_win != curwin && wip->wi_win != NULL
|
||||
&& wip->wi_win->w_buffer == buf) {
|
||||
win_T *wp = wip->wi_win;
|
||||
@ -2800,7 +2789,7 @@ fmark_T *buflist_findfmark(buf_T *buf)
|
||||
{
|
||||
static fmark_T no_position = { { 1, 0, 0 }, 0, 0, { 0 }, NULL };
|
||||
|
||||
wininfo_T *const wip = find_wininfo(buf, false, false);
|
||||
WinInfo *const wip = find_wininfo(buf, false, false);
|
||||
return (wip == NULL) ? &no_position : &(wip->wi_mark);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ typedef struct {
|
||||
// Mask to check for flags that prevent normal writing
|
||||
#define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR)
|
||||
|
||||
typedef struct wininfo_S wininfo_T;
|
||||
typedef struct wininfo_S WinInfo;
|
||||
typedef struct frame_S frame_T;
|
||||
typedef uint64_t disptick_T; // display tick type
|
||||
|
||||
@ -85,7 +85,7 @@ typedef struct {
|
||||
|
||||
// Structure that contains all options that are local to a window.
|
||||
// Used twice in a window: for the current buffer and for all buffers.
|
||||
// Also used in wininfo_T.
|
||||
// Also used in WinInfo.
|
||||
typedef struct {
|
||||
int wo_arab;
|
||||
#define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
|
||||
@ -219,8 +219,6 @@ typedef struct {
|
||||
// The window-info is kept in a list at b_wininfo. It is kept in
|
||||
// most-recently-used order.
|
||||
struct wininfo_S {
|
||||
wininfo_T *wi_next; // next entry or NULL for last entry
|
||||
wininfo_T *wi_prev; // previous entry or NULL for first entry
|
||||
win_T *wi_win; // pointer to window that did set wi_mark
|
||||
fmark_T wi_mark; // last cursor mark in the file
|
||||
bool wi_optset; // true when wi_opt has useful values
|
||||
@ -411,7 +409,7 @@ struct file_buffer {
|
||||
// change
|
||||
linenr_T b_mod_xlines; // number of extra buffer lines inserted;
|
||||
// negative when lines were deleted
|
||||
wininfo_T *b_wininfo; // list of last used info for each window
|
||||
kvec_t(WinInfo *) b_wininfo; // list of last used info for each window
|
||||
disptick_T b_mod_tick_syn; // last display tick syntax was updated
|
||||
disptick_T b_mod_tick_decor; // last display tick decoration providers
|
||||
// where invoked
|
||||
|
@ -341,9 +341,11 @@ void check_cursor_col(win_T *win)
|
||||
} else if (win->w_cursor.col >= len) {
|
||||
// Allow cursor past end-of-line when:
|
||||
// - in Insert mode or restarting Insert mode
|
||||
// - in Terminal mode
|
||||
// - in Visual mode and 'selection' isn't "old"
|
||||
// - 'virtualedit' is set
|
||||
if ((State & MODE_INSERT) || restart_edit
|
||||
|| (State & MODE_TERMINAL)
|
||||
|| (VIsual_active && *p_sel != 'o')
|
||||
|| (cur_ve_flags & kOptVeFlagOnemore)
|
||||
|| virtual_active(win)) {
|
||||
|
@ -45,6 +45,7 @@ cursorentry_T shape_table[SHAPE_IDX_COUNT] = {
|
||||
{ "more", 0, 0, 0, 0, 0, 0, 0, 0, "m", SHAPE_MOUSE },
|
||||
{ "more_lastline", 0, 0, 0, 0, 0, 0, 0, 0, "ml", SHAPE_MOUSE },
|
||||
{ "showmatch", 0, 0, 0, 100, 100, 100, 0, 0, "sm", SHAPE_CURSOR },
|
||||
{ "terminal", 0, 0, 0, 0, 0, 0, 0, 0, "t", SHAPE_CURSOR },
|
||||
};
|
||||
|
||||
/// Converts cursor_shapes into an Array of Dictionaries
|
||||
@ -321,6 +322,8 @@ int cursor_get_mode_idx(void)
|
||||
{
|
||||
if (State == MODE_SHOWMATCH) {
|
||||
return SHAPE_IDX_SM;
|
||||
} else if (State == MODE_TERMINAL) {
|
||||
return SHAPE_IDX_TERM;
|
||||
} else if (State & VREPLACE_FLAG) {
|
||||
return SHAPE_IDX_R;
|
||||
} else if (State & REPLACE_FLAG) {
|
||||
|
@ -23,7 +23,8 @@ typedef enum {
|
||||
SHAPE_IDX_MORE = 14, ///< Hit-return or More
|
||||
SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
|
||||
SHAPE_IDX_SM = 16, ///< showing matching paren
|
||||
SHAPE_IDX_COUNT = 17,
|
||||
SHAPE_IDX_TERM = 17, ///< Terminal mode
|
||||
SHAPE_IDX_COUNT = 18,
|
||||
} ModeShape;
|
||||
|
||||
typedef enum {
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "nvim/highlight_defs.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/indent.h"
|
||||
#include "nvim/insexpand.h"
|
||||
#include "nvim/mark_defs.h"
|
||||
#include "nvim/marktree_defs.h"
|
||||
#include "nvim/match.h"
|
||||
@ -462,10 +463,12 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in
|
||||
static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr)
|
||||
{
|
||||
SignTextAttrs sattr = wlv->sattrs[sign_idx];
|
||||
int scl_attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC);
|
||||
|
||||
if (sattr.text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) {
|
||||
int attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr)
|
||||
? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0;
|
||||
attr = hl_combine_attr(scl_attr, attr);
|
||||
int fill = nrcol ? number_width(wp) + 1 : SIGN_WIDTH;
|
||||
draw_col_fill(wlv, schar_from_ascii(' '), fill, attr);
|
||||
int sign_pos = wlv->off - SIGN_WIDTH - (int)nrcol;
|
||||
@ -474,8 +477,7 @@ static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, i
|
||||
linebuf_char[sign_pos + 1] = sattr.text[1];
|
||||
} else {
|
||||
assert(!nrcol); // handled in draw_lnum_col()
|
||||
int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC);
|
||||
draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, attr);
|
||||
draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, scl_attr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,8 +561,8 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int
|
||||
} else {
|
||||
// Draw the line number (empty space after wrapping).
|
||||
int width = number_width(wp) + 1;
|
||||
int attr = (sign_num_attr > 0 && wlv->filler_todo <= 0)
|
||||
? sign_num_attr : get_line_number_attr(wp, wlv);
|
||||
int attr = hl_combine_attr(get_line_number_attr(wp, wlv),
|
||||
wlv->filler_todo <= 0 ? sign_num_attr : 0);
|
||||
if (wlv->row == wlv->startrow + wlv->filler_lines
|
||||
&& (wp->w_skipcol == 0 || wlv->row > 0 || (wp->w_p_nu && wp->w_p_rnu))) {
|
||||
char buf[32];
|
||||
@ -640,7 +642,7 @@ static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int vir
|
||||
draw_col_buf(wp, wlv, transbuf, translen, attr, false);
|
||||
p = sp->start;
|
||||
int hl = sp->userhl;
|
||||
attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr;
|
||||
attr = hl < 0 ? hl_combine_attr(stcp->num_attr, syn_id2attr(-hl)) : stcp->num_attr;
|
||||
}
|
||||
size_t translen = transstr_buf(p, buf + len - p, transbuf, MAXPATHL, true);
|
||||
draw_col_buf(wp, wlv, transbuf, translen, attr, false);
|
||||
@ -933,6 +935,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
colnr_T vcol_prev = -1; // "wlv.vcol" of previous character
|
||||
ScreenGrid *grid = &wp->w_grid; // grid specific to the window
|
||||
|
||||
const bool in_curline = wp == curwin && lnum == curwin->w_cursor.lnum;
|
||||
const bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
|
||||
const bool has_foldtext = has_fold && *wp->w_p_fdt != NUL;
|
||||
|
||||
@ -1116,7 +1119,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
}
|
||||
|
||||
// Check if the char under the cursor should be inverted (highlighted).
|
||||
if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
|
||||
if (!highlight_match && in_curline
|
||||
&& cursor_is_block_during_visual(*p_sel == 'e')) {
|
||||
noinvcur = true;
|
||||
}
|
||||
@ -1628,8 +1631,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
}
|
||||
|
||||
// When still displaying '$' of change command, stop at cursor.
|
||||
if (dollar_vcol >= 0 && wp == curwin
|
||||
&& lnum == wp->w_cursor.lnum && wlv.vcol >= wp->w_virtcol) {
|
||||
if (dollar_vcol >= 0 && in_curline && wlv.vcol >= wp->w_virtcol) {
|
||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
|
||||
// don't clear anything after wlv.col
|
||||
wlv_put_linebuf(wp, &wlv, wlv.col, false, bg_attr, 0);
|
||||
@ -1785,6 +1787,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
wlv.char_attr = hl_combine_attr(char_attr_base, char_attr_pri);
|
||||
}
|
||||
|
||||
// Apply ComplMatchIns highlight if needed.
|
||||
if (wlv.filler_todo <= 0
|
||||
&& (State & MODE_INSERT) && in_curline && ins_compl_active()) {
|
||||
int ins_match_attr = ins_compl_col_range_attr((int)(ptr - line));
|
||||
if (ins_match_attr > 0) {
|
||||
char_attr_pri = hl_combine_attr(char_attr_pri, ins_match_attr);
|
||||
wlv.char_attr = hl_combine_attr(char_attr_base, char_attr_pri);
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_folded && has_foldtext && wlv.n_extra == 0 && wlv.col == win_col_offset) {
|
||||
const int v = (int)(ptr - line);
|
||||
linenr_T lnume = lnum + foldinfo.fi_lines - 1;
|
||||
@ -2445,8 +2457,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
// With 'virtualedit' we may never reach cursor position, but we still
|
||||
// need to correct the cursor column, so do that at end of line.
|
||||
if (!did_wcol && wlv.filler_todo <= 0
|
||||
&& wp == curwin && lnum == wp->w_cursor.lnum
|
||||
&& conceal_cursor_line(wp)
|
||||
&& in_curline && conceal_cursor_line(wp)
|
||||
&& (wlv.vcol + wlv.skip_cells >= wp->w_virtcol || mb_schar == NUL)) {
|
||||
wp->w_wcol = wlv.col - wlv.boguscols;
|
||||
if (wlv.vcol + wlv.skip_cells < wp->w_virtcol) {
|
||||
@ -2639,7 +2650,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
|
||||
// Update w_cline_height and w_cline_folded if the cursor line was
|
||||
// updated (saves a call to plines_win() later).
|
||||
if (wp == curwin && lnum == curwin->w_cursor.lnum) {
|
||||
if (in_curline) {
|
||||
curwin->w_cline_row = startrow;
|
||||
curwin->w_cline_height = wlv.row - startrow;
|
||||
curwin->w_cline_folded = has_fold;
|
||||
|
@ -17,6 +17,7 @@
|
||||
--- @field deprecated? true
|
||||
--- @field returns? string|false
|
||||
--- @field returns_desc? string
|
||||
--- @field generics? string[] Used to write `---@generic` annotations over a function.
|
||||
--- @field signature? string
|
||||
--- @field desc? string
|
||||
--- @field params [string, string, string][]
|
||||
@ -1521,9 +1522,10 @@ M.funcs = {
|
||||
A |Dictionary| is copied in a similar way as a |List|.
|
||||
Also see |deepcopy()|.
|
||||
]=],
|
||||
generics = { 'T' },
|
||||
name = 'copy',
|
||||
params = { { 'expr', 'any' } },
|
||||
returns = 'any',
|
||||
params = { { 'expr', 'T' } },
|
||||
returns = 'T',
|
||||
signature = 'copy({expr})',
|
||||
},
|
||||
cos = {
|
||||
@ -1739,8 +1741,10 @@ M.funcs = {
|
||||
Also see |copy()|.
|
||||
|
||||
]=],
|
||||
generics = { 'T' },
|
||||
name = 'deepcopy',
|
||||
params = { { 'expr', 'any' }, { 'noref', 'boolean' } },
|
||||
params = { { 'expr', 'T' }, { 'noref', 'boolean' } },
|
||||
returns = 'T',
|
||||
signature = 'deepcopy({expr} [, {noref}])',
|
||||
},
|
||||
delete = {
|
||||
@ -5894,7 +5898,7 @@ M.funcs = {
|
||||
the index.
|
||||
]=],
|
||||
name = 'items',
|
||||
params = { { 'dict', 'any' } },
|
||||
params = { { 'dict', 'table' } },
|
||||
signature = 'items({dict})',
|
||||
},
|
||||
jobclose = {
|
||||
@ -7309,6 +7313,7 @@ M.funcs = {
|
||||
]=],
|
||||
name = 'max',
|
||||
params = { { 'expr', 'any' } },
|
||||
returns = 'number',
|
||||
signature = 'max({expr})',
|
||||
},
|
||||
menu_get = {
|
||||
@ -8520,7 +8525,13 @@ M.funcs = {
|
||||
<
|
||||
]=],
|
||||
name = 'reduce',
|
||||
params = { { 'object', 'any' }, { 'func', 'function' }, { 'initial', 'any' } },
|
||||
generics = { 'T' },
|
||||
params = {
|
||||
{ 'object', 'any' },
|
||||
{ 'func', 'fun(accumulator: T, current: any): any' },
|
||||
{ 'initial', 'any' },
|
||||
},
|
||||
returns = 'T',
|
||||
signature = 'reduce({object}, {func} [, {initial}])',
|
||||
},
|
||||
reg_executing = {
|
||||
@ -8785,7 +8796,9 @@ M.funcs = {
|
||||
<
|
||||
]=],
|
||||
name = 'reverse',
|
||||
params = { { 'object', 'any' } },
|
||||
generics = { 'T' },
|
||||
params = { { 'object', 'T[]' } },
|
||||
returns = 'T[]',
|
||||
signature = 'reverse({object})',
|
||||
},
|
||||
round = {
|
||||
@ -10924,7 +10937,9 @@ M.funcs = {
|
||||
<
|
||||
]=],
|
||||
name = 'sort',
|
||||
params = { { 'list', 'any' }, { 'how', 'string|function' }, { 'dict', 'any' } },
|
||||
generics = { 'T' },
|
||||
params = { { 'list', 'T[]' }, { 'how', 'string|function' }, { 'dict', 'any' } },
|
||||
returns = 'T[]',
|
||||
signature = 'sort({list} [, {how} [, {dict}]])',
|
||||
},
|
||||
soundfold = {
|
||||
|
@ -66,12 +66,11 @@ buf_T *find_buffer(typval_T *avar)
|
||||
/// If there is a window for "curbuf", make it the current window.
|
||||
static void find_win_for_curbuf(void)
|
||||
{
|
||||
wininfo_T *wip;
|
||||
|
||||
// The b_wininfo list should have the windows that recently contained the
|
||||
// buffer, going over this is faster than going over all the windows.
|
||||
// Do check the buffer is still there.
|
||||
FOR_ALL_BUF_WININFO(curbuf, wip) {
|
||||
for (size_t i = 0; i < kv_size(curbuf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(curbuf->b_wininfo, i);
|
||||
if (wip->wi_win != NULL && wip->wi_win->w_buffer == curbuf) {
|
||||
curwin = wip->wi_win;
|
||||
break;
|
||||
|
@ -2402,14 +2402,15 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, EvalFuncData fpt
|
||||
if (buf == curwin->w_buffer) {
|
||||
changelistindex = curwin->w_changelistidx;
|
||||
} else {
|
||||
wininfo_T *wip;
|
||||
changelistindex = buf->b_changelistlen;
|
||||
|
||||
FOR_ALL_BUF_WININFO(buf, wip) {
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||
if (wip->wi_win == curwin) {
|
||||
changelistindex = wip->wi_changelistidx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
changelistindex = wip != NULL ? wip->wi_changelistidx : buf->b_changelistlen;
|
||||
}
|
||||
tv_list_append_number(rettv->vval.v_list, (varnumber_T)changelistindex);
|
||||
|
||||
|
@ -1946,6 +1946,12 @@ M.cmds = {
|
||||
addr_type = 'ADDR_NONE',
|
||||
func = 'ex_packloadall',
|
||||
},
|
||||
{
|
||||
command = 'pbuffer',
|
||||
flags = bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR),
|
||||
addr_type = 'ADDR_BUFFERS',
|
||||
func = 'ex_pbuffer',
|
||||
},
|
||||
{
|
||||
command = 'pclose',
|
||||
flags = bit.bor(BANG, TRLBAR),
|
||||
|
@ -4501,6 +4501,12 @@ static void ex_bunload(exarg_T *eap)
|
||||
/// :[N]buffer [N] to buffer N
|
||||
/// :[N]sbuffer [N] to buffer N
|
||||
static void ex_buffer(exarg_T *eap)
|
||||
{
|
||||
do_exbuffer(eap);
|
||||
}
|
||||
|
||||
/// ":buffer" command and alike.
|
||||
static void do_exbuffer(exarg_T *eap)
|
||||
{
|
||||
if (*eap->arg) {
|
||||
eap->errmsg = ex_errmsg(e_trailing_arg, eap->arg);
|
||||
@ -7002,14 +7008,35 @@ static void ex_ptag(exarg_T *eap)
|
||||
static void ex_pedit(exarg_T *eap)
|
||||
{
|
||||
win_T *curwin_save = curwin;
|
||||
|
||||
// Open the preview window or popup and make it the current window.
|
||||
g_do_tagpreview = (int)p_pvh;
|
||||
prepare_tagpreview(true);
|
||||
prepare_preview_window();
|
||||
|
||||
// Edit the file.
|
||||
do_exedit(eap, NULL);
|
||||
|
||||
back_to_current_window(curwin_save);
|
||||
}
|
||||
|
||||
/// ":pbuffer"
|
||||
static void ex_pbuffer(exarg_T *eap)
|
||||
{
|
||||
win_T *curwin_save = curwin;
|
||||
prepare_preview_window();
|
||||
|
||||
// Go to the buffer.
|
||||
do_exbuffer(eap);
|
||||
|
||||
back_to_current_window(curwin_save);
|
||||
}
|
||||
|
||||
static void prepare_preview_window(void)
|
||||
{
|
||||
// Open the preview window or popup and make it the current window.
|
||||
g_do_tagpreview = (int)p_pvh;
|
||||
prepare_tagpreview(true);
|
||||
}
|
||||
|
||||
static void back_to_current_window(win_T *curwin_save)
|
||||
{
|
||||
if (curwin != curwin_save && win_valid(curwin_save)) {
|
||||
// Return cursor to where we were
|
||||
validate_cursor(curwin);
|
||||
|
@ -787,9 +787,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
setmouse();
|
||||
setcursor();
|
||||
|
||||
TryState tstate;
|
||||
Error err = ERROR_INIT;
|
||||
bool tl_ret = true;
|
||||
char firstcbuf[2];
|
||||
firstcbuf[0] = (char)(firstc > 0 ? firstc : '-');
|
||||
firstcbuf[1] = 0;
|
||||
@ -802,20 +800,19 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
|
||||
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
|
||||
tv_dict_set_keys_readonly(dict);
|
||||
try_enter(&tstate);
|
||||
TRY_WRAP(&err, {
|
||||
apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf);
|
||||
restore_v_event(dict, &save_v_event);
|
||||
});
|
||||
|
||||
apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf);
|
||||
restore_v_event(dict, &save_v_event);
|
||||
|
||||
tl_ret = try_leave(&tstate, &err);
|
||||
if (!tl_ret && ERROR_SET(&err)) {
|
||||
if (ERROR_SET(&err)) {
|
||||
msg_putchar('\n');
|
||||
msg_scroll = true;
|
||||
msg_puts_hl(err.msg, HLF_E, true);
|
||||
api_clear_error(&err);
|
||||
redrawcmd();
|
||||
}
|
||||
tl_ret = true;
|
||||
err = ERROR_INIT;
|
||||
}
|
||||
may_trigger_modechanged();
|
||||
|
||||
@ -873,10 +870,10 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
// not readonly:
|
||||
tv_dict_add_bool(dict, S_LEN("abort"),
|
||||
s->gotesc ? kBoolVarTrue : kBoolVarFalse);
|
||||
try_enter(&tstate);
|
||||
apply_autocmds(EVENT_CMDLINELEAVE, firstcbuf, firstcbuf, false, curbuf);
|
||||
// error printed below, to avoid redraw issues
|
||||
tl_ret = try_leave(&tstate, &err);
|
||||
TRY_WRAP(&err, {
|
||||
apply_autocmds(EVENT_CMDLINELEAVE, firstcbuf, firstcbuf, false, curbuf);
|
||||
// error printed below, to avoid redraw issues
|
||||
});
|
||||
if (tv_dict_get_number(dict, "abort") != 0) {
|
||||
s->gotesc = true;
|
||||
}
|
||||
@ -929,7 +926,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
msg_scroll = s->save_msg_scroll;
|
||||
redir_off = false;
|
||||
|
||||
if (!tl_ret && ERROR_SET(&err)) {
|
||||
if (ERROR_SET(&err)) {
|
||||
msg_putchar('\n');
|
||||
emsg(err.msg);
|
||||
did_emsg = false;
|
||||
@ -937,7 +934,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
}
|
||||
|
||||
// When the command line was typed, no need for a wait-return prompt.
|
||||
if (s->some_key_typed && tl_ret) {
|
||||
if (s->some_key_typed && !ERROR_SET(&err)) {
|
||||
need_wait_return = false;
|
||||
}
|
||||
|
||||
@ -2315,11 +2312,13 @@ static win_T *cmdpreview_open_win(buf_T *cmdpreview_buf)
|
||||
|
||||
win_T *preview_win = curwin;
|
||||
Error err = ERROR_INIT;
|
||||
int result = OK;
|
||||
|
||||
// Switch to preview buffer
|
||||
try_start();
|
||||
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, cmdpreview_buf->handle, 0);
|
||||
if (try_end(&err) || result == FAIL) {
|
||||
TRY_WRAP(&err, {
|
||||
result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, cmdpreview_buf->handle, 0);
|
||||
});
|
||||
if (ERROR_SET(&err) || result == FAIL) {
|
||||
api_clear_error(&err);
|
||||
return NULL;
|
||||
}
|
||||
@ -2600,9 +2599,10 @@ static bool cmdpreview_may_show(CommandLineState *s)
|
||||
// open the preview window. The preview callback also handles doing the changes and highlights for
|
||||
// the preview.
|
||||
Error err = ERROR_INIT;
|
||||
try_start();
|
||||
cmdpreview_type = execute_cmd(&ea, &cmdinfo, true);
|
||||
if (try_end(&err)) {
|
||||
TRY_WRAP(&err, {
|
||||
cmdpreview_type = execute_cmd(&ea, &cmdinfo, true);
|
||||
});
|
||||
if (ERROR_SET(&err)) {
|
||||
api_clear_error(&err);
|
||||
cmdpreview_type = 0;
|
||||
}
|
||||
@ -2643,7 +2643,6 @@ end:
|
||||
static void do_autocmd_cmdlinechanged(int firstc)
|
||||
{
|
||||
if (has_event(EVENT_CMDLINECHANGED)) {
|
||||
TryState tstate;
|
||||
Error err = ERROR_INIT;
|
||||
save_v_event_T save_v_event;
|
||||
dict_T *dict = get_v_event(&save_v_event);
|
||||
@ -2656,13 +2655,11 @@ static void do_autocmd_cmdlinechanged(int firstc)
|
||||
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
|
||||
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
|
||||
tv_dict_set_keys_readonly(dict);
|
||||
try_enter(&tstate);
|
||||
|
||||
apply_autocmds(EVENT_CMDLINECHANGED, firstcbuf, firstcbuf, false, curbuf);
|
||||
restore_v_event(dict, &save_v_event);
|
||||
|
||||
bool tl_ret = try_leave(&tstate, &err);
|
||||
if (!tl_ret && ERROR_SET(&err)) {
|
||||
TRY_WRAP(&err, {
|
||||
apply_autocmds(EVENT_CMDLINECHANGED, firstcbuf, firstcbuf, false, curbuf);
|
||||
restore_v_event(dict, &save_v_event);
|
||||
});
|
||||
if (ERROR_SET(&err)) {
|
||||
msg_putchar('\n');
|
||||
msg_scroll = true;
|
||||
msg_puts_hl(err.msg, HLF_E, true);
|
||||
@ -3179,11 +3176,9 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
static int prev_prompt_errors = 0;
|
||||
Callback color_cb = CALLBACK_NONE;
|
||||
bool can_free_cb = false;
|
||||
TryState tstate;
|
||||
Error err = ERROR_INIT;
|
||||
const char *err_errmsg = e_intern2;
|
||||
bool dgc_ret = true;
|
||||
bool tl_ret = true;
|
||||
|
||||
if (colored_ccline->prompt_id != prev_prompt_id) {
|
||||
prev_prompt_errors = 0;
|
||||
@ -3196,16 +3191,16 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
assert(colored_ccline->input_fn);
|
||||
color_cb = colored_ccline->highlight_callback;
|
||||
} else if (colored_ccline->cmdfirstc == ':') {
|
||||
try_enter(&tstate);
|
||||
err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s");
|
||||
dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
|
||||
&color_cb);
|
||||
tl_ret = try_leave(&tstate, &err);
|
||||
TRY_WRAP(&err, {
|
||||
err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s");
|
||||
dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
|
||||
&color_cb);
|
||||
});
|
||||
can_free_cb = true;
|
||||
} else if (colored_ccline->cmdfirstc == '=') {
|
||||
color_expr_cmdline(colored_ccline, ccline_colors);
|
||||
}
|
||||
if (!tl_ret || !dgc_ret) {
|
||||
if (ERROR_SET(&err) || !dgc_ret) {
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
|
||||
@ -3226,20 +3221,22 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
// correct, with msg_col it just misses leading `:`. Since `redraw!` in
|
||||
// callback lags this is least of the user problems.
|
||||
//
|
||||
// Also using try_enter() because error messages may overwrite typed
|
||||
// Also using TRY_WRAP because error messages may overwrite typed
|
||||
// command-line which is not expected.
|
||||
getln_interrupted_highlight = false;
|
||||
try_enter(&tstate);
|
||||
err_errmsg = N_("E5407: Callback has thrown an exception: %s");
|
||||
const int saved_msg_col = msg_col;
|
||||
msg_silent++;
|
||||
const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
|
||||
msg_silent--;
|
||||
msg_col = saved_msg_col;
|
||||
if (got_int) {
|
||||
getln_interrupted_highlight = true;
|
||||
}
|
||||
if (!try_leave(&tstate, &err) || !cbcall_ret) {
|
||||
bool cbcall_ret = true;
|
||||
TRY_WRAP(&err, {
|
||||
err_errmsg = N_("E5407: Callback has thrown an exception: %s");
|
||||
const int saved_msg_col = msg_col;
|
||||
msg_silent++;
|
||||
cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
|
||||
msg_silent--;
|
||||
msg_col = saved_msg_col;
|
||||
if (got_int) {
|
||||
getln_interrupted_highlight = true;
|
||||
}
|
||||
});
|
||||
if (ERROR_SET(&err) || !cbcall_ret) {
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
if (tv.v_type != VAR_LIST) {
|
||||
|
@ -659,9 +659,8 @@ static int makeopens(FILE *fd, char *dirnow)
|
||||
&& buf->b_fname != NULL
|
||||
&& buf->b_p_bl) {
|
||||
if (fprintf(fd, "badd +%" PRId64 " ",
|
||||
buf->b_wininfo == NULL
|
||||
? 1
|
||||
: (int64_t)buf->b_wininfo->wi_mark.mark.lnum) < 0
|
||||
kv_size(buf->b_wininfo) == 0
|
||||
? 1 : (int64_t)kv_A(buf->b_wininfo, 0)->wi_mark.mark.lnum) < 0
|
||||
|| ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
@ -405,9 +405,6 @@ EXTERN buf_T *curbuf INIT( = NULL); // currently active buffer
|
||||
#define FOR_ALL_BUFFERS_BACKWARDS(buf) \
|
||||
for (buf_T *buf = lastbuf; buf != NULL; buf = buf->b_prev)
|
||||
|
||||
#define FOR_ALL_BUF_WININFO(buf, wip) \
|
||||
for ((wip) = (buf)->b_wininfo; (wip) != NULL; (wip) = (wip)->wi_next)
|
||||
|
||||
// List of files being edited (global argument list). curwin->w_alist points
|
||||
// to this when the window is using the global argument list.
|
||||
EXTERN alist_T global_alist; // global argument list
|
||||
|
@ -15,7 +15,6 @@ EXTERN const char *hlf_names[] INIT( = {
|
||||
[HLF_8] = "SpecialKey",
|
||||
[HLF_EOB] = "EndOfBuffer",
|
||||
[HLF_TERM] = "TermCursor",
|
||||
[HLF_TERMNC] = "TermCursorNC",
|
||||
[HLF_AT] = "NonText",
|
||||
[HLF_D] = "Directory",
|
||||
[HLF_E] = "ErrorMsg",
|
||||
|
@ -63,7 +63,6 @@ typedef enum {
|
||||
///< displayed different from what it is
|
||||
HLF_EOB, ///< after the last line in the buffer
|
||||
HLF_TERM, ///< terminal cursor focused
|
||||
HLF_TERMNC, ///< terminal cursor unfocused
|
||||
HLF_AT, ///< @ characters at end of screen, characters that don't really exist in the text
|
||||
HLF_D, ///< directories in CTRL-D listing
|
||||
HLF_E, ///< error messages
|
||||
|
@ -173,12 +173,12 @@ static const char *highlight_init_both[] = {
|
||||
"default link PmenuKind Pmenu",
|
||||
"default link PmenuKindSel PmenuSel",
|
||||
"default link PmenuSbar Pmenu",
|
||||
"default link ComplMatchIns Normal",
|
||||
"default link Substitute Search",
|
||||
"default link StatusLineTerm StatusLine",
|
||||
"default link StatusLineTermNC StatusLineNC",
|
||||
"default link TabLine StatusLineNC",
|
||||
"default link TabLineFill TabLine",
|
||||
"default link TermCursorNC NONE",
|
||||
"default link VertSplit WinSeparator",
|
||||
"default link VisualNOS Visual",
|
||||
"default link Whitespace NonText",
|
||||
|
@ -256,6 +256,7 @@ static pos_T compl_startpos;
|
||||
static int compl_length = 0;
|
||||
static colnr_T compl_col = 0; ///< column where the text starts
|
||||
///< that is being completed
|
||||
static colnr_T compl_ins_end_col = 0;
|
||||
static char *compl_orig_text = NULL; ///< text as it was before
|
||||
///< completion started
|
||||
/// Undo information to restore extmarks for original text.
|
||||
@ -282,6 +283,11 @@ static size_t spell_bad_len = 0; // length of located bad word
|
||||
|
||||
static int compl_selected_item = -1;
|
||||
|
||||
// "compl_match_array" points the currently displayed list of entries in the
|
||||
// popup menu. It is NULL when there is no popup menu.
|
||||
static pumitem_T *compl_match_array = NULL;
|
||||
static int compl_match_arraysize;
|
||||
|
||||
/// CTRL-X pressed in Insert mode.
|
||||
void ins_ctrl_x(void)
|
||||
{
|
||||
@ -756,7 +762,7 @@ int ins_compl_add_infercase(char *str_arg, int len, bool icase, char *fname, Dir
|
||||
|
||||
// "char_len" may be smaller than "compl_char_len" when using
|
||||
// thesaurus, only use the minimum when comparing.
|
||||
int min_len = char_len < compl_char_len ? char_len : compl_char_len;
|
||||
int min_len = MIN(char_len, compl_char_len);
|
||||
|
||||
str = ins_compl_infercase_gettext(str, char_len, compl_char_len, min_len, &tofree);
|
||||
}
|
||||
@ -943,6 +949,30 @@ static bool ins_compl_equal(compl_T *match, char *str, size_t len)
|
||||
return strncmp(match->cp_str, str, len) == 0;
|
||||
}
|
||||
|
||||
/// when len is -1 mean use whole length of p otherwise part of p
|
||||
static void ins_compl_insert_bytes(char *p, int len)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (len == -1) {
|
||||
len = (int)strlen(p);
|
||||
}
|
||||
assert(len >= 0);
|
||||
ins_bytes_len(p, (size_t)len);
|
||||
compl_ins_end_col = curwin->w_cursor.col - 1;
|
||||
}
|
||||
|
||||
/// Checks if the column is within the currently inserted completion text
|
||||
/// column range. If it is, it returns a special highlight attribute.
|
||||
/// -1 mean normal item.
|
||||
int ins_compl_col_range_attr(int col)
|
||||
{
|
||||
if (col >= compl_col && col < compl_ins_end_col) {
|
||||
return syn_name2attr("ComplMatchIns");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Reduce the longest common string for match "match".
|
||||
static void ins_compl_longest_match(compl_T *match)
|
||||
{
|
||||
@ -952,7 +982,7 @@ static void ins_compl_longest_match(compl_T *match)
|
||||
|
||||
bool had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete(false);
|
||||
ins_bytes(compl_leader + get_compl_len());
|
||||
ins_compl_insert_bytes(compl_leader + get_compl_len(), -1);
|
||||
ins_redraw(false);
|
||||
|
||||
// When the match isn't there (to avoid matching itself) remove it
|
||||
@ -986,7 +1016,7 @@ static void ins_compl_longest_match(compl_T *match)
|
||||
*p = NUL;
|
||||
bool had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete(false);
|
||||
ins_bytes(compl_leader + get_compl_len());
|
||||
ins_compl_insert_bytes(compl_leader + get_compl_len(), -1);
|
||||
ins_redraw(false);
|
||||
|
||||
// When the match isn't there (to avoid matching itself) remove it
|
||||
@ -1007,9 +1037,9 @@ static void ins_compl_add_matches(int num_matches, char **matches, int icase)
|
||||
Direction dir = compl_direction;
|
||||
|
||||
for (int i = 0; i < num_matches && add_r != FAIL; i++) {
|
||||
if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, false, NULL, dir,
|
||||
CP_FAST | (icase ? CP_ICASE : 0),
|
||||
false, NULL)) == OK) {
|
||||
add_r = ins_compl_add(matches[i], -1, NULL, NULL, false, NULL, dir,
|
||||
CP_FAST | (icase ? CP_ICASE : 0), false, NULL);
|
||||
if (add_r == OK) {
|
||||
// If dir was BACKWARD then honor it just once.
|
||||
dir = FORWARD;
|
||||
}
|
||||
@ -1058,11 +1088,6 @@ unsigned get_cot_flags(void)
|
||||
return curbuf->b_cot_flags != 0 ? curbuf->b_cot_flags : cot_flags;
|
||||
}
|
||||
|
||||
/// "compl_match_array" points the currently displayed list of entries in the
|
||||
/// popup menu. It is NULL when there is no popup menu.
|
||||
static pumitem_T *compl_match_array = NULL;
|
||||
static int compl_match_arraysize;
|
||||
|
||||
/// Remove any popup menu.
|
||||
static void ins_compl_del_pum(void)
|
||||
{
|
||||
@ -1277,21 +1302,15 @@ static int ins_compl_build_pum(void)
|
||||
i = 0;
|
||||
comp = match_head;
|
||||
while (comp != NULL) {
|
||||
if (comp->cp_text[CPT_ABBR] != NULL) {
|
||||
compl_match_array[i].pum_text = comp->cp_text[CPT_ABBR];
|
||||
} else {
|
||||
compl_match_array[i].pum_text = comp->cp_str;
|
||||
}
|
||||
compl_match_array[i].pum_text = comp->cp_text[CPT_ABBR] != NULL
|
||||
? comp->cp_text[CPT_ABBR] : comp->cp_str;
|
||||
compl_match_array[i].pum_kind = comp->cp_text[CPT_KIND];
|
||||
compl_match_array[i].pum_info = comp->cp_text[CPT_INFO];
|
||||
compl_match_array[i].pum_score = comp->cp_score;
|
||||
compl_match_array[i].pum_user_abbr_hlattr = comp->cp_user_abbr_hlattr;
|
||||
compl_match_array[i].pum_user_kind_hlattr = comp->cp_user_kind_hlattr;
|
||||
if (comp->cp_text[CPT_MENU] != NULL) {
|
||||
compl_match_array[i++].pum_extra = comp->cp_text[CPT_MENU];
|
||||
} else {
|
||||
compl_match_array[i++].pum_extra = comp->cp_fname;
|
||||
}
|
||||
compl_match_array[i++].pum_extra = comp->cp_text[CPT_MENU] != NULL
|
||||
? comp->cp_text[CPT_MENU] : comp->cp_fname;
|
||||
compl_T *match_next = comp->cp_match_next;
|
||||
comp->cp_match_next = NULL;
|
||||
comp = match_next;
|
||||
@ -1578,11 +1597,7 @@ static void ins_compl_files(int count, char **files, bool thesaurus, int flags,
|
||||
char *ptr = buf;
|
||||
while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) {
|
||||
ptr = regmatch->startp[0];
|
||||
if (ctrl_x_mode_line_or_eval()) {
|
||||
ptr = find_line_end(ptr);
|
||||
} else {
|
||||
ptr = find_word_end(ptr);
|
||||
}
|
||||
ptr = ctrl_x_mode_line_or_eval() ? find_line_end(ptr) : find_word_end(ptr);
|
||||
int add_r = ins_compl_add_infercase(regmatch->startp[0],
|
||||
(int)(ptr - regmatch->startp[0]),
|
||||
p_ic, files[i], *dir, false);
|
||||
@ -1688,6 +1703,7 @@ void ins_compl_clear(void)
|
||||
compl_cont_status = 0;
|
||||
compl_started = false;
|
||||
compl_matches = 0;
|
||||
compl_ins_end_col = 0;
|
||||
XFREE_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
XFREE_CLEAR(compl_leader);
|
||||
@ -1812,7 +1828,7 @@ static void ins_compl_new_leader(void)
|
||||
{
|
||||
ins_compl_del_pum();
|
||||
ins_compl_delete(true);
|
||||
ins_bytes(compl_leader + get_compl_len());
|
||||
ins_compl_insert_bytes(compl_leader + get_compl_len(), -1);
|
||||
compl_used_match = false;
|
||||
|
||||
if (compl_started) {
|
||||
@ -2147,7 +2163,7 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
|
||||
const int compl_len = get_compl_len();
|
||||
const int len = (int)strlen(p);
|
||||
if (len > compl_len) {
|
||||
ins_bytes_len(p + compl_len, (size_t)(len - compl_len));
|
||||
ins_compl_insert_bytes(p + compl_len, len - compl_len);
|
||||
}
|
||||
}
|
||||
restore_orig_extmarks();
|
||||
@ -3649,7 +3665,7 @@ void ins_compl_insert(bool in_compl_func)
|
||||
// Make sure we don't go over the end of the string, this can happen with
|
||||
// illegal bytes.
|
||||
if (compl_len < (int)strlen(compl_shown_match->cp_str)) {
|
||||
ins_bytes(compl_shown_match->cp_str + compl_len);
|
||||
ins_compl_insert_bytes(compl_shown_match->cp_str + compl_len, -1);
|
||||
}
|
||||
compl_used_match = !match_at_original_text(compl_shown_match);
|
||||
|
||||
@ -3898,14 +3914,15 @@ static int ins_compl_next(bool allow_get_expansion, int count, bool insert_match
|
||||
|
||||
// Insert the text of the new completion, or the compl_leader.
|
||||
if (compl_no_insert && !started) {
|
||||
ins_bytes(compl_orig_text + get_compl_len());
|
||||
ins_compl_insert_bytes(compl_orig_text + get_compl_len(), -1);
|
||||
compl_used_match = false;
|
||||
restore_orig_extmarks();
|
||||
} else if (insert_match) {
|
||||
if (!compl_get_longest || compl_used_match) {
|
||||
ins_compl_insert(in_compl_func);
|
||||
} else {
|
||||
ins_bytes(compl_leader + get_compl_len());
|
||||
assert(compl_leader != NULL);
|
||||
ins_compl_insert_bytes(compl_leader + get_compl_len(), -1);
|
||||
}
|
||||
if (!strcmp(compl_curr_match->cp_str, compl_orig_text)) {
|
||||
restore_orig_extmarks();
|
||||
|
@ -623,38 +623,32 @@ static int nlua_with(lua_State *L)
|
||||
cmdmod.cmod_flags = flags;
|
||||
apply_cmdmod(&cmdmod);
|
||||
|
||||
if (buf || win) {
|
||||
try_start();
|
||||
}
|
||||
|
||||
aco_save_T aco;
|
||||
win_execute_T win_execute_args;
|
||||
Error err = ERROR_INIT;
|
||||
TRY_WRAP(&err, {
|
||||
aco_save_T aco;
|
||||
win_execute_T win_execute_args;
|
||||
|
||||
if (win) {
|
||||
tabpage_T *tabpage = win_find_tabpage(win);
|
||||
if (!win_execute_before(&win_execute_args, win, tabpage)) {
|
||||
goto end;
|
||||
if (win) {
|
||||
tabpage_T *tabpage = win_find_tabpage(win);
|
||||
if (!win_execute_before(&win_execute_args, win, tabpage)) {
|
||||
goto end;
|
||||
}
|
||||
} else if (buf) {
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
}
|
||||
} else if (buf) {
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
}
|
||||
|
||||
int s = lua_gettop(L);
|
||||
lua_pushvalue(L, 2);
|
||||
status = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||
rets = lua_gettop(L) - s;
|
||||
int s = lua_gettop(L);
|
||||
lua_pushvalue(L, 2);
|
||||
status = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||
rets = lua_gettop(L) - s;
|
||||
|
||||
if (win) {
|
||||
win_execute_after(&win_execute_args);
|
||||
} else if (buf) {
|
||||
aucmd_restbuf(&aco);
|
||||
}
|
||||
|
||||
end:
|
||||
if (buf || win) {
|
||||
try_end(&err);
|
||||
}
|
||||
if (win) {
|
||||
win_execute_after(&win_execute_args);
|
||||
} else if (buf) {
|
||||
aucmd_restbuf(&aco);
|
||||
}
|
||||
end:;
|
||||
});
|
||||
|
||||
undo_cmdmod(&cmdmod);
|
||||
cmdmod = save_cmdmod;
|
||||
|
@ -5038,6 +5038,9 @@ static void nv_visual(cmdarg_T *cap)
|
||||
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
|
||||
curwin->w_curswant += resel_VIsual_vcol * cap->count0 - 1;
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
if (*p_sel == 'e') {
|
||||
curwin->w_curswant++;
|
||||
}
|
||||
coladvance(curwin, curwin->w_curswant);
|
||||
} else {
|
||||
curwin->w_set_curswant = true;
|
||||
|
@ -3933,7 +3933,7 @@ static bool switch_option_context(void *const ctx, OptScope scope, void *const f
|
||||
== FAIL) {
|
||||
restore_win_noblock(switchwin, true);
|
||||
|
||||
if (try_end(err)) {
|
||||
if (ERROR_SET(err)) {
|
||||
return false;
|
||||
}
|
||||
api_set_error(err, kErrorTypeException, "Problem while switching windows");
|
||||
|
@ -12,7 +12,7 @@
|
||||
// option_vars.h: definition of global variables for settable options
|
||||
|
||||
#define HIGHLIGHT_INIT \
|
||||
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \
|
||||
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,@:NonText,d:Directory,e:ErrorMsg," \
|
||||
"i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow," \
|
||||
"N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC," \
|
||||
"c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
|
||||
|
@ -3631,7 +3631,9 @@ return {
|
||||
{
|
||||
abbreviation = 'gcr',
|
||||
cb = 'did_set_guicursor',
|
||||
defaults = { if_true = 'n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20' },
|
||||
defaults = {
|
||||
if_true = 'n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor',
|
||||
},
|
||||
deny_duplicates = true,
|
||||
desc = [=[
|
||||
Configures the cursor style for each mode. Works in the GUI and many
|
||||
@ -3660,6 +3662,7 @@ return {
|
||||
ci Command-line Insert mode
|
||||
cr Command-line Replace mode
|
||||
sm showmatch in Insert mode
|
||||
t Terminal mode
|
||||
a all modes
|
||||
The argument-list is a dash separated list of these arguments:
|
||||
hor{N} horizontal bar, {N} percent of the character height
|
||||
@ -3676,7 +3679,8 @@ return {
|
||||
cursor is not shown. Times are in msec. When one of
|
||||
the numbers is zero, there is no blinking. E.g.: >vim
|
||||
set guicursor=n:blinkon0
|
||||
< - Default is "blinkon0" for each mode.
|
||||
<
|
||||
Default is "blinkon0" for each mode.
|
||||
{group-name}
|
||||
Highlight group that decides the color and font of the
|
||||
cursor.
|
||||
@ -7011,6 +7015,8 @@ return {
|
||||
selection.
|
||||
When "old" is used and 'virtualedit' allows the cursor to move past
|
||||
the end of line the line break still isn't included.
|
||||
When "exclusive" is used, cursor position in visual mode will be
|
||||
adjusted for inclusive motions |inclusive-motion-selection-exclusive|.
|
||||
Note that when "exclusive" is used and selecting from the end
|
||||
backwards, you cannot include the last character of a line, when
|
||||
starting in Normal mode and 'virtualedit' empty.
|
||||
|
@ -234,12 +234,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
}
|
||||
|
||||
// Figure out the size and position of the pum.
|
||||
if (size < PUM_DEF_HEIGHT) {
|
||||
pum_height = size;
|
||||
} else {
|
||||
pum_height = PUM_DEF_HEIGHT;
|
||||
}
|
||||
|
||||
pum_height = MIN(size, PUM_DEF_HEIGHT);
|
||||
if (p_ph > 0 && pum_height > p_ph) {
|
||||
pum_height = (int)p_ph;
|
||||
}
|
||||
@ -256,11 +251,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
context_lines = 0;
|
||||
} else {
|
||||
// Leave two lines of context if possible
|
||||
if (curwin->w_wrow - curwin->w_cline_row >= 2) {
|
||||
context_lines = 2;
|
||||
} else {
|
||||
context_lines = curwin->w_wrow - curwin->w_cline_row;
|
||||
}
|
||||
context_lines = MIN(2, curwin->w_wrow - curwin->w_cline_row);
|
||||
}
|
||||
|
||||
if (pum_win_row - min_row >= size + context_lines) {
|
||||
@ -285,20 +276,13 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
} else {
|
||||
// Leave two lines of context if possible
|
||||
validate_cheight(curwin);
|
||||
if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) {
|
||||
context_lines = 3;
|
||||
} else {
|
||||
context_lines = curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow;
|
||||
}
|
||||
int cline_visible_offset = curwin->w_cline_row +
|
||||
curwin->w_cline_height - curwin->w_wrow;
|
||||
context_lines = MIN(3, cline_visible_offset);
|
||||
}
|
||||
|
||||
pum_row = pum_win_row + context_lines;
|
||||
if (size > below_row - pum_row) {
|
||||
pum_height = below_row - pum_row;
|
||||
} else {
|
||||
pum_height = size;
|
||||
}
|
||||
|
||||
pum_height = MIN(below_row - pum_row, size);
|
||||
if (p_ph > 0 && pum_height > p_ph) {
|
||||
pum_height = (int)p_ph;
|
||||
}
|
||||
@ -353,15 +337,10 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
pum_width = max_col - pum_col - pum_scrollbar;
|
||||
}
|
||||
|
||||
if (pum_width > max_width + pum_kind_width + pum_extra_width + 1
|
||||
&& pum_width > p_pw) {
|
||||
// the width is more than needed for the items, make it
|
||||
// narrower
|
||||
pum_width = max_width + pum_kind_width + pum_extra_width + 1;
|
||||
|
||||
if (pum_width < p_pw) {
|
||||
pum_width = (int)p_pw;
|
||||
}
|
||||
int content_width = max_width + pum_kind_width + pum_extra_width + 1;
|
||||
if (pum_width > content_width && pum_width > p_pw) {
|
||||
// Reduce width to fit item
|
||||
pum_width = MAX(content_width, (int)p_pw);
|
||||
} else if (((cursor_col - min_col > p_pw
|
||||
|| cursor_col - min_col > max_width) && !pum_rl)
|
||||
|| (pum_rl && (cursor_col < max_col - p_pw
|
||||
@ -373,13 +352,10 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
pum_col = max_col - 1;
|
||||
}
|
||||
} else if (!pum_rl) {
|
||||
if (win_start_col > max_col - max_width - pum_scrollbar
|
||||
&& max_width <= p_pw) {
|
||||
int right_edge_col = max_col - max_width - pum_scrollbar;
|
||||
if (win_start_col > right_edge_col && max_width <= p_pw) {
|
||||
// use full width to end of the screen
|
||||
pum_col = max_col - max_width - pum_scrollbar;
|
||||
if (pum_col < min_col) {
|
||||
pum_col = min_col;
|
||||
}
|
||||
pum_col = MAX(min_col, right_edge_col);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,12 +376,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
pum_width = max_col - pum_col - 1;
|
||||
}
|
||||
}
|
||||
} else if (pum_width > max_width + pum_kind_width + pum_extra_width + 1
|
||||
&& pum_width > p_pw) {
|
||||
pum_width = max_width + pum_kind_width + pum_extra_width + 1;
|
||||
if (pum_width < p_pw) {
|
||||
pum_width = (int)p_pw;
|
||||
}
|
||||
} else if (pum_width > content_width && pum_width > p_pw) {
|
||||
pum_width = MAX(content_width, (int)p_pw);
|
||||
}
|
||||
}
|
||||
} else if (max_col - min_col < def_width) {
|
||||
@ -997,9 +969,7 @@ static bool pum_set_selected(int n, int repeat)
|
||||
}
|
||||
}
|
||||
// adjust for the number of lines displayed
|
||||
if (pum_first > pum_size - pum_height) {
|
||||
pum_first = pum_size - pum_height;
|
||||
}
|
||||
pum_first = MIN(pum_first, pum_size - pum_height);
|
||||
|
||||
// Show extra info in the preview window if there is something and
|
||||
// 'completeopt' contains "preview".
|
||||
|
@ -138,14 +138,20 @@ void state_handle_k_event(void)
|
||||
/// Return true if in the current mode we need to use virtual.
|
||||
bool virtual_active(win_T *wp)
|
||||
{
|
||||
unsigned cur_ve_flags = get_ve_flags(wp);
|
||||
|
||||
// While an operator is being executed we return "virtual_op", because
|
||||
// VIsual_active has already been reset, thus we can't check for "block"
|
||||
// being used.
|
||||
if (virtual_op != kNone) {
|
||||
return virtual_op;
|
||||
}
|
||||
|
||||
// In Terminal mode the cursor can be positioned anywhere by the application
|
||||
if (State & MODE_TERMINAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned cur_ve_flags = get_ve_flags(wp);
|
||||
|
||||
return cur_ve_flags == kOptVeFlagAll
|
||||
|| ((cur_ve_flags & kOptVeFlagBlock) && VIsual_active && VIsual_mode == Ctrl_V)
|
||||
|| ((cur_ve_flags & kOptVeFlagInsert) && (State & MODE_INSERT));
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "nvim/channel.h"
|
||||
#include "nvim/channel_defs.h"
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/cursor_shape.h"
|
||||
#include "nvim/drawline.h"
|
||||
#include "nvim/drawscreen.h"
|
||||
#include "nvim/eval.h"
|
||||
@ -160,15 +161,19 @@ struct terminal {
|
||||
int invalid_start, invalid_end; // invalid rows in libvterm screen
|
||||
struct {
|
||||
int row, col;
|
||||
int shape;
|
||||
bool visible;
|
||||
bool blink;
|
||||
} cursor;
|
||||
bool pending_resize; // pending width/height
|
||||
|
||||
struct {
|
||||
bool resize; ///< pending width/height
|
||||
bool cursor; ///< pending cursor shape or blink change
|
||||
StringBuilder *send; ///< When there is a pending TermRequest autocommand, block and store input.
|
||||
} pending;
|
||||
|
||||
bool color_set[16];
|
||||
|
||||
// When there is a pending TermRequest autocommand, block and store input.
|
||||
StringBuilder *pending_send;
|
||||
|
||||
char *selection_buffer; /// libvterm selection buffer
|
||||
StringBuilder selection; /// Growable array containing full selection data
|
||||
|
||||
@ -207,24 +212,24 @@ static void emit_termrequest(void **argv)
|
||||
apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, false, AUGROUP_ALL, buf, NULL, &data);
|
||||
xfree(payload);
|
||||
|
||||
StringBuilder *term_pending_send = term->pending_send;
|
||||
term->pending_send = NULL;
|
||||
StringBuilder *term_pending_send = term->pending.send;
|
||||
term->pending.send = NULL;
|
||||
if (kv_size(*pending_send)) {
|
||||
terminal_send(term, pending_send->items, pending_send->size);
|
||||
kv_destroy(*pending_send);
|
||||
}
|
||||
if (term_pending_send != pending_send) {
|
||||
term->pending_send = term_pending_send;
|
||||
term->pending.send = term_pending_send;
|
||||
}
|
||||
xfree(pending_send);
|
||||
}
|
||||
|
||||
static void schedule_termrequest(Terminal *term, char *payload, size_t payload_length)
|
||||
{
|
||||
term->pending_send = xmalloc(sizeof(StringBuilder));
|
||||
kv_init(*term->pending_send);
|
||||
term->pending.send = xmalloc(sizeof(StringBuilder));
|
||||
kv_init(*term->pending.send);
|
||||
multiqueue_put(main_loop.events, emit_termrequest, term, payload, (void *)payload_length,
|
||||
term->pending_send);
|
||||
term->pending.send);
|
||||
}
|
||||
|
||||
static int parse_osc8(VTermStringFragment frag, int *attr)
|
||||
@ -363,7 +368,7 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts)
|
||||
// Create a new terminal instance and configure it
|
||||
Terminal *term = *termpp = xcalloc(1, sizeof(Terminal));
|
||||
term->opts = opts;
|
||||
term->cursor.visible = true;
|
||||
|
||||
// Associate the terminal instance with the new buffer
|
||||
term->buf_handle = buf->handle;
|
||||
buf->terminal = term;
|
||||
@ -387,6 +392,28 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts)
|
||||
vterm_state_set_selection_callbacks(state, &vterm_selection_callbacks, term,
|
||||
term->selection_buffer, SELECTIONBUF_SIZE);
|
||||
|
||||
VTermValue cursor_shape;
|
||||
switch (shape_table[SHAPE_IDX_TERM].shape) {
|
||||
case SHAPE_BLOCK:
|
||||
cursor_shape.number = VTERM_PROP_CURSORSHAPE_BLOCK;
|
||||
break;
|
||||
case SHAPE_HOR:
|
||||
cursor_shape.number = VTERM_PROP_CURSORSHAPE_UNDERLINE;
|
||||
break;
|
||||
case SHAPE_VER:
|
||||
cursor_shape.number = VTERM_PROP_CURSORSHAPE_BAR_LEFT;
|
||||
break;
|
||||
}
|
||||
vterm_state_set_termprop(state, VTERM_PROP_CURSORSHAPE, &cursor_shape);
|
||||
|
||||
VTermValue cursor_blink;
|
||||
if (shape_table[SHAPE_IDX_TERM].blinkon != 0 && shape_table[SHAPE_IDX_TERM].blinkoff != 0) {
|
||||
cursor_blink.boolean = true;
|
||||
} else {
|
||||
cursor_blink.boolean = false;
|
||||
}
|
||||
vterm_state_set_termprop(state, VTERM_PROP_CURSORBLINK, &cursor_blink);
|
||||
|
||||
// force a initial refresh of the screen to ensure the buffer will always
|
||||
// have as many lines as screen rows when refresh_scrollback is called
|
||||
term->invalid_start = 0;
|
||||
@ -565,7 +592,7 @@ void terminal_check_size(Terminal *term)
|
||||
|
||||
vterm_set_size(term->vt, height, width);
|
||||
vterm_screen_flush_damage(term->vts);
|
||||
term->pending_resize = true;
|
||||
term->pending.resize = true;
|
||||
invalidate_terminal(term, -1, -1);
|
||||
}
|
||||
|
||||
@ -614,16 +641,28 @@ bool terminal_enter(void)
|
||||
curwin->w_p_so = 0;
|
||||
curwin->w_p_siso = 0;
|
||||
|
||||
// Save the existing cursor entry since it may be modified by the application
|
||||
cursorentry_T save_cursorentry = shape_table[SHAPE_IDX_TERM];
|
||||
|
||||
// Update the cursor shape table and flush changes to the UI
|
||||
s->term->pending.cursor = true;
|
||||
refresh_cursor(s->term);
|
||||
|
||||
adjust_topline(s->term, buf, 0); // scroll to end
|
||||
// erase the unfocused cursor
|
||||
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
|
||||
showmode();
|
||||
curwin->w_redr_status = true; // For mode() in statusline. #8323
|
||||
redraw_custom_title_later();
|
||||
ui_busy_start();
|
||||
if (!s->term->cursor.visible) {
|
||||
// Hide cursor if it should be hidden
|
||||
ui_busy_start();
|
||||
}
|
||||
ui_cursor_shape();
|
||||
apply_autocmds(EVENT_TERMENTER, NULL, NULL, false, curbuf);
|
||||
may_trigger_modechanged();
|
||||
|
||||
// Tell the terminal it has focus
|
||||
terminal_focus(s->term, true);
|
||||
|
||||
s->state.execute = terminal_execute;
|
||||
s->state.check = terminal_check;
|
||||
state_enter(&s->state);
|
||||
@ -635,6 +674,9 @@ bool terminal_enter(void)
|
||||
RedrawingDisabled = s->save_rd;
|
||||
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
|
||||
|
||||
shape_table[SHAPE_IDX_TERM] = save_cursorentry;
|
||||
ui_mode_info_set();
|
||||
|
||||
if (save_curwin == curwin->handle) { // Else: window was closed.
|
||||
curwin->w_p_cul = save_w_p_cul;
|
||||
if (save_w_p_culopt) {
|
||||
@ -649,8 +691,9 @@ bool terminal_enter(void)
|
||||
free_string_option(save_w_p_culopt);
|
||||
}
|
||||
|
||||
// draw the unfocused cursor
|
||||
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
|
||||
// Tell the terminal it lost focus
|
||||
terminal_focus(s->term, false);
|
||||
|
||||
if (curbuf->terminal == s->term && !s->close) {
|
||||
terminal_check_cursor();
|
||||
}
|
||||
@ -659,7 +702,11 @@ bool terminal_enter(void)
|
||||
} else {
|
||||
unshowmode(true);
|
||||
}
|
||||
ui_busy_stop();
|
||||
if (!s->term->cursor.visible) {
|
||||
// If cursor was hidden, show it again
|
||||
ui_busy_stop();
|
||||
}
|
||||
ui_cursor_shape();
|
||||
if (s->close) {
|
||||
bool wipe = s->term->buf_handle != 0;
|
||||
s->term->destroy = true;
|
||||
@ -810,6 +857,19 @@ static int terminal_execute(VimState *state, int key)
|
||||
return 0;
|
||||
}
|
||||
if (s->term != curbuf->terminal) {
|
||||
// Active terminal buffer changed, flush terminal's cursor state to the UI
|
||||
curbuf->terminal->pending.cursor = true;
|
||||
|
||||
if (!s->term->cursor.visible) {
|
||||
// If cursor was hidden, show it again
|
||||
ui_busy_stop();
|
||||
}
|
||||
|
||||
if (!curbuf->terminal->cursor.visible) {
|
||||
// Hide cursor if it should be hidden
|
||||
ui_busy_start();
|
||||
}
|
||||
|
||||
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
|
||||
invalidate_terminal(curbuf->terminal,
|
||||
curbuf->terminal->cursor.row,
|
||||
@ -857,8 +917,8 @@ static void terminal_send(Terminal *term, const char *data, size_t size)
|
||||
if (term->closed) {
|
||||
return;
|
||||
}
|
||||
if (term->pending_send) {
|
||||
kv_concat_len(*term->pending_send, data, size);
|
||||
if (term->pending.send) {
|
||||
kv_concat_len(*term->pending.send, data, size);
|
||||
return;
|
||||
}
|
||||
term->opts.write_cb(data, size, term->opts.data);
|
||||
@ -1063,14 +1123,6 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, int *te
|
||||
attr_id = hl_combine_attr(attr_id, cell.uri);
|
||||
}
|
||||
|
||||
if (term->cursor.visible && term->cursor.row == row
|
||||
&& term->cursor.col == col) {
|
||||
attr_id = hl_combine_attr(attr_id,
|
||||
is_focused(term) && wp == curwin
|
||||
? win_hl_attr(wp, HLF_TERM)
|
||||
: win_hl_attr(wp, HLF_TERMNC));
|
||||
}
|
||||
|
||||
term_attrs[col] = attr_id;
|
||||
}
|
||||
}
|
||||
@ -1085,6 +1137,17 @@ bool terminal_running(const Terminal *term)
|
||||
return !term->closed;
|
||||
}
|
||||
|
||||
static void terminal_focus(const Terminal *term, bool focus)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
VTermState *state = vterm_obtain_state(term->vt);
|
||||
if (focus) {
|
||||
vterm_state_focus_in(state);
|
||||
} else {
|
||||
vterm_state_focus_out(state);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// libvterm callbacks {{{
|
||||
|
||||
@ -1106,8 +1169,7 @@ static int term_movecursor(VTermPos new_pos, VTermPos old_pos, int visible, void
|
||||
Terminal *term = data;
|
||||
term->cursor.row = new_pos.row;
|
||||
term->cursor.col = new_pos.col;
|
||||
invalidate_terminal(term, old_pos.row, old_pos.row + 1);
|
||||
invalidate_terminal(term, new_pos.row, new_pos.row + 1);
|
||||
invalidate_terminal(term, -1, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1135,8 +1197,17 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
|
||||
break;
|
||||
|
||||
case VTERM_PROP_CURSORVISIBLE:
|
||||
if (is_focused(term)) {
|
||||
if (!val->boolean && term->cursor.visible) {
|
||||
// Hide the cursor
|
||||
ui_busy_start();
|
||||
} else if (val->boolean && !term->cursor.visible) {
|
||||
// Unhide the cursor
|
||||
ui_busy_stop();
|
||||
}
|
||||
invalidate_terminal(term, -1, -1);
|
||||
}
|
||||
term->cursor.visible = val->boolean;
|
||||
invalidate_terminal(term, term->cursor.row, term->cursor.row + 1);
|
||||
break;
|
||||
|
||||
case VTERM_PROP_TITLE: {
|
||||
@ -1172,6 +1243,18 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
|
||||
term->forward_mouse = (bool)val->number;
|
||||
break;
|
||||
|
||||
case VTERM_PROP_CURSORBLINK:
|
||||
term->cursor.blink = val->boolean;
|
||||
term->pending.cursor = true;
|
||||
invalidate_terminal(term, -1, -1);
|
||||
break;
|
||||
|
||||
case VTERM_PROP_CURSORSHAPE:
|
||||
term->cursor.shape = val->number;
|
||||
term->pending.cursor = true;
|
||||
invalidate_terminal(term, -1, -1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -1849,12 +1932,47 @@ static void refresh_terminal(Terminal *term)
|
||||
refresh_size(term, buf);
|
||||
refresh_scrollback(term, buf);
|
||||
refresh_screen(term, buf);
|
||||
refresh_cursor(term);
|
||||
aucmd_restbuf(&aco);
|
||||
|
||||
int ml_added = buf->b_ml.ml_line_count - ml_before;
|
||||
adjust_topline(term, buf, ml_added);
|
||||
}
|
||||
|
||||
static void refresh_cursor(Terminal *term)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (!is_focused(term) || !term->pending.cursor) {
|
||||
return;
|
||||
}
|
||||
term->pending.cursor = false;
|
||||
|
||||
if (term->cursor.blink) {
|
||||
// For the TUI, this value doesn't actually matter, as long as it's non-zero. The terminal
|
||||
// emulator dictates the blink frequency, not the application.
|
||||
// For GUIs we just pick an arbitrary value, for now.
|
||||
shape_table[SHAPE_IDX_TERM].blinkon = 500;
|
||||
shape_table[SHAPE_IDX_TERM].blinkoff = 500;
|
||||
} else {
|
||||
shape_table[SHAPE_IDX_TERM].blinkon = 0;
|
||||
shape_table[SHAPE_IDX_TERM].blinkoff = 0;
|
||||
}
|
||||
|
||||
switch (term->cursor.shape) {
|
||||
case VTERM_PROP_CURSORSHAPE_BLOCK:
|
||||
shape_table[SHAPE_IDX_TERM].shape = SHAPE_BLOCK;
|
||||
break;
|
||||
case VTERM_PROP_CURSORSHAPE_UNDERLINE:
|
||||
shape_table[SHAPE_IDX_TERM].shape = SHAPE_HOR;
|
||||
break;
|
||||
case VTERM_PROP_CURSORSHAPE_BAR_LEFT:
|
||||
shape_table[SHAPE_IDX_TERM].shape = SHAPE_VER;
|
||||
break;
|
||||
}
|
||||
|
||||
ui_mode_info_set();
|
||||
}
|
||||
|
||||
/// Calls refresh_terminal() on all invalidated_terminals.
|
||||
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
||||
{
|
||||
@ -1875,11 +1993,11 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
||||
|
||||
static void refresh_size(Terminal *term, buf_T *buf)
|
||||
{
|
||||
if (!term->pending_resize || term->closed) {
|
||||
if (!term->pending.resize || term->closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
term->pending_resize = false;
|
||||
term->pending.resize = false;
|
||||
int width, height;
|
||||
vterm_get_size(term->vt, &height, &width);
|
||||
term->invalid_start = 0;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/textformat.h"
|
||||
#include "nvim/textobject.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/undo.h"
|
||||
#include "nvim/vim_defs.h"
|
||||
#include "nvim/window.h"
|
||||
@ -1049,12 +1050,18 @@ void format_lines(linenr_T line_count, bool avoid_fex)
|
||||
State = MODE_INSERT; // for open_line()
|
||||
smd_save = p_smd;
|
||||
p_smd = false;
|
||||
|
||||
insertchar(NUL, INSCHAR_FORMAT
|
||||
+ (do_comments ? INSCHAR_DO_COM : 0)
|
||||
+ (do_comments && do_comments_list ? INSCHAR_COM_LIST : 0)
|
||||
+ (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
|
||||
|
||||
State = old_State;
|
||||
p_smd = smd_save;
|
||||
// Cursor shape may have been updated (e.g. by :normal) in insertchar(),
|
||||
// so it needs to be updated here.
|
||||
ui_cursor_shape();
|
||||
|
||||
second_indent = -1;
|
||||
// at end of par.: need to set indent of next par.
|
||||
need_set_indent = is_end_par;
|
||||
|
@ -1339,7 +1339,7 @@ static void tui_set_mode(TUIData *tui, ModeShape mode)
|
||||
case SHAPE_VER:
|
||||
shape = 5; break;
|
||||
}
|
||||
UNIBI_SET_NUM_VAR(tui->params[0], shape + (int)(c.blinkon == 0));
|
||||
UNIBI_SET_NUM_VAR(tui->params[0], shape + (int)(c.blinkon == 0 || c.blinkoff == 0));
|
||||
unibi_out_ext(tui, tui->unibi_ext.set_cursor_style);
|
||||
}
|
||||
|
||||
|
@ -1862,6 +1862,7 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
|
||||
u_oldcount = -1;
|
||||
}
|
||||
|
||||
msg_ext_set_kind("undo");
|
||||
int count = startcount;
|
||||
while (count--) {
|
||||
// Do the change warning now, so that it triggers FileChangedRO when
|
||||
|
@ -746,40 +746,28 @@ void win_set_buf(win_T *win, buf_T *buf, Error *err)
|
||||
RedrawingDisabled++;
|
||||
|
||||
switchwin_T switchwin;
|
||||
if (switch_win_noblock(&switchwin, win, tab, true) == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to window %d",
|
||||
win->handle);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
try_start();
|
||||
TRY_WRAP(err, {
|
||||
int win_result = switch_win_noblock(&switchwin, win, tab, true);
|
||||
if (win_result != FAIL) {
|
||||
const int save_acd = p_acd;
|
||||
if (!switchwin.sw_same_win) {
|
||||
// Temporarily disable 'autochdir' when setting buffer in another window.
|
||||
p_acd = false;
|
||||
}
|
||||
|
||||
const int save_acd = p_acd;
|
||||
if (!switchwin.sw_same_win) {
|
||||
// Temporarily disable 'autochdir' when setting buffer in another window.
|
||||
p_acd = false;
|
||||
}
|
||||
do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
|
||||
|
||||
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
|
||||
|
||||
if (!switchwin.sw_same_win) {
|
||||
p_acd = save_acd;
|
||||
}
|
||||
|
||||
if (!try_end(err) && result == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to set buffer %d",
|
||||
buf->handle);
|
||||
}
|
||||
if (!switchwin.sw_same_win) {
|
||||
p_acd = save_acd;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// If window is not current, state logic will not validate its cursor. So do it now.
|
||||
// Still needed if do_buffer returns FAIL (e.g: autocmds abort script after buffer was set).
|
||||
validate_cursor(curwin);
|
||||
|
||||
cleanup:
|
||||
restore_win_noblock(&switchwin, true);
|
||||
RedrawingDisabled--;
|
||||
}
|
||||
@ -5175,8 +5163,8 @@ win_T *win_alloc(win_T *after, bool hidden)
|
||||
return new_wp;
|
||||
}
|
||||
|
||||
// Free one wininfo_T.
|
||||
void free_wininfo(wininfo_T *wip, buf_T *bp)
|
||||
// Free one WinInfo.
|
||||
void free_wininfo(WinInfo *wip, buf_T *bp)
|
||||
{
|
||||
if (wip->wi_optset) {
|
||||
clear_winopt(&wip->wi_opt);
|
||||
@ -5241,30 +5229,24 @@ void win_free(win_T *wp, tabpage_T *tp)
|
||||
// Remove the window from the b_wininfo lists, it may happen that the
|
||||
// freed memory is re-used for another window.
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
for (wininfo_T *wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
|
||||
WinInfo *wip_wp = NULL;
|
||||
size_t pos_null = kv_size(buf->b_wininfo);
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||
if (wip->wi_win == wp) {
|
||||
wininfo_T *wip2;
|
||||
wip_wp = wip;
|
||||
} else if (wip->wi_win == NULL) {
|
||||
pos_null = i;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (wip2->wi_next != NULL) {
|
||||
wip2->wi_next->wi_prev = wip2->wi_prev;
|
||||
}
|
||||
if (wip2->wi_prev == NULL) {
|
||||
buf->b_wininfo = wip2->wi_next;
|
||||
} else {
|
||||
wip2->wi_prev->wi_next = wip2->wi_next;
|
||||
}
|
||||
free_wininfo(wip2, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wip->wi_win = NULL;
|
||||
if (wip_wp) {
|
||||
wip_wp->wi_win = NULL;
|
||||
// If there already is an entry with "wi_win" set to NULL it
|
||||
// must be removed, it would never be used.
|
||||
if (pos_null < kv_size(buf->b_wininfo)) {
|
||||
free_wininfo(kv_A(buf->b_wininfo, pos_null), buf);
|
||||
kv_shift(buf->b_wininfo, pos_null, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1731,7 +1731,7 @@ describe('API/extmarks', function()
|
||||
-- mark with invalidate is removed
|
||||
command('d2')
|
||||
screen:expect([[
|
||||
S2^aaa bbb ccc |
|
||||
{7:S2}^aaa bbb ccc |
|
||||
{7: }aaa bbb ccc |*3
|
||||
{7: } |
|
||||
|
|
||||
@ -1739,9 +1739,9 @@ describe('API/extmarks', function()
|
||||
-- mark is restored with undo_restore == true
|
||||
command('silent undo')
|
||||
screen:expect([[
|
||||
S1{7: }^aaa bbb ccc |
|
||||
S2S1aaa bbb ccc |
|
||||
S2{7: }aaa bbb ccc |
|
||||
{7:S1 }^aaa bbb ccc |
|
||||
{7:S2S1}aaa bbb ccc |
|
||||
{7:S2 }aaa bbb ccc |
|
||||
{7: }aaa bbb ccc |*2
|
||||
|
|
||||
]])
|
||||
|
@ -695,7 +695,7 @@ describe('API', function()
|
||||
pcall_err(request, 'nvim_call_dict_function', 42, 'f', { 1, 2 })
|
||||
)
|
||||
eq(
|
||||
'Failed to evaluate dict expression',
|
||||
'Vim:E121: Undefined variable: foo',
|
||||
pcall_err(request, 'nvim_call_dict_function', 'foo', 'f', { 1, 2 })
|
||||
)
|
||||
eq('dict not found', pcall_err(request, 'nvim_call_dict_function', '42', 'f', { 1, 2 }))
|
||||
@ -1957,6 +1957,16 @@ describe('API', function()
|
||||
api.nvim_set_current_win(api.nvim_list_wins()[2])
|
||||
eq(api.nvim_list_wins()[2], api.nvim_get_current_win())
|
||||
end)
|
||||
|
||||
it('failure modes', function()
|
||||
n.command('split')
|
||||
|
||||
eq('Invalid window id: 9999', pcall_err(api.nvim_set_current_win, 9999))
|
||||
|
||||
-- XXX: force nvim_set_current_win to fail somehow.
|
||||
n.command("au WinLeave * throw 'foo'")
|
||||
eq('WinLeave Autocommands for "*": foo', pcall_err(api.nvim_set_current_win, 1000))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_{get,set}_current_tabpage, nvim_list_tabpages', function()
|
||||
@ -1976,6 +1986,16 @@ describe('API', function()
|
||||
eq(api.nvim_list_tabpages()[2], api.nvim_get_current_tabpage())
|
||||
eq(api.nvim_list_wins()[2], api.nvim_get_current_win())
|
||||
end)
|
||||
|
||||
it('failure modes', function()
|
||||
n.command('tabnew')
|
||||
|
||||
eq('Invalid tabpage id: 999', pcall_err(api.nvim_set_current_tabpage, 999))
|
||||
|
||||
-- XXX: force nvim_set_current_tabpage to fail somehow.
|
||||
n.command("au TabLeave * throw 'foo'")
|
||||
eq('TabLeave Autocommands for "*": foo', pcall_err(api.nvim_set_current_tabpage, 1))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_get_mode', function()
|
||||
@ -3765,7 +3785,7 @@ describe('API', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{1:~}{102: }{4: }{1: }|
|
||||
{1:~}{4:^ }{1: }|
|
||||
{1:~}{4: }{1: }|*4
|
||||
{1:~ }|*3
|
||||
{5:-- TERMINAL --} |
|
||||
@ -3781,7 +3801,7 @@ describe('API', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{1:~}{4:herrejösses!}{102: }{4: }{1: }|
|
||||
{1:~}{4:herrejösses!^ }{1: }|
|
||||
{1:~}{4: }{1: }|*4
|
||||
{1:~ }|*3
|
||||
{5:-- TERMINAL --} |
|
||||
|
@ -359,6 +359,15 @@ describe('API/win', function()
|
||||
eq(2, api.nvim_win_get_height(api.nvim_list_wins()[2]))
|
||||
end)
|
||||
|
||||
it('failure modes', function()
|
||||
command('split')
|
||||
eq('Invalid window id: 999999', pcall_err(api.nvim_win_set_height, 999999, 10))
|
||||
eq(
|
||||
'Wrong type for argument 2 when calling nvim_win_set_height, expecting Integer',
|
||||
pcall_err(api.nvim_win_set_height, 0, 0.9)
|
||||
)
|
||||
end)
|
||||
|
||||
it('correctly handles height=1', function()
|
||||
command('split')
|
||||
api.nvim_set_current_win(api.nvim_list_wins()[1])
|
||||
@ -409,6 +418,15 @@ describe('API/win', function()
|
||||
eq(2, api.nvim_win_get_width(api.nvim_list_wins()[2]))
|
||||
end)
|
||||
|
||||
it('failure modes', function()
|
||||
command('vsplit')
|
||||
eq('Invalid window id: 999999', pcall_err(api.nvim_win_set_width, 999999, 10))
|
||||
eq(
|
||||
'Wrong type for argument 2 when calling nvim_win_set_width, expecting Integer',
|
||||
pcall_err(api.nvim_win_set_width, 0, 0.9)
|
||||
)
|
||||
end)
|
||||
|
||||
it('do not cause ml_get errors with foldmethod=expr #19989', function()
|
||||
insert([[
|
||||
aaaaa
|
||||
@ -1664,7 +1682,7 @@ describe('API/win', function()
|
||||
autocmd BufWinEnter * ++once let fired = v:true
|
||||
]])
|
||||
eq(
|
||||
'Failed to set buffer 2',
|
||||
'Vim:E37: No write since last change (add ! to override)',
|
||||
pcall_err(api.nvim_open_win, api.nvim_create_buf(true, true), false, { split = 'left' })
|
||||
)
|
||||
eq(false, eval('fired'))
|
||||
|
@ -351,11 +351,10 @@ describe('autocmd DirChanged and DirChangedPre', function()
|
||||
eq(2, eval('g:cdprecount'))
|
||||
eq(2, eval('g:cdcount'))
|
||||
|
||||
local status, err = pcall(function()
|
||||
request('nvim_set_current_dir', '/doesnotexist')
|
||||
end)
|
||||
eq(false, status)
|
||||
eq('Failed to change directory', string.match(err, ': (.*)'))
|
||||
eq(
|
||||
'Vim:E344: Can\'t find directory "/doesnotexist" in cdpath',
|
||||
t.pcall_err(request, 'nvim_set_current_dir', '/doesnotexist')
|
||||
)
|
||||
eq({ directory = '/doesnotexist', scope = 'global', changed_window = false }, eval('g:evpre'))
|
||||
eq(3, eval('g:cdprecount'))
|
||||
eq(2, eval('g:cdcount'))
|
||||
|
@ -47,7 +47,7 @@ describe('autoread TUI FocusGained/FocusLost', function()
|
||||
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] }|
|
||||
|
|
||||
@ -57,7 +57,7 @@ describe('autoread TUI FocusGained/FocusLost', function()
|
||||
feed_command('edit ' .. path)
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:xtest-foo }|
|
||||
:edit xtest-foo |
|
||||
@ -68,7 +68,7 @@ describe('autoread TUI FocusGained/FocusLost', function()
|
||||
feed_data('\027[O')
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:xtest-foo }|
|
||||
:edit xtest-foo |
|
||||
@ -83,7 +83,7 @@ describe('autoread TUI FocusGained/FocusLost', function()
|
||||
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1:l}ine 1 |
|
||||
^line 1 |
|
||||
line 2 |
|
||||
line 3 |
|
||||
line 4 |
|
||||
|
@ -1198,7 +1198,7 @@ describe('jobs', function()
|
||||
})
|
||||
-- Wait for startup to complete, so that all terminal responses are received.
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
^ |
|
||||
~ |*3
|
||||
{1:[No Name] 0,0-1 All}|
|
||||
|
|
||||
@ -1208,7 +1208,7 @@ describe('jobs', function()
|
||||
feed(':q<CR>')
|
||||
screen:expect([[
|
||||
|
|
||||
[Process exited 0]{1: } |
|
||||
[Process exited 0]^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
@ -46,7 +46,7 @@ describe('log', function()
|
||||
env = env,
|
||||
})
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
^ |
|
||||
~ |*4
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
|
@ -120,7 +120,7 @@ describe('command-line option', function()
|
||||
feed('i:cq<CR>')
|
||||
screen:expect([[
|
||||
|
|
||||
[Process exited 1]{2: } |
|
||||
[Process exited 1]^ |
|
||||
|*5
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
|
@ -1153,7 +1153,7 @@ describe('user config init', function()
|
||||
-- `i` to enter Terminal mode, `a` to allow
|
||||
feed('ia')
|
||||
screen:expect([[
|
||||
|
|
||||
^ |
|
||||
~ |*4
|
||||
[No Name] 0,0-1 All|
|
||||
|
|
||||
@ -1162,7 +1162,7 @@ describe('user config init', function()
|
||||
feed(':echo g:exrc_file<CR>')
|
||||
screen:expect(string.format(
|
||||
[[
|
||||
|
|
||||
^ |
|
||||
~ |*4
|
||||
[No Name] 0,0-1 All|
|
||||
%s%s|
|
||||
|
@ -29,8 +29,8 @@ describe(':highlight', function()
|
||||
|
|
||||
TermCursor {2:xxx} {18:cterm=}reverse |
|
||||
{18:gui=}reverse |
|
||||
TermCursorNC xxx cleared |
|
||||
NonText {1:xxx} {18:ctermfg=}12 |
|
||||
{18:gui=}bold |
|
||||
{6:-- More --}^ |
|
||||
]])
|
||||
feed('q')
|
||||
|
@ -709,7 +709,7 @@ describe('messages', function()
|
||||
feed('<CR>')
|
||||
|
||||
-- Check no hit-enter prompt when "wait:" is set
|
||||
command('set messagesopt=wait:100,history:500')
|
||||
command('set messagesopt=wait:500,history:500')
|
||||
feed(":echo 'foo' | echo 'bar' | echo 'baz'\n")
|
||||
screen:expect({
|
||||
grid = [[
|
||||
@ -720,7 +720,7 @@ describe('messages', function()
|
||||
bar |
|
||||
baz |
|
||||
]],
|
||||
timeout = 100,
|
||||
timeout = 500,
|
||||
})
|
||||
screen:expect([[
|
||||
^ |
|
||||
|
@ -26,6 +26,9 @@ describe('signs', function()
|
||||
-- oldtest: Test_sign_cursor_position()
|
||||
it('are drawn correctly', function()
|
||||
local screen = Screen.new(75, 6)
|
||||
screen:add_extra_attr_ids({
|
||||
[100] = { foreground = Screen.colors.Blue4, background = Screen.colors.Yellow },
|
||||
})
|
||||
exec([[
|
||||
call setline(1, [repeat('x', 75), 'mmmm', 'yyyy'])
|
||||
call cursor(2,1)
|
||||
@ -37,7 +40,7 @@ describe('signs', function()
|
||||
screen:expect([[
|
||||
{7: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|
||||
{7: }xx |
|
||||
{10:=>}^mmmm |
|
||||
{100:=>}^mmmm |
|
||||
{7: }yyyy |
|
||||
{1:~ }|
|
||||
|
|
||||
@ -48,7 +51,7 @@ describe('signs', function()
|
||||
screen:expect([[
|
||||
{7: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|
||||
{7: }xx |
|
||||
{10:-)}^mmmm |
|
||||
{100:-)}^mmmm |
|
||||
{7: }yyyy |
|
||||
{1:~ }|
|
||||
|
|
||||
@ -59,7 +62,7 @@ describe('signs', function()
|
||||
screen:expect([[
|
||||
{7: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|
||||
{7: }xx |
|
||||
{10:-)}{4:^mmmm }|
|
||||
{100:-)}{4:^mmmm }|
|
||||
{7: }yyyy |
|
||||
{1:~ }|
|
||||
|
|
||||
|
@ -5,6 +5,7 @@ local command = n.command
|
||||
local clear = n.clear
|
||||
local exec_lua = n.exec_lua
|
||||
local eq = t.eq
|
||||
local neq = t.neq
|
||||
local matches = t.matches
|
||||
local api = n.api
|
||||
local pcall_err = t.pcall_err
|
||||
@ -3212,6 +3213,74 @@ describe('vim.diagnostic', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('setqflist()', function()
|
||||
it('updates existing diagnostics quickfix if one already exists', function()
|
||||
local result = exec_lua(function()
|
||||
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
|
||||
|
||||
vim.fn.setqflist({}, ' ', { title = 'Diagnostics' })
|
||||
local diagnostics_qf_id = vim.fn.getqflist({ id = 0 }).id
|
||||
|
||||
vim.diagnostic.setqflist({ title = 'Diagnostics' })
|
||||
local qf_id = vim.fn.getqflist({ id = 0, nr = '$' }).id
|
||||
|
||||
return { diagnostics_qf_id, qf_id }
|
||||
end)
|
||||
|
||||
eq(result[1], result[2])
|
||||
end)
|
||||
|
||||
it('navigates to existing diagnostics quickfix if one already exists and open=true', function()
|
||||
local result = exec_lua(function()
|
||||
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
|
||||
|
||||
vim.fn.setqflist({}, ' ', { title = 'Diagnostics' })
|
||||
local diagnostics_qf_id = vim.fn.getqflist({ id = 0 }).id
|
||||
|
||||
vim.fn.setqflist({}, ' ', { title = 'Other' })
|
||||
|
||||
vim.diagnostic.setqflist({ title = 'Diagnostics', open = true })
|
||||
local qf_id = vim.fn.getqflist({ id = 0 }).id
|
||||
|
||||
return { diagnostics_qf_id, qf_id }
|
||||
end)
|
||||
|
||||
eq(result[1], result[2])
|
||||
end)
|
||||
|
||||
it('sets new diagnostics quickfix as active when open=true', function()
|
||||
local result = exec_lua(function()
|
||||
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
|
||||
|
||||
vim.fn.setqflist({}, ' ', { title = 'Other' })
|
||||
local other_qf_id = vim.fn.getqflist({ id = 0 }).id
|
||||
|
||||
vim.diagnostic.setqflist({ title = 'Diagnostics', open = true })
|
||||
local qf_id = vim.fn.getqflist({ id = 0 }).id
|
||||
|
||||
return { other_qf_id, qf_id }
|
||||
end)
|
||||
|
||||
neq(result[1], result[2])
|
||||
end)
|
||||
|
||||
it('opens quickfix window when open=true', function()
|
||||
local qf_winid = exec_lua(function()
|
||||
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
|
||||
|
||||
vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, {
|
||||
_G.make_error('Error', 1, 1, 1, 1),
|
||||
})
|
||||
|
||||
vim.diagnostic.setqflist({ open = true })
|
||||
|
||||
return vim.fn.getqflist({ winid = 0 }).winid
|
||||
end)
|
||||
|
||||
neq(0, qf_winid)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('match()', function()
|
||||
it('matches a string', function()
|
||||
local msg = 'ERROR: george.txt:19:84:Two plus two equals five'
|
||||
|
@ -263,7 +263,7 @@ describe('vim.ui_attach', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 7 } },
|
||||
content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 6 } },
|
||||
kind = 'emsg',
|
||||
},
|
||||
},
|
||||
@ -280,7 +280,7 @@ describe('vim.ui_attach', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 19 } },
|
||||
content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } },
|
||||
kind = 'confirm_sub',
|
||||
},
|
||||
},
|
||||
@ -348,7 +348,7 @@ describe('vim.ui_attach', function()
|
||||
foo^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { '-- INSERT --', 5, 12 } },
|
||||
showmode = { { '-- INSERT --', 5, 11 } },
|
||||
})
|
||||
feed('<esc>:1mes clear<cr>:mes<cr>')
|
||||
screen:expect({
|
||||
@ -375,7 +375,7 @@ describe('vim.ui_attach', function()
|
||||
{
|
||||
'Error executing vim.schedule lua callback: [string "<nvim>"]:2: attempt to index global \'err\' (a nil value)\nstack traceback:\n\t[string "<nvim>"]:2: in function <[string "<nvim>"]:2>',
|
||||
9,
|
||||
7,
|
||||
6,
|
||||
},
|
||||
},
|
||||
kind = 'lua_error',
|
||||
@ -385,13 +385,13 @@ describe('vim.ui_attach', function()
|
||||
{
|
||||
'Error executing vim.schedule lua callback: [string "<nvim>"]:2: attempt to index global \'err\' (a nil value)\nstack traceback:\n\t[string "<nvim>"]:2: in function <[string "<nvim>"]:2>',
|
||||
9,
|
||||
7,
|
||||
6,
|
||||
},
|
||||
},
|
||||
kind = 'lua_error',
|
||||
},
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 100, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 100, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
|
@ -3955,6 +3955,17 @@ stack traceback:
|
||||
eq(win2, val)
|
||||
end)
|
||||
|
||||
it('failure modes', function()
|
||||
matches(
|
||||
'nvim_exec2%(%): Vim:E492: Not an editor command: fooooo',
|
||||
pcall_err(exec_lua, [[vim.api.nvim_win_call(0, function() vim.cmd 'fooooo' end)]])
|
||||
)
|
||||
eq(
|
||||
'Error executing lua: [string "<nvim>"]:0: fooooo',
|
||||
pcall_err(exec_lua, [[vim.api.nvim_win_call(0, function() error('fooooo') end)]])
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not cause ml_get errors with invalid visual selection', function()
|
||||
-- Add lines to the current buffer and make another window looking into an empty buffer.
|
||||
exec_lua [[
|
||||
|
@ -1,55 +1,51 @@
|
||||
local n = require('test.functional.testnvim')()
|
||||
local t = require('test.testutil')
|
||||
|
||||
local clear = n.clear
|
||||
local exec_lua = n.exec_lua
|
||||
|
||||
describe("Nvim API calls with 'winfixbuf'", function()
|
||||
describe("'winfixbuf'", function()
|
||||
before_each(function()
|
||||
clear()
|
||||
end)
|
||||
|
||||
it("Calling vim.api.nvim_win_set_buf with 'winfixbuf'", function()
|
||||
local results = exec_lua([[
|
||||
local function _setup_two_buffers()
|
||||
local buffer = vim.api.nvim_create_buf(true, true)
|
||||
|
||||
vim.api.nvim_create_buf(true, true) -- Make another buffer
|
||||
|
||||
local current_window = 0
|
||||
vim.api.nvim_set_option_value("winfixbuf", true, {win=current_window})
|
||||
|
||||
return buffer
|
||||
end
|
||||
|
||||
local other_buffer = _setup_two_buffers()
|
||||
local current_window = 0
|
||||
local results, _ = pcall(vim.api.nvim_win_set_buf, current_window, other_buffer)
|
||||
|
||||
return results
|
||||
---@return integer
|
||||
local function setup_winfixbuf()
|
||||
return exec_lua([[
|
||||
local buffer = vim.api.nvim_create_buf(true, true)
|
||||
vim.api.nvim_create_buf(true, true) -- Make another buffer
|
||||
vim.wo.winfixbuf = true
|
||||
return buffer
|
||||
]])
|
||||
end
|
||||
|
||||
assert(results == false)
|
||||
it('nvim_win_set_buf on non-current buffer', function()
|
||||
local other_buf = setup_winfixbuf()
|
||||
t.eq(
|
||||
"Vim:E1513: Cannot switch buffer. 'winfixbuf' is enabled",
|
||||
t.pcall_err(n.api.nvim_win_set_buf, 0, other_buf)
|
||||
)
|
||||
end)
|
||||
|
||||
it("Calling vim.api.nvim_set_current_buf with 'winfixbuf'", function()
|
||||
local results = exec_lua([[
|
||||
local function _setup_two_buffers()
|
||||
local buffer = vim.api.nvim_create_buf(true, true)
|
||||
it('nvim_set_current_buf on non-current buffer', function()
|
||||
local other_buf = setup_winfixbuf()
|
||||
t.eq(
|
||||
"Vim:E1513: Cannot switch buffer. 'winfixbuf' is enabled",
|
||||
t.pcall_err(n.api.nvim_set_current_buf, other_buf)
|
||||
)
|
||||
end)
|
||||
|
||||
vim.api.nvim_create_buf(true, true) -- Make another buffer
|
||||
it('nvim_win_set_buf on current buffer', function()
|
||||
setup_winfixbuf()
|
||||
local curbuf = n.api.nvim_get_current_buf()
|
||||
n.api.nvim_win_set_buf(0, curbuf)
|
||||
t.eq(curbuf, n.api.nvim_get_current_buf())
|
||||
end)
|
||||
|
||||
local current_window = 0
|
||||
vim.api.nvim_set_option_value("winfixbuf", true, {win=current_window})
|
||||
|
||||
return buffer
|
||||
end
|
||||
|
||||
local other_buffer = _setup_two_buffers()
|
||||
local results, _ = pcall(vim.api.nvim_set_current_buf, other_buffer)
|
||||
|
||||
return results
|
||||
]])
|
||||
|
||||
assert(results == false)
|
||||
it('nvim_set_current_buf on current buffer', function()
|
||||
setup_winfixbuf()
|
||||
local curbuf = n.api.nvim_get_current_buf()
|
||||
n.api.nvim_set_current_buf(curbuf)
|
||||
t.eq(curbuf, n.api.nvim_get_current_buf())
|
||||
end)
|
||||
end)
|
||||
|
@ -731,9 +731,10 @@ describe('vim.lsp.completion: item conversion', function()
|
||||
)
|
||||
end)
|
||||
|
||||
--- @param name string
|
||||
--- @param completion_result lsp.CompletionList
|
||||
--- @return integer
|
||||
local function create_server(completion_result)
|
||||
local function create_server(name, completion_result)
|
||||
return exec_lua(function()
|
||||
local server = _G._create_server({
|
||||
capabilities = {
|
||||
@ -751,7 +752,7 @@ local function create_server(completion_result)
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_win_set_buf(0, bufnr)
|
||||
return vim.lsp.start({
|
||||
name = 'dummy',
|
||||
name = name,
|
||||
cmd = server.cmd,
|
||||
on_attach = function(client, bufnr0)
|
||||
vim.lsp.completion.enable(true, client.id, bufnr0, {
|
||||
@ -800,7 +801,7 @@ describe('vim.lsp.completion: protocol', function()
|
||||
end
|
||||
|
||||
it('fetches completions and shows them using complete on trigger', function()
|
||||
create_server({
|
||||
create_server('dummy', {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
@ -892,7 +893,7 @@ describe('vim.lsp.completion: protocol', function()
|
||||
end)
|
||||
|
||||
it('merges results from multiple clients', function()
|
||||
create_server({
|
||||
create_server('dummy1', {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
@ -900,7 +901,7 @@ describe('vim.lsp.completion: protocol', function()
|
||||
},
|
||||
},
|
||||
})
|
||||
create_server({
|
||||
create_server('dummy2', {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
@ -933,7 +934,7 @@ describe('vim.lsp.completion: protocol', function()
|
||||
},
|
||||
},
|
||||
}
|
||||
local client_id = create_server(completion_list)
|
||||
local client_id = create_server('dummy', completion_list)
|
||||
|
||||
exec_lua(function()
|
||||
_G.called = false
|
||||
@ -970,7 +971,7 @@ describe('vim.lsp.completion: protocol', function()
|
||||
end)
|
||||
|
||||
it('enable(…,{convert=fn}) custom word/abbr format', function()
|
||||
create_server({
|
||||
create_server('dummy', {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
@ -1012,7 +1013,7 @@ describe('vim.lsp.completion: integration', function()
|
||||
exec_lua(function()
|
||||
vim.o.completeopt = 'menuone,noselect'
|
||||
end)
|
||||
create_server(completion_list)
|
||||
create_server('dummy', completion_list)
|
||||
feed('i world<esc>0ih<c-x><c-o>')
|
||||
retry(nil, nil, function()
|
||||
eq(
|
||||
|
@ -5184,8 +5184,8 @@ describe('LSP', function()
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'local x = 10', '', 'print(x)' })
|
||||
vim.api.nvim_win_set_cursor(win, { 3, 6 })
|
||||
local client_id1 = assert(vim.lsp.start({ name = 'dummy', cmd = server1.cmd }))
|
||||
local client_id2 = assert(vim.lsp.start({ name = 'dummy', cmd = server2.cmd }))
|
||||
local client_id1 = assert(vim.lsp.start({ name = 'dummy1', cmd = server1.cmd }))
|
||||
local client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = server2.cmd }))
|
||||
local response
|
||||
vim.lsp.buf.definition({
|
||||
on_list = function(r)
|
||||
@ -6203,5 +6203,33 @@ describe('LSP', function()
|
||||
end)
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not attach to buffers more than once if no root_dir', function()
|
||||
exec_lua(create_server_definition)
|
||||
|
||||
local tmp1 = t.tmpname(true)
|
||||
|
||||
eq(
|
||||
1,
|
||||
exec_lua(function()
|
||||
local server = _G._create_server({
|
||||
handlers = {
|
||||
initialize = function(_, _, callback)
|
||||
callback(nil, { capabilities = {} })
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config('foo', { cmd = server.cmd, filetypes = { 'foo' } })
|
||||
vim.lsp.enable('foo')
|
||||
|
||||
vim.cmd.edit(assert(tmp1))
|
||||
vim.bo.filetype = 'foo'
|
||||
vim.bo.filetype = 'foo'
|
||||
|
||||
return #vim.lsp.get_clients({ bufnr = vim.api.nvim_get_current_buf() })
|
||||
end)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
@ -263,4 +263,14 @@ describe(':Man', function()
|
||||
{ '1', 'other_man' },
|
||||
}, get_search_history('other_man(1)'))
|
||||
end)
|
||||
|
||||
it('can complete', function()
|
||||
t.skip(t.is_os('mac') and t.is_arch('x86_64'), 'not supported on intel mac')
|
||||
eq(
|
||||
true,
|
||||
exec_lua(function()
|
||||
return #require('man').man_complete('f', 'Man g') > 0
|
||||
end)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
@ -35,13 +35,13 @@ describe(':terminal altscreen', function()
|
||||
line6 |
|
||||
line7 |
|
||||
line8 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
enter_altscreen()
|
||||
screen:expect([[
|
||||
|*5
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq(10, api.nvim_buf_line_count(0))
|
||||
@ -68,7 +68,7 @@ describe(':terminal altscreen', function()
|
||||
line6 |
|
||||
line7 |
|
||||
line8 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<c-\\><c-n>gg')
|
||||
@ -103,7 +103,7 @@ describe(':terminal altscreen', function()
|
||||
line14 |
|
||||
line15 |
|
||||
line16 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -132,7 +132,7 @@ describe(':terminal altscreen', function()
|
||||
screen:expect([[
|
||||
|*2
|
||||
rows: 4, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end
|
||||
@ -160,7 +160,7 @@ describe(':terminal altscreen', function()
|
||||
line5 |
|
||||
line6 |
|
||||
line7 |
|
||||
line8 |
|
||||
^line8 |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
|
@ -33,7 +33,7 @@ describe('api', function()
|
||||
it('qa! RPC request during insert-mode', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*4
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
@ -45,7 +45,7 @@ describe('api', function()
|
||||
|
||||
-- Wait for socket creation.
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*4
|
||||
]] .. socket_name .. [[ |
|
||||
{3:-- TERMINAL --} |
|
||||
@ -57,7 +57,7 @@ describe('api', function()
|
||||
tt.feed_data('i[tui] insert-mode')
|
||||
-- Wait for stdin to be processed.
|
||||
screen:expect([[
|
||||
[tui] insert-mode{1: } |
|
||||
[tui] insert-mode^ |
|
||||
{4:~ }|*4
|
||||
{3:-- INSERT --} |
|
||||
{3:-- TERMINAL --} |
|
||||
@ -73,7 +73,7 @@ describe('api', function()
|
||||
[tui] insert-mode |
|
||||
[socket 1] this is more t |
|
||||
han 25 columns |
|
||||
[socket 2] input{1: } |
|
||||
[socket 2] input^ |
|
||||
{4:~ } |
|
||||
{3:-- INSERT --} |
|
||||
{3:-- TERMINAL --} |
|
||||
|
@ -89,7 +89,7 @@ describe(':terminal buffer', function()
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
end)
|
||||
@ -109,7 +109,7 @@ describe(':terminal buffer', function()
|
||||
feed('<c-\\><c-n>dd')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*4
|
||||
{8:E21: Cannot make changes, 'modifiable' is off} |
|
||||
]])
|
||||
@ -122,7 +122,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
appended tty ready |*2
|
||||
{2: } |
|
||||
|
|
||||
|*2
|
||||
:let @a = "appended " . @a |
|
||||
]])
|
||||
@ -142,7 +142,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
appended tty ready |
|
||||
{2: } |
|
||||
|
|
||||
|*3
|
||||
:put a |
|
||||
]])
|
||||
@ -151,7 +151,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
appended tty ready |*2
|
||||
{2: } |
|
||||
|
|
||||
|
|
||||
^ |
|
||||
:6put a |
|
||||
@ -198,7 +198,7 @@ describe(':terminal buffer', function()
|
||||
{4:~ }|
|
||||
{5:========== }|
|
||||
rows: 2, cols: 50 |
|
||||
{2: } |
|
||||
|
|
||||
{18:========== }|
|
||||
|
|
||||
]])
|
||||
@ -234,7 +234,7 @@ describe(':terminal buffer', function()
|
||||
command('set rightleft')
|
||||
screen:expect([[
|
||||
ydaer ytt|
|
||||
{1:a}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -277,7 +277,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- (terminal) --} |
|
||||
]],
|
||||
@ -288,7 +288,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
tty ready |
|
||||
{2: } |
|
||||
|
|
||||
|*4
|
||||
:let g:x = 17^ |
|
||||
]],
|
||||
@ -298,7 +298,7 @@ describe(':terminal buffer', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
@ -534,7 +534,7 @@ describe('terminal input', function()
|
||||
'while 1 | redraw | echo keytrans(getcharstr()) | endwhile',
|
||||
})
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
|
|
||||
@ -594,7 +594,7 @@ describe('terminal input', function()
|
||||
|
|
||||
{4:~ }|*3
|
||||
{5:[No Name] 0,0-1 All}|
|
||||
%s{1: }{MATCH: *}|
|
||||
%s^ {MATCH: *}|
|
||||
{3:-- TERMINAL --} |
|
||||
]]):format(key))
|
||||
end
|
||||
@ -624,7 +624,7 @@ if is_os('win') then
|
||||
> :: appended :: tty ready |
|
||||
> :: tty ready |
|
||||
> :: appended :: tty ready |
|
||||
^> {2: } |
|
||||
^> |
|
||||
:let @a = @a . "\n:: appended " . @a . "\n\n" |
|
||||
]])
|
||||
-- operator count is also taken into consideration
|
||||
@ -635,7 +635,7 @@ if is_os('win') then
|
||||
> :: appended :: tty ready |
|
||||
> :: tty ready |
|
||||
> :: appended :: tty ready |
|
||||
^> {2: } |
|
||||
^> |
|
||||
:let @a = @a . "\n:: appended " . @a . "\n\n" |
|
||||
]])
|
||||
end)
|
||||
@ -649,7 +649,7 @@ if is_os('win') then
|
||||
|
|
||||
> :: tty ready |
|
||||
> :: appended :: tty ready |
|
||||
> {2: } |
|
||||
> |
|
||||
|
|
||||
^ |
|
||||
:put a |
|
||||
@ -662,7 +662,7 @@ if is_os('win') then
|
||||
> :: appended :: tty ready |
|
||||
> :: tty ready |
|
||||
> :: appended :: tty ready |
|
||||
^> {2: } |
|
||||
^> |
|
||||
:6put a |
|
||||
]])
|
||||
end)
|
||||
|
@ -1,13 +1,12 @@
|
||||
local t = require('test.testutil')
|
||||
local n = require('test.functional.testnvim')()
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local tt = require('test.functional.testterm')
|
||||
|
||||
local feed, clear = n.feed, n.clear
|
||||
local testprg, command = n.testprg, n.command
|
||||
local eq, eval = t.eq, n.eval
|
||||
local matches = t.matches
|
||||
local poke_eventloop = n.poke_eventloop
|
||||
local call = n.call
|
||||
local hide_cursor = tt.hide_cursor
|
||||
local show_cursor = tt.show_cursor
|
||||
local is_os = t.is_os
|
||||
@ -25,7 +24,7 @@ describe(':terminal cursor', function()
|
||||
tt.feed_data('testing cursor')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
testing cursor{1: } |
|
||||
testing cursor^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -35,7 +34,7 @@ describe(':terminal cursor', function()
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
end)
|
||||
@ -49,7 +48,7 @@ describe(':terminal cursor', function()
|
||||
screen:expect([[
|
||||
{7: 1 }tty ready |
|
||||
{7: 2 }^rows: 6, cols: 46 |
|
||||
{7: 3 }{2: } |
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 } |
|
||||
{7: 6 } |
|
||||
@ -61,7 +60,7 @@ describe(':terminal cursor', function()
|
||||
screen:expect([[
|
||||
{7: 1 }tty ready |
|
||||
{7: 2 }^rows: 6, cols: 46 |
|
||||
{7: 3 }{2: } |
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 } |
|
||||
{7: 6 } |
|
||||
@ -72,7 +71,7 @@ describe(':terminal cursor', function()
|
||||
screen:expect([[
|
||||
{7: 1 }tty ready |
|
||||
{7: 2 }rows: 6, cols: 46 |
|
||||
{7: 3 }{1: } |
|
||||
{7: 3 }^ |
|
||||
{7: 4 } |
|
||||
{7: 5 } |
|
||||
{7: 6 } |
|
||||
@ -82,8 +81,8 @@ describe(':terminal cursor', function()
|
||||
end)
|
||||
|
||||
describe('when invisible', function()
|
||||
it('is not highlighted and is detached from screen cursor', function()
|
||||
skip(is_os('win'))
|
||||
it('is not highlighted', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
hide_cursor()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
@ -93,58 +92,238 @@ describe(':terminal cursor', function()
|
||||
show_cursor()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
-- same for when the terminal is unfocused
|
||||
feed('<c-\\><c-n>')
|
||||
hide_cursor()
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]],
|
||||
unchanged = true,
|
||||
})
|
||||
show_cursor()
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]],
|
||||
unchanged = true,
|
||||
})
|
||||
end)
|
||||
|
||||
it('becomes visible when exiting Terminal mode', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
hide_cursor()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
|*5
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
show_cursor()
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
|*5
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('cursor with customized highlighting', function()
|
||||
local screen
|
||||
it('can be modified by application #3681', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
local idx ---@type number
|
||||
for i, v in ipairs(screen._mode_info) do
|
||||
if v.name == 'terminal' then
|
||||
idx = i
|
||||
end
|
||||
end
|
||||
assert(idx)
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
command('highlight TermCursor ctermfg=45 ctermbg=46 cterm=NONE')
|
||||
command('highlight TermCursorNC ctermfg=55 ctermbg=56 cterm=NONE')
|
||||
screen = Screen.new(50, 7, { rgb = false })
|
||||
screen:set_default_attr_ids({
|
||||
[1] = { foreground = 45, background = 46 },
|
||||
[2] = { foreground = 55, background = 56 },
|
||||
[3] = { bold = true },
|
||||
})
|
||||
command('call termopen(["' .. testprg('tty-test') .. '"])')
|
||||
feed('i')
|
||||
poke_eventloop()
|
||||
local states = {
|
||||
[1] = { blink = true, shape = 'block' },
|
||||
[2] = { blink = false, shape = 'block' },
|
||||
[3] = { blink = true, shape = 'horizontal' },
|
||||
[4] = { blink = false, shape = 'horizontal' },
|
||||
[5] = { blink = true, shape = 'vertical' },
|
||||
[6] = { blink = false, shape = 'vertical' },
|
||||
}
|
||||
|
||||
for k, v in pairs(states) do
|
||||
tt.feed_csi(('%d q'):format(k))
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
if v.blink then
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
else
|
||||
eq(0, screen._mode_info[idx].blinkon)
|
||||
eq(0, screen._mode_info[idx].blinkoff)
|
||||
end
|
||||
eq(v.shape, screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
feed([[<C-\><C-N>]])
|
||||
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
|
||||
-- Cursor returns to default on TermLeave
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
eq('block', screen._mode_info[idx].cursor_shape)
|
||||
end)
|
||||
|
||||
it('overrides the default highlighting', function()
|
||||
screen:expect([[
|
||||
it('can be modified per terminal', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
local idx ---@type number
|
||||
for i, v in ipairs(screen._mode_info) do
|
||||
if v.name == 'terminal' then
|
||||
idx = i
|
||||
end
|
||||
end
|
||||
assert(idx)
|
||||
|
||||
-- Set cursor to vertical bar with blink
|
||||
tt.feed_csi('5 q')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
]],
|
||||
condition = function()
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
|
||||
tt.hide_cursor()
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
|*5
|
||||
|
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Exit terminal mode to reset terminal cursor settings to default and
|
||||
-- create a new terminal window
|
||||
feed([[<C-\><C-N>]])
|
||||
command('set statusline=~~~')
|
||||
command('new')
|
||||
call('termopen', { testprg('tty-test') })
|
||||
feed('i')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
{17:~~~ }|
|
||||
rows: 2, cols: 50 |
|
||||
|
|
||||
{18:~~~ }|
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
-- New terminal, cursor resets to defaults
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
eq('block', screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Set cursor to underline, no blink
|
||||
tt.feed_csi('4 q')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
{17:~~~ }|
|
||||
rows: 2, cols: 50 |
|
||||
|
|
||||
{18:~~~ }|
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
eq(0, screen._mode_info[idx].blinkon)
|
||||
eq(0, screen._mode_info[idx].blinkoff)
|
||||
eq('horizontal', screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Switch back to first terminal, cursor should still be hidden
|
||||
command('wincmd p')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
|
|
||||
{18:~~~ }|
|
||||
rows: 2, cols: 50 |
|
||||
|
|
||||
{17:~~~ }|
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
eq(500, screen._mode_info[idx].blinkon)
|
||||
eq(500, screen._mode_info[idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
end)
|
||||
|
||||
it('can be positioned arbitrarily', function()
|
||||
clear()
|
||||
screen = tt.setup_child_nvim({
|
||||
'-u',
|
||||
'NONE',
|
||||
'-i',
|
||||
'NONE',
|
||||
'--cmd',
|
||||
n.nvim_set .. ' noshowmode',
|
||||
})
|
||||
screen:expect([[
|
||||
^ |
|
||||
~ |*4
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed('i<Tab>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
~ |*4
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
@ -183,7 +362,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:{2:^ } |
|
||||
:^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end
|
||||
@ -200,7 +379,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaaaaa{2:^ } |
|
||||
:aaaaaaaa^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 9 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -208,7 +387,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaaaa^a{4: } |
|
||||
:aaaaaaa^a |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 8 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -219,7 +398,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaaa{2:^a}a |
|
||||
:aaaaaa^aa |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 7 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -227,7 +406,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaa^a{4:a}a |
|
||||
:aaaaa^aaa |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 6 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -238,7 +417,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:a{2:^a}aaaaaa |
|
||||
:a^aaaaaaa |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 2 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -246,7 +425,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:^a{4:a}aaaaaa |
|
||||
:^aaaaaaaa |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -263,7 +442,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µµµµµµµµ{2:^ } |
|
||||
:µµµµµµµµ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 17 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -271,7 +450,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µµµµµµµ^µ{4: } |
|
||||
:µµµµµµµ^µ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 15 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -282,7 +461,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µµµµµµ{2:^µ}µ |
|
||||
:µµµµµµ^µµ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -290,7 +469,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µµµµµ^µ{4:µ}µ |
|
||||
:µµµµµ^µµµ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 11 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -301,7 +480,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ{2:^µ}µµµµµµ |
|
||||
:µ^µµµµµµµ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 3 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -309,7 +488,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:^µ{4:µ}µµµµµµ |
|
||||
:^µµµµµµµµ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -326,7 +505,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{2:^ } |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 33 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -334,7 +513,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{4: } |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 29 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -346,7 +525,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳{2:^µ̳}µ̳ |
|
||||
:µ̳µ̳µ̳µ̳µ̳µ̳^µ̳µ̳ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -354,7 +533,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ̳µ̳µ̳µ̳µ̳^µ̳{4:µ̳}µ̳ |
|
||||
:µ̳µ̳µ̳µ̳µ̳^µ̳µ̳µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 21 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -366,7 +545,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:µ̳{2:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
:µ̳^µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 5 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -374,7 +553,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:^µ̳{4:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
:^µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -391,7 +570,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:哦哦哦哦哦哦哦哦{2:^ } |
|
||||
:哦哦哦哦哦哦哦哦^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -399,7 +578,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:哦哦哦哦哦哦哦^哦{4: } |
|
||||
:哦哦哦哦哦哦哦^哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 22 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -410,7 +589,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:哦哦哦哦哦哦{2:^哦}哦 |
|
||||
:哦哦哦哦哦哦^哦哦 |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 19 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -418,7 +597,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:哦哦哦哦哦^哦{4:哦}哦 |
|
||||
:哦哦哦哦哦^哦哦哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 16 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -429,7 +608,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:哦{2:^哦}哦哦哦哦哦哦 |
|
||||
:哦^哦哦哦哦哦哦哦 |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 4 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -437,7 +616,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:^哦{4:哦}哦哦哦哦哦哦 |
|
||||
:^哦哦哦哦哦哦哦哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -450,7 +629,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaaaaa {2:^ } |
|
||||
:aaaaaaaa ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
|
||||
@ -459,7 +638,7 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:aaaaaaaa ^ {4: } |
|
||||
:aaaaaaaa ^ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 12 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -504,7 +683,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:{2:^ } |
|
||||
{7: 6 }:^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end
|
||||
@ -527,7 +706,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaaaaa{2:^ } |
|
||||
{7: 6 }:aaaaaaaa^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 9 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -538,7 +717,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaaaa^a{4: } |
|
||||
{7: 6 }:aaaaaaa^a |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 8 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -552,7 +731,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaaa{2:^a}a |
|
||||
{7: 6 }:aaaaaa^aa |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 7 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -563,7 +742,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaa^a{4:a}a |
|
||||
{7: 6 }:aaaaa^aaa |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 6 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -577,7 +756,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:a{2:^a}aaaaaa |
|
||||
{7: 6 }:a^aaaaaaa |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 2 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -588,7 +767,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:^a{4:a}aaaaaa |
|
||||
{7: 6 }:^aaaaaaaa |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -608,7 +787,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µµµµµµµµ{2:^ } |
|
||||
{7: 6 }:µµµµµµµµ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 17 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -619,7 +798,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µµµµµµµ^µ{4: } |
|
||||
{7: 6 }:µµµµµµµ^µ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 15 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -633,7 +812,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µµµµµµ{2:^µ}µ |
|
||||
{7: 6 }:µµµµµµ^µµ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 13 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -644,7 +823,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µµµµµ^µ{4:µ}µ |
|
||||
{7: 6 }:µµµµµ^µµµ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 11 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -658,7 +837,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ{2:^µ}µµµµµµ |
|
||||
{7: 6 }:µ^µµµµµµµ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 3 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -669,7 +848,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:^µ{4:µ}µµµµµµ |
|
||||
{7: 6 }:^µµµµµµµµ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -689,7 +868,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{2:^ } |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 33 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -700,7 +879,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{4: } |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 29 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -715,7 +894,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳{2:^µ̳}µ̳ |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳^µ̳µ̳ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -726,7 +905,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳{4:µ̳}µ̳ |
|
||||
{7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳µ̳µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 21 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -741,7 +920,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:µ̳{2:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
{7: 6 }:µ̳^µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 5 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -752,7 +931,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:^µ̳{4:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
{7: 6 }:^µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -772,7 +951,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:哦哦哦哦哦哦哦哦{2:^ } |
|
||||
{7: 6 }:哦哦哦哦哦哦哦哦^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 25 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -783,7 +962,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:哦哦哦哦哦哦哦^哦{4: } |
|
||||
{7: 6 }:哦哦哦哦哦哦哦^哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 22 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -797,7 +976,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:哦哦哦哦哦哦{2:^哦}哦 |
|
||||
{7: 6 }:哦哦哦哦哦哦^哦哦 |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 19 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -808,7 +987,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:哦哦哦哦哦^哦{4:哦}哦 |
|
||||
{7: 6 }:哦哦哦哦哦^哦哦哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 16 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -822,7 +1001,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:哦{2:^哦}哦哦哦哦哦哦 |
|
||||
{7: 6 }:哦^哦哦哦哦哦哦哦 |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq({ 6, 4 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -833,7 +1012,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:^哦{4:哦}哦哦哦哦哦哦 |
|
||||
{7: 6 }:^哦哦哦哦哦哦哦哦 |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -849,7 +1028,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaaaaa {2:^ } |
|
||||
{7: 6 }:aaaaaaaa ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
|
||||
@ -861,7 +1040,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
{7: 3 } |
|
||||
{7: 4 } |
|
||||
{7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
{7: 6 }:aaaaaaaa ^ {4: } |
|
||||
{7: 6 }:aaaaaaaa ^ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 12 }, eval('nvim_win_get_cursor(0)'))
|
||||
|
@ -37,7 +37,7 @@ describe(':terminal highlight', function()
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{10: } |
|
||||
^ |
|
||||
|*4
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
@ -61,7 +61,7 @@ describe(':terminal highlight', function()
|
||||
skip(is_os('win'))
|
||||
screen:expect(sub([[
|
||||
tty ready |
|
||||
{NUM:text}text{10: } |
|
||||
{NUM:text}text^ |
|
||||
|*4
|
||||
{5:-- TERMINAL --} |
|
||||
]]))
|
||||
@ -84,7 +84,7 @@ describe(':terminal highlight', function()
|
||||
line6 |
|
||||
line7 |
|
||||
line8 |
|
||||
{10: } |
|
||||
^ |
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<c-\\><c-n>gg')
|
||||
@ -195,7 +195,7 @@ it('CursorLine and CursorColumn work in :terminal buffer in Normal mode', functi
|
||||
local screen = Screen.new(50, 7)
|
||||
screen:set_default_attr_ids({
|
||||
[1] = { background = Screen.colors.Grey90 }, -- CursorLine, CursorColumn
|
||||
[2] = { reverse = true }, -- TermCursor
|
||||
[2] = { reverse = true },
|
||||
[3] = { bold = true }, -- ModeMsg
|
||||
[4] = { background = Screen.colors.Grey90, reverse = true },
|
||||
[5] = { background = Screen.colors.Red },
|
||||
@ -234,7 +234,7 @@ it('CursorLine and CursorColumn work in :terminal buffer in Normal mode', functi
|
||||
foobar foobar foobar foobar foobar foobar foobar f|
|
||||
oobar foobar foobar foobar foobar foobar foobar fo|
|
||||
obar foobar foobar foobar foobar foobar foobar foo|
|
||||
bar foobar{2: } |
|
||||
bar foobar^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
-- Leaving terminal mode restores old values.
|
||||
@ -248,46 +248,60 @@ it('CursorLine and CursorColumn work in :terminal buffer in Normal mode', functi
|
||||
{1:bar fooba^r }|
|
||||
|
|
||||
]])
|
||||
-- CursorLine and CursorColumn are combined with TermCursorNC.
|
||||
command('highlight TermCursorNC gui=reverse')
|
||||
|
||||
-- Skip the rest of these tests on Windows #31587
|
||||
if is_os('win') then
|
||||
return
|
||||
end
|
||||
|
||||
-- CursorLine and CursorColumn are combined with terminal colors.
|
||||
tt.set_reverse()
|
||||
tt.feed_data(' foobar')
|
||||
tt.clear_attrs()
|
||||
screen:expect([[
|
||||
tty ready{1: } |
|
||||
foobar f{1:o}obar foobar foobar foobar foobar foobar |
|
||||
foobar fo{1:o}bar foobar foobar foobar foobar foobar f|
|
||||
oobar foo{1:b}ar foobar foobar foobar foobar foobar fo|
|
||||
obar foob{1:a}r foobar foobar foobar foobar foobar foo|
|
||||
{1:bar fooba^r}{4: }{1: }|
|
||||
{1:bar fooba^r}{4: foobar}{1: }|
|
||||
|
|
||||
]])
|
||||
feed('2gg11|')
|
||||
feed('2gg15|')
|
||||
screen:expect([[
|
||||
tty ready {1: } |
|
||||
{1: foobar fo^obar foobar foobar foobar foobar foobar }|
|
||||
foobar foo{1:b}ar foobar foobar foobar foobar foobar f|
|
||||
oobar foob{1:a}r foobar foobar foobar foobar foobar fo|
|
||||
obar fooba{1:r} foobar foobar foobar foobar foobar foo|
|
||||
bar foobar{4: } |
|
||||
tty ready {1: } |
|
||||
{1: foobar foobar^ foobar foobar foobar foobar foobar }|
|
||||
foobar foobar {1:f}oobar foobar foobar foobar foobar f|
|
||||
oobar foobar f{1:o}obar foobar foobar foobar foobar fo|
|
||||
obar foobar fo{1:o}bar foobar foobar foobar foobar foo|
|
||||
bar foobar{2: foo}{4:b}{2:ar} |
|
||||
|
|
||||
]])
|
||||
-- TermCursorNC has higher precedence.
|
||||
command('highlight TermCursorNC gui=NONE guibg=Red')
|
||||
|
||||
-- Set bg color to red
|
||||
tt.feed_csi('48;2;255:0:0m')
|
||||
tt.feed_data(' foobar')
|
||||
tt.clear_attrs()
|
||||
feed('2gg20|')
|
||||
|
||||
-- Terminal color has higher precedence
|
||||
screen:expect([[
|
||||
tty ready {1: } |
|
||||
{1: foobar fo^obar foobar foobar foobar foobar foobar }|
|
||||
foobar foo{1:b}ar foobar foobar foobar foobar foobar f|
|
||||
oobar foob{1:a}r foobar foobar foobar foobar foobar fo|
|
||||
obar fooba{1:r} foobar foobar foobar foobar foobar foo|
|
||||
bar foobar{5: } |
|
||||
tty ready {1: } |
|
||||
{1: foobar foobar foob^ar foobar foobar foobar foobar }|
|
||||
foobar foobar fooba{1:r} foobar foobar foobar foobar f|
|
||||
oobar foobar foobar{1: }foobar foobar foobar foobar fo|
|
||||
obar foobar foobar {1:f}oobar foobar foobar foobar foo|
|
||||
bar foobar{2: foobar}{5: foobar} |
|
||||
|
|
||||
]])
|
||||
feed('G$')
|
||||
screen:expect([[
|
||||
tty ready{1: } |
|
||||
foobar f{1:o}obar foobar foobar foobar foobar foobar |
|
||||
foobar fo{1:o}bar foobar foobar foobar foobar foobar f|
|
||||
oobar foo{1:b}ar foobar foobar foobar foobar foobar fo|
|
||||
obar foob{1:a}r foobar foobar foobar foobar foobar foo|
|
||||
{1:bar fooba^r}{5: }{1: }|
|
||||
tty ready {1: } |
|
||||
foobar foobar foobar f{1:o}obar foobar foobar foobar |
|
||||
foobar foobar foobar fo{1:o}bar foobar foobar foobar f|
|
||||
oobar foobar foobar foo{1:b}ar foobar foobar foobar fo|
|
||||
obar foobar foobar foob{1:a}r foobar foobar foobar foo|
|
||||
{1:bar foobar}{4: foobar}{5: fooba^r}{1: }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
@ -300,18 +314,17 @@ describe(':terminal highlight forwarding', function()
|
||||
screen = Screen.new(50, 7)
|
||||
screen:set_rgb_cterm(true)
|
||||
screen:set_default_attr_ids({
|
||||
[1] = { { reverse = true }, { reverse = true } },
|
||||
[2] = { { bold = true }, { bold = true } },
|
||||
[3] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } },
|
||||
[4] = { { foreground = tonumber('0xff8000') }, {} },
|
||||
[1] = { { bold = true }, { bold = true } },
|
||||
[2] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } },
|
||||
[3] = { { foreground = tonumber('0xff8000') }, {} },
|
||||
})
|
||||
command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
{2:-- TERMINAL --} |
|
||||
{1:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
@ -326,9 +339,9 @@ describe(':terminal highlight forwarding', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
tty ready |
|
||||
{3:text}{4:color}text{1: } |
|
||||
{2:text}{3:color}text^ |
|
||||
|*4
|
||||
{2:-- TERMINAL --} |
|
||||
{1:-- TERMINAL --} |
|
||||
]],
|
||||
}
|
||||
end)
|
||||
@ -355,7 +368,7 @@ describe(':terminal highlight with custom palette', function()
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{7: } |
|
||||
^ |
|
||||
|*4
|
||||
{9:-- TERMINAL --} |
|
||||
]])
|
||||
@ -369,7 +382,7 @@ describe(':terminal highlight with custom palette', function()
|
||||
tt.feed_data('text')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{1:text}text{7: } |
|
||||
{1:text}text^ |
|
||||
|*4
|
||||
{9:-- TERMINAL --} |
|
||||
]])
|
||||
|
@ -32,7 +32,7 @@ describe(':terminal mouse', function()
|
||||
line28 |
|
||||
line29 |
|
||||
line30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -107,7 +107,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -121,7 +121,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
"#{1: } |
|
||||
"#^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftDrag><2,2>')
|
||||
@ -131,7 +131,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
@##{1: } |
|
||||
@##^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftDrag><3,2>')
|
||||
@ -141,7 +141,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
@$#{1: } |
|
||||
@$#^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftRelease><3,2>')
|
||||
@ -151,7 +151,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
#$#{1: } |
|
||||
#$#^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -165,7 +165,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
`!!{1: } |
|
||||
`!!^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -179,7 +179,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
"#{1: } |
|
||||
"#^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<ScrollWheelUp><1,2>')
|
||||
@ -189,7 +189,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
`"#{1: } |
|
||||
`"#^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftDrag><2,2>')
|
||||
@ -199,7 +199,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
@##{1: } |
|
||||
@##^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<ScrollWheelUp><2,2>')
|
||||
@ -209,7 +209,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
`##{1: } |
|
||||
`##^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftRelease><2,2>')
|
||||
@ -219,7 +219,7 @@ describe(':terminal mouse', function()
|
||||
line29 |
|
||||
line30 |
|
||||
mouse enabled |
|
||||
###{1: } |
|
||||
###^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -237,7 +237,7 @@ describe(':terminal mouse', function()
|
||||
{7: 13 }line30 |
|
||||
{7: 14 }mouse enabled |
|
||||
{7: 15 }rows: 6, cols: 46 |
|
||||
{7: 16 }{2: } |
|
||||
{7: 16 } |
|
||||
|
|
||||
]])
|
||||
-- If click on the coordinate (0,1) of the region of the terminal
|
||||
@ -249,7 +249,7 @@ describe(':terminal mouse', function()
|
||||
{7: 13 }line30 |
|
||||
{7: 14 }mouse enabled |
|
||||
{7: 15 }rows: 6, cols: 46 |
|
||||
{7: 16 } !"{1: } |
|
||||
{7: 16 } !"^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -261,7 +261,7 @@ describe(':terminal mouse', function()
|
||||
line30 |
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -271,7 +271,7 @@ describe(':terminal mouse', function()
|
||||
line30 |
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
========== |
|
||||
|
|
||||
]])
|
||||
@ -280,7 +280,7 @@ describe(':terminal mouse', function()
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
rows: 4, cols: 50 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
========== |
|
||||
|*2
|
||||
]])
|
||||
@ -293,7 +293,7 @@ describe(':terminal mouse', function()
|
||||
line30 │{4:~ }|
|
||||
mouse enabled │{4:~ }|
|
||||
rows: 5, cols: 24 │{4:~ }|
|
||||
{1: } │{4:~ }|
|
||||
^ │{4:~ }|
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -303,7 +303,7 @@ describe(':terminal mouse', function()
|
||||
line30 │{4:~ }|
|
||||
mouse enabled │{4:~ }|
|
||||
rows: 5, cols: 24 │{4:~ }|
|
||||
{2:^ } │{4:~ }|
|
||||
^ │{4:~ }|
|
||||
========== ========== |
|
||||
|
|
||||
]])
|
||||
@ -313,7 +313,7 @@ describe(':terminal mouse', function()
|
||||
mouse enabled │{4:~ }|
|
||||
rows: 5, cols: 24 │{4:~ }|
|
||||
rows: 5, cols: 23 │{4:~ }|
|
||||
{2:^ } │{4:~ }|
|
||||
^ │{4:~ }|
|
||||
========== ========== |
|
||||
|
|
||||
]])
|
||||
@ -327,7 +327,7 @@ describe(':terminal mouse', function()
|
||||
line30 |
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftMouse><0,0>')
|
||||
@ -337,7 +337,7 @@ describe(':terminal mouse', function()
|
||||
line30 |
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
command('set showtabline=2 tabline=TABLINE | startinsert')
|
||||
@ -347,7 +347,7 @@ describe(':terminal mouse', function()
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
rows: 4, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftMouse><0,0>')
|
||||
@ -357,7 +357,7 @@ describe(':terminal mouse', function()
|
||||
mouse enabled |
|
||||
rows: 5, cols: 50 |
|
||||
rows: 4, cols: 50 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
command('setlocal winbar= | startinsert')
|
||||
@ -367,7 +367,7 @@ describe(':terminal mouse', function()
|
||||
rows: 5, cols: 50 |
|
||||
rows: 4, cols: 50 |
|
||||
rows: 5, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<LeftMouse><0,0>')
|
||||
@ -377,7 +377,7 @@ describe(':terminal mouse', function()
|
||||
rows: 5, cols: 50 |
|
||||
rows: 4, cols: 50 |
|
||||
rows: 5, cols: 50 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
@ -391,7 +391,7 @@ describe(':terminal mouse', function()
|
||||
line29 │line29 |
|
||||
line30 │line30 |
|
||||
rows: 5, cols: 25 │rows: 5, cols: 25 |
|
||||
{2:^ } │{2: } |
|
||||
^ │ |
|
||||
========== ========== |
|
||||
:vsp |
|
||||
]])
|
||||
@ -401,7 +401,7 @@ describe(':terminal mouse', function()
|
||||
{4:~ }│line30 |
|
||||
{4:~ }│rows: 5, cols: 25 |
|
||||
{4:~ }│rows: 5, cols: 24 |
|
||||
{4:~ }│{2: } |
|
||||
{4:~ }│ |
|
||||
========== ========== |
|
||||
:enew | set number |
|
||||
]])
|
||||
@ -411,7 +411,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }line │line30 |
|
||||
{7: 29 }line │rows: 5, cols: 25 |
|
||||
{7: 30 }line │rows: 5, cols: 24 |
|
||||
{7: 31 }^ │{2: } |
|
||||
{7: 31 }^ │ |
|
||||
========== ========== |
|
||||
|
|
||||
]])
|
||||
@ -421,7 +421,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }line │line30 |
|
||||
{7: 29 }line │rows: 5, cols: 25 |
|
||||
{7: 30 }line │rows: 5, cols: 24 |
|
||||
{7: 31 } │{1: } |
|
||||
{7: 31 } │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -434,7 +434,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }line │rows: 5, cols: 25 |
|
||||
{7: 29 }line │rows: 5, cols: 24 |
|
||||
{7: 30 }line │mouse enabled |
|
||||
{7: 31 } │{1: } |
|
||||
{7: 31 } │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -447,7 +447,7 @@ describe(':terminal mouse', function()
|
||||
{7: 22 }line │rows: 5, cols: 25 |
|
||||
{7: 23 }line │rows: 5, cols: 24 |
|
||||
{7: 24 }line │mouse enabled |
|
||||
{7: 25 }line │{1: } |
|
||||
{7: 25 }line │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -457,7 +457,7 @@ describe(':terminal mouse', function()
|
||||
{7: 27 }line │rows: 5, cols: 25 |
|
||||
{7: 28 }line │rows: 5, cols: 24 |
|
||||
{7: 29 }line │mouse enabled |
|
||||
{7: 30 }line │{1: } |
|
||||
{7: 30 }line │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -468,7 +468,7 @@ describe(':terminal mouse', function()
|
||||
{7: 17 }line │rows: 5, cols: 25 |
|
||||
{7: 18 }line │rows: 5, cols: 24 |
|
||||
{7: 19 }line │mouse enabled |
|
||||
{7: 20 }line │{1: } |
|
||||
{7: 20 }line │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -483,7 +483,7 @@ describe(':terminal mouse', function()
|
||||
{7: 2 }linelinelinelineline │rows: 5, cols: 25 |
|
||||
{7: 3 }linelinelinelineline │rows: 5, cols: 24 |
|
||||
{7: 4 }linelinelinelineline │mouse enabled |
|
||||
{7: 5 }linelinelinelineline │{1: } |
|
||||
{7: 5 }linelinelinelineline │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -493,7 +493,7 @@ describe(':terminal mouse', function()
|
||||
{7: 2 }nelinelineline │rows: 5, cols: 25 |
|
||||
{7: 3 }nelinelineline │rows: 5, cols: 24 |
|
||||
{7: 4 }nelinelineline │mouse enabled |
|
||||
{7: 5 }nelinelineline │{1: } |
|
||||
{7: 5 }nelinelineline │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -504,7 +504,7 @@ describe(':terminal mouse', function()
|
||||
{7: 2 }nelinelinelineline │rows: 5, cols: 25 |
|
||||
{7: 3 }nelinelinelineline │rows: 5, cols: 24 |
|
||||
{7: 4 }nelinelinelineline │mouse enabled |
|
||||
{7: 5 }nelinelinelineline │{1: } |
|
||||
{7: 5 }nelinelinelineline │^ |
|
||||
========== ========== |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -517,7 +517,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }l^ine │rows: 5, cols: 25 |
|
||||
{7: 29 }line │rows: 5, cols: 24 |
|
||||
{7: 30 }line │mouse enabled |
|
||||
{7: 31 } │{2: } |
|
||||
{7: 31 } │ |
|
||||
========== ========== |
|
||||
|
|
||||
]])
|
||||
@ -531,7 +531,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }line │rows: 5, cols: 25 |
|
||||
{7: 29 }line │rows: 5, cols: 24 |
|
||||
{7: 30 }line │mouse enabled |
|
||||
{7: 31 }^ │{2: } |
|
||||
{7: 31 }^ │ |
|
||||
========== ========== |
|
||||
|
|
||||
]])
|
||||
@ -541,7 +541,7 @@ describe(':terminal mouse', function()
|
||||
rows: 5, cols: 24 │rows: 5, cols: 24 |
|
||||
mouse enabled │mouse enabled |
|
||||
rows: 5, cols: 25 │rows: 5, cols: 25 |
|
||||
{2:^ } │{2: } |
|
||||
^ │ |
|
||||
========== ========== |
|
||||
:bn |
|
||||
]])
|
||||
@ -551,7 +551,7 @@ describe(':terminal mouse', function()
|
||||
{7: 28 }line │mouse enabled |
|
||||
{7: 29 }line │rows: 5, cols: 25 |
|
||||
{7: 30 }line │rows: 5, cols: 24 |
|
||||
{7: 31 }^ │{2: } |
|
||||
{7: 31 }^ │ |
|
||||
========== ========== |
|
||||
:bn |
|
||||
]])
|
||||
|
@ -39,7 +39,7 @@ describe(':terminal scrollback', function()
|
||||
line28 |
|
||||
line29 |
|
||||
line30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -67,7 +67,7 @@ describe(':terminal scrollback', function()
|
||||
line2 |
|
||||
line3 |
|
||||
line4 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -84,7 +84,7 @@ describe(':terminal scrollback', function()
|
||||
line3 |
|
||||
line4 |
|
||||
line5 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq(7, api.nvim_buf_line_count(0))
|
||||
@ -102,7 +102,7 @@ describe(':terminal scrollback', function()
|
||||
line5 |
|
||||
line6 |
|
||||
line7 |
|
||||
line8{1: } |
|
||||
line8^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
@ -135,7 +135,7 @@ describe(':terminal scrollback', function()
|
||||
line5 |
|
||||
line6 |
|
||||
line7 |
|
||||
^line8{2: } |
|
||||
^line8 |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
@ -151,7 +151,7 @@ describe(':terminal scrollback', function()
|
||||
line3 |
|
||||
line4 |
|
||||
rows: 5, cols: 28 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
end
|
||||
@ -168,7 +168,7 @@ describe(':terminal scrollback', function()
|
||||
screen:expect([[
|
||||
rows: 5, cols: 28 |
|
||||
rows: 3, cols: 26 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
eq(8, api.nvim_buf_line_count(0))
|
||||
@ -201,7 +201,7 @@ describe(':terminal scrollback', function()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
rows: 4, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -220,7 +220,7 @@ describe(':terminal scrollback', function()
|
||||
screen:expect([[
|
||||
rows: 4, cols: 30 |
|
||||
rows: 3, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq(4, api.nvim_buf_line_count(0))
|
||||
@ -235,7 +235,7 @@ describe(':terminal scrollback', function()
|
||||
screen:expect([[
|
||||
rows: 4, cols: 30 |
|
||||
rows: 3, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -252,14 +252,14 @@ describe(':terminal scrollback', function()
|
||||
line2 |
|
||||
line3 |
|
||||
line4 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
screen:try_resize(screen._width, screen._height - 3)
|
||||
screen:expect([[
|
||||
line4 |
|
||||
rows: 3, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq(7, api.nvim_buf_line_count(0))
|
||||
@ -278,7 +278,7 @@ describe(':terminal scrollback', function()
|
||||
line4 |
|
||||
rows: 3, cols: 30 |
|
||||
rows: 4, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end
|
||||
@ -300,7 +300,7 @@ describe(':terminal scrollback', function()
|
||||
rows: 3, cols: 30 |
|
||||
rows: 4, cols: 30 |
|
||||
rows: 7, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
eq(9, api.nvim_buf_line_count(0))
|
||||
@ -337,7 +337,7 @@ describe(':terminal scrollback', function()
|
||||
rows: 4, cols: 30 |
|
||||
rows: 7, cols: 30 |
|
||||
rows: 11, cols: 30 |
|
||||
{1: } |
|
||||
^ |
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -362,7 +362,7 @@ describe(':terminal prints more lines than the screen height and exits', functio
|
||||
line8 |
|
||||
line9 |
|
||||
|
|
||||
[Process exited 0]{2: } |
|
||||
[Process exited 0]^ |
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<cr>')
|
||||
@ -454,7 +454,7 @@ describe("'scrollback' option", function()
|
||||
39: line |
|
||||
40: line |
|
||||
|
|
||||
${1: } |
|
||||
$^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
}
|
||||
@ -493,7 +493,7 @@ describe("'scrollback' option", function()
|
||||
line28 |
|
||||
line29 |
|
||||
line30 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
local term_height = 6 -- Actual terminal screen height, not the scrollback
|
||||
@ -634,7 +634,7 @@ describe('pending scrollback line handling', function()
|
||||
screen:expect [[
|
||||
hi |*4
|
||||
|
|
||||
[Process exited 0]{2: } |
|
||||
[Process exited 0]^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]]
|
||||
assert_alive()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@ describe(':terminal window', function()
|
||||
screen:expect([[
|
||||
{7:1 }tty ready |
|
||||
{7:2 }rows: 6, cols: 48 |
|
||||
{7:3 }{1: } |
|
||||
{7:3 }^ |
|
||||
{7:4 } |
|
||||
{7:5 } |
|
||||
{7:6 } |
|
||||
@ -73,7 +73,7 @@ describe(':terminal window', function()
|
||||
{7:1 }tty ready |
|
||||
{7:2 }rows: 6, cols: 48 |
|
||||
{7:3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV|
|
||||
{7:4 }WXYZ{1: } |
|
||||
{7:4 }WXYZ^ |
|
||||
{7:5 } |
|
||||
{7:6 } |
|
||||
{3:-- TERMINAL --} |
|
||||
@ -87,7 +87,7 @@ describe(':terminal window', function()
|
||||
{7: 2 }rows: 6, cols: 48 |
|
||||
{7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
|
||||
{7: 4 }PQRSTUVWXYZrows: 6, cols: 41 |
|
||||
{7: 5 }{1: } |
|
||||
{7: 5 }^ |
|
||||
{7: 6 } |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -98,7 +98,7 @@ describe(':terminal window', function()
|
||||
{7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
|
||||
{7: 4 }PQRSTUVWXYZrows: 6, cols: 41 |
|
||||
{7: 5 } abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN|
|
||||
{7: 6 }OPQRSTUVWXYZ{1: } |
|
||||
{7: 6 }OPQRSTUVWXYZ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -110,7 +110,7 @@ describe(':terminal window', function()
|
||||
screen:expect([[
|
||||
{7:++1 }tty ready |
|
||||
{7:++2 }rows: 6, cols: 45 |
|
||||
{7:++3 }{1: } |
|
||||
{7:++3 }^ |
|
||||
{7:++4 } |
|
||||
{7:++5 } |
|
||||
{7:++6 } |
|
||||
@ -123,7 +123,7 @@ describe(':terminal window', function()
|
||||
{7:++6 } |
|
||||
{7:++7 } |
|
||||
{7:++8 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS|
|
||||
{7:++9 }TUVWXYZ{1: } |
|
||||
{7:++9 }TUVWXYZ^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed_data('\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
||||
@ -133,7 +133,7 @@ describe(':terminal window', function()
|
||||
{7:++ 9 }STUVWXYZ |
|
||||
{7:++10 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
|
||||
{7:++11 }STUVWXYZrows: 6, cols: 44 |
|
||||
{7:++12 }{1: } |
|
||||
{7:++12 }^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -144,7 +144,7 @@ describe(':terminal window', function()
|
||||
feed([[<C-\><C-N>]])
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
feed(':set colorcolumn=20<CR>i')
|
||||
@ -153,7 +153,7 @@ describe(':terminal window', function()
|
||||
it('wont show the color column', function()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -170,7 +170,7 @@ describe(':terminal window', function()
|
||||
line2 |
|
||||
line3 |
|
||||
line4 |
|
||||
{1: } |
|
||||
^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
@ -184,7 +184,7 @@ describe(':terminal window', function()
|
||||
line2 |
|
||||
line3 |
|
||||
line4 |
|
||||
{2: } |
|
||||
|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
@ -206,7 +206,7 @@ describe(':terminal with multigrid', function()
|
||||
[3:--------------------------------------------------]|
|
||||
## grid 2
|
||||
tty ready |
|
||||
{1: } |
|
||||
^ |
|
||||
|*4
|
||||
## grid 3
|
||||
{3:-- TERMINAL --} |
|
||||
@ -223,7 +223,7 @@ describe(':terminal with multigrid', function()
|
||||
## grid 2
|
||||
tty ready |
|
||||
rows: 10, cols: 20 |
|
||||
{1: } |
|
||||
^ |
|
||||
|*7
|
||||
## grid 3
|
||||
{3:-- TERMINAL --} |
|
||||
@ -241,7 +241,7 @@ describe(':terminal with multigrid', function()
|
||||
## grid 2
|
||||
rows: 10, cols: 20 |
|
||||
rows: 3, cols: 70 |
|
||||
{1: } |
|
||||
^ |
|
||||
## grid 3
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -260,7 +260,7 @@ describe(':terminal with multigrid', function()
|
||||
rows: 10, cols: 20 |
|
||||
rows: 3, cols: 70 |
|
||||
rows: 6, cols: 50 |
|
||||
{1: } |
|
||||
^ |
|
||||
|
|
||||
## grid 3
|
||||
{3:-- TERMINAL --} |
|
||||
|
@ -49,7 +49,7 @@ describe(':terminal', function()
|
||||
========== |
|
||||
tty ready |
|
||||
rows: 5, cols: 50 |
|
||||
{2: } |
|
||||
|
|
||||
|*2
|
||||
========== |
|
||||
:2split |
|
||||
@ -61,7 +61,7 @@ describe(':terminal', function()
|
||||
========== |
|
||||
^tty ready |
|
||||
rows: 5, cols: 50 |
|
||||
{2: } |
|
||||
|
|
||||
|*2
|
||||
========== |
|
||||
:wincmd p |
|
||||
@ -77,7 +77,7 @@ describe(':terminal', function()
|
||||
command('bprevious')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
^foo{2: } |
|
||||
^foo |
|
||||
|*8
|
||||
]])
|
||||
end)
|
||||
@ -102,7 +102,7 @@ describe(':terminal', function()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
rows: 7, cols: 47 |
|
||||
{2: } |
|
||||
|
|
||||
|*3
|
||||
^ |
|
||||
|
|
||||
@ -112,7 +112,7 @@ describe(':terminal', function()
|
||||
tty ready |
|
||||
rows: 7, cols: 47 |
|
||||
rows: 4, cols: 41 |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
@ -29,6 +29,10 @@ function M.feed_termcode(data)
|
||||
M.feed_data('\027' .. data)
|
||||
end
|
||||
|
||||
function M.feed_csi(data)
|
||||
M.feed_termcode('[' .. data)
|
||||
end
|
||||
|
||||
function M.make_lua_executor(session)
|
||||
return function(code, ...)
|
||||
local status, rv = session:request('nvim_exec_lua', code, { ... })
|
||||
@ -78,6 +82,9 @@ end
|
||||
function M.set_undercurl()
|
||||
M.feed_termcode('[4:3m')
|
||||
end
|
||||
function M.set_reverse()
|
||||
M.feed_termcode('[7m')
|
||||
end
|
||||
function M.set_strikethrough()
|
||||
M.feed_termcode('[9m')
|
||||
end
|
||||
@ -108,7 +115,6 @@ function M.setup_screen(extra_rows, cmd, cols, env, screen_opts)
|
||||
cols = cols and cols or 50
|
||||
|
||||
api.nvim_command('highlight TermCursor cterm=reverse')
|
||||
api.nvim_command('highlight TermCursorNC ctermbg=11')
|
||||
api.nvim_command('highlight StatusLineTerm ctermbg=2 ctermfg=0')
|
||||
api.nvim_command('highlight StatusLineTermNC ctermbg=2 ctermfg=8')
|
||||
|
||||
@ -154,7 +160,7 @@ function M.setup_screen(extra_rows, cmd, cols, env, screen_opts)
|
||||
local empty_line = (' '):rep(cols)
|
||||
local expected = {
|
||||
'tty ready' .. (' '):rep(cols - 9),
|
||||
'{1: }' .. (' '):rep(cols - 1),
|
||||
'^' .. (' '):rep(cols),
|
||||
empty_line,
|
||||
empty_line,
|
||||
empty_line,
|
||||
|
@ -190,6 +190,19 @@ describe('ui/cursor', function()
|
||||
attr_lm = {},
|
||||
short_name = 'sm',
|
||||
},
|
||||
[18] = {
|
||||
blinkoff = 500,
|
||||
blinkon = 500,
|
||||
blinkwait = 0,
|
||||
cell_percentage = 0,
|
||||
cursor_shape = 'block',
|
||||
name = 'terminal',
|
||||
hl_id = 3,
|
||||
id_lm = 3,
|
||||
attr = { reverse = true },
|
||||
attr_lm = { reverse = true },
|
||||
short_name = 't',
|
||||
},
|
||||
}
|
||||
|
||||
screen:expect(function()
|
||||
@ -245,17 +258,20 @@ describe('ui/cursor', function()
|
||||
end
|
||||
end
|
||||
if m.hl_id then
|
||||
m.hl_id = 66
|
||||
m.hl_id = 65
|
||||
m.attr = { background = Screen.colors.DarkGray }
|
||||
end
|
||||
if m.id_lm then
|
||||
m.id_lm = 73
|
||||
m.id_lm = 72
|
||||
m.attr_lm = {}
|
||||
end
|
||||
end
|
||||
|
||||
-- Assert the new expectation.
|
||||
screen:expect(function()
|
||||
eq(expected_mode_info, screen._mode_info)
|
||||
for i, v in ipairs(expected_mode_info) do
|
||||
eq(v, screen._mode_info[i])
|
||||
end
|
||||
eq(true, screen._cursor_style_enabled)
|
||||
eq('normal', screen.mode)
|
||||
end)
|
||||
|
@ -631,7 +631,7 @@ describe('decorations providers', function()
|
||||
{14: }hello97 |
|
||||
{14: }hello98 |
|
||||
{14: }hello99 |
|
||||
X ^hello100 |
|
||||
{14:X }^hello100 |
|
||||
{14: }hello101 |
|
||||
{14: }hello102 |
|
||||
{14: }hello103 |
|
||||
@ -2301,13 +2301,16 @@ describe('extmark decorations', function()
|
||||
|
||||
it('works with both hl_group and sign_hl_group', function()
|
||||
screen:try_resize(50, 3)
|
||||
screen:add_extra_attr_ids({
|
||||
[100] = { background = Screen.colors.WebGray, foreground = Screen.colors.Blue, bold = true },
|
||||
})
|
||||
insert('abcdefghijklmn')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S', sign_hl_group='NonText', hl_group='Error', end_col=14})
|
||||
screen:expect{grid=[[
|
||||
{1:S }{4:abcdefghijklm^n} |
|
||||
screen:expect([[
|
||||
{100:S }{9:abcdefghijklm^n} |
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('virt_text_repeat_linebreak repeats virtual text on wrapped lines', function()
|
||||
@ -5064,16 +5067,16 @@ l5
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S'})
|
||||
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S l2 |
|
||||
{7:S }l2 |
|
||||
{7: }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add a single sign (with end row)', function()
|
||||
@ -5082,16 +5085,16 @@ l5
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row=1})
|
||||
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S l2 |
|
||||
{7:S }l2 |
|
||||
{7: }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add a single sign and text highlight', function()
|
||||
@ -5099,16 +5102,16 @@ l5
|
||||
feed 'gg'
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text='S', hl_group='Todo', end_col=1})
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S {100:l}2 |
|
||||
{7:S }{100:l}2 |
|
||||
{7: }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
|
||||
api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
end)
|
||||
@ -5119,16 +5122,16 @@ l5
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row = 2})
|
||||
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S l2 |
|
||||
S l3 |
|
||||
{7:S }l2 |
|
||||
{7:S }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add multiple signs (multiple extmarks)', function()
|
||||
@ -5138,16 +5141,16 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S1'})
|
||||
api.nvim_buf_set_extmark(0, ns, 3, -1, {sign_text='S2', end_row = 4})
|
||||
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S1l2 |
|
||||
{7:S1}l2 |
|
||||
{7: }l3 |
|
||||
S2l4 |
|
||||
S2l5 |
|
||||
{7:S2}l4 |
|
||||
{7:S2}l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add multiple signs (multiple extmarks) 2', function()
|
||||
@ -5156,16 +5159,16 @@ l5
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 3, -1, {sign_text='S1'})
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row = 3})
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S2{7: }l2 |
|
||||
S2{7: }l3 |
|
||||
S2S1l4 |
|
||||
{7:S2 }l2 |
|
||||
{7:S2 }l3 |
|
||||
{7:S2S1}l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add multiple signs (multiple extmarks) 3', function()
|
||||
@ -5176,16 +5179,16 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S1', end_row=2})
|
||||
api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S2', end_row=3})
|
||||
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
S1{7: }l2 |
|
||||
S2S1l3 |
|
||||
S2{7: }l4 |
|
||||
{7:S1 }l2 |
|
||||
{7:S2S1}l3 |
|
||||
{7:S2 }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add multiple signs (multiple extmarks) 4', function()
|
||||
@ -5195,16 +5198,16 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=0})
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row=1})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S1^l1 |
|
||||
S2l2 |
|
||||
screen:expect([[
|
||||
{7:S1}^l1 |
|
||||
{7:S2}l2 |
|
||||
{7: }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('works with old signs', function()
|
||||
@ -5219,16 +5222,16 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S4'})
|
||||
api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S5'})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S4S1^l1 |
|
||||
S2x l2 |
|
||||
S5{7: }l3 |
|
||||
screen:expect([[
|
||||
{7:S4S1}^l1 |
|
||||
{7:S2x }l2 |
|
||||
{7:S5 }l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('works with old signs (with range)', function()
|
||||
@ -5244,16 +5247,16 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S4'})
|
||||
api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S5'})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S4S3S1^l1 |
|
||||
S3S2x l2 |
|
||||
S5S3{7: }l3 |
|
||||
S3{7: }l4 |
|
||||
S3{7: }l5 |
|
||||
screen:expect([[
|
||||
{7:S4S3S1}^l1 |
|
||||
{7:S3S2x }l2 |
|
||||
{7:S5S3 }l3 |
|
||||
{7:S3 }l4 |
|
||||
{7:S3 }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add a ranged sign (with start out of view)', function()
|
||||
@ -5264,14 +5267,14 @@ l5
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='X', end_row=3})
|
||||
|
||||
screen:expect{grid=[[
|
||||
X {7: }^l3 |
|
||||
X {7: }l4 |
|
||||
screen:expect([[
|
||||
{7:X }^l3 |
|
||||
{7:X }l4 |
|
||||
{7: }l5 |
|
||||
{7: } |
|
||||
{1:~ }|*5
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can add lots of signs', function()
|
||||
@ -5293,11 +5296,11 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, i, -1, { sign_text='Z' })
|
||||
end
|
||||
|
||||
screen:expect{grid=[[
|
||||
Z Y X W {100:a} {100:b} {100:c} {100:d} {100:e} {100:f} {100:g} {100:h} |*8
|
||||
Z Y X W {100:a} {100:b} {100:c} {100:d} {100:e} {100:f} {100:g} {100:^h} |
|
||||
screen:expect([[
|
||||
{7:Z Y X W }{100:a} {100:b} {100:c} {100:d} {100:e} {100:f} {100:g} {100:h} |*8
|
||||
{7:Z Y X W }{100:a} {100:b} {100:c} {100:d} {100:e} {100:f} {100:g} {100:^h} |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('works with priority #19716', function()
|
||||
@ -5313,20 +5316,20 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200})
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S5S4O3S2S1^l1 |
|
||||
screen:expect([[
|
||||
{7:S5S4O3S2S1}^l1 |
|
||||
{7: }l2 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
|
||||
-- Check truncation works too
|
||||
api.nvim_set_option_value('signcolumn', 'auto', {})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S5^l1 |
|
||||
screen:expect([[
|
||||
{7:S5}^l1 |
|
||||
{7: }l2 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('does not overflow with many old signs #23852', function()
|
||||
@ -5343,21 +5346,21 @@ l5
|
||||
command([[exe 'sign place 07 line=1 name=Oldsign priority=10 buffer=' . bufnr('')]])
|
||||
command([[exe 'sign place 08 line=1 name=Oldsign priority=10 buffer=' . bufnr('')]])
|
||||
command([[exe 'sign place 09 line=1 name=Oldsign priority=10 buffer=' . bufnr('')]])
|
||||
screen:expect{grid=[[
|
||||
O3O3O3O3O3O3O3O3O3^ |
|
||||
screen:expect([[
|
||||
{7:O3O3O3O3O3O3O3O3O3}^ |
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1})
|
||||
screen:expect_unchanged()
|
||||
|
||||
api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200})
|
||||
screen:expect{grid=[[
|
||||
S5O3O3O3O3O3O3O3O3^ |
|
||||
screen:expect([[
|
||||
{7:S5O3O3O3O3O3O3O3O3}^ |
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
|
||||
assert_alive()
|
||||
end)
|
||||
@ -5383,12 +5386,12 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 1, -1, {invalidate = true, sign_text='S3'})
|
||||
feed('2Gdd')
|
||||
|
||||
screen:expect{grid=[[
|
||||
S1l1 |
|
||||
S1^l3 |
|
||||
S1l4 |
|
||||
screen:expect([[
|
||||
{7:S1}l1 |
|
||||
{7:S1}^l3 |
|
||||
{7:S1}l4 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct width with multiple overlapping signs', function()
|
||||
@ -5400,36 +5403,36 @@ l5
|
||||
feed('gg')
|
||||
|
||||
local s1 = [[
|
||||
S2S1^l1 |
|
||||
S3S2l2 |
|
||||
S3S2l3 |
|
||||
{7:S2S1}^l1 |
|
||||
{7:S3S2}l2 |
|
||||
{7:S3S2}l3 |
|
||||
|
|
||||
]]
|
||||
screen:expect{grid=s1}
|
||||
screen:expect(s1)
|
||||
-- Correct width when :move'ing a line with signs
|
||||
command('move2')
|
||||
screen:expect{grid=[[
|
||||
S3{7: }l2 |
|
||||
S3S2S1^l1 |
|
||||
screen:expect([[
|
||||
{7:S3 }l2 |
|
||||
{7:S3S2S1}^l1 |
|
||||
{7: }l3 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
command('silent undo')
|
||||
screen:expect{grid=s1}
|
||||
command('d')
|
||||
screen:expect{grid=[[
|
||||
S3S2S1^l2 |
|
||||
S3S2{7: }l3 |
|
||||
screen:expect([[
|
||||
{7:S3S2S1}^l2 |
|
||||
{7:S3S2 }l3 |
|
||||
{7: }l4 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
command('d')
|
||||
screen:expect{grid=[[
|
||||
S3S2S1^l3 |
|
||||
screen:expect([[
|
||||
{7:S3S2S1}^l3 |
|
||||
{7: }l4 |
|
||||
{7: }l5 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct width when adding and removing multiple signs', function()
|
||||
@ -5452,12 +5455,12 @@ l5
|
||||
redraw!
|
||||
call nvim_buf_del_extmark(0, ns, s1)
|
||||
]])
|
||||
screen:expect{grid=[[
|
||||
S1^l1 |
|
||||
S1l2 |
|
||||
S1l3 |
|
||||
screen:expect([[
|
||||
{7:S1}^l1 |
|
||||
{7:S1}l2 |
|
||||
{7:S1}l3 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct width when deleting lines', function()
|
||||
@ -5472,12 +5475,12 @@ l5
|
||||
call nvim_buf_del_extmark(0, ns, s3)
|
||||
norm 4Gdd
|
||||
]])
|
||||
screen:expect{grid=[[
|
||||
screen:expect([[
|
||||
{7: }l3 |
|
||||
S2S1l5 |
|
||||
{7:S2S1}l5 |
|
||||
{7: }^ |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct width when splitting lines with signs on different columns', function()
|
||||
@ -5487,12 +5490,12 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S1'})
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 1, {sign_text='S2'})
|
||||
feed('a<cr><esc>')
|
||||
screen:expect{grid=[[
|
||||
S1l |
|
||||
S2^1 |
|
||||
screen:expect([[
|
||||
{7:S1}l |
|
||||
{7:S2}^1 |
|
||||
{7: }l2 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct width after wiping a buffer', function()
|
||||
@ -5501,12 +5504,12 @@ l5
|
||||
feed('gg')
|
||||
local buf = api.nvim_get_current_buf()
|
||||
api.nvim_buf_set_extmark(buf, ns, 0, 0, { sign_text = 'h' })
|
||||
screen:expect{grid=[[
|
||||
h ^l1 |
|
||||
screen:expect([[
|
||||
{7:h }^l1 |
|
||||
{7: }l2 |
|
||||
{7: }l3 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
api.nvim_win_set_buf(0, api.nvim_create_buf(false, true))
|
||||
api.nvim_buf_delete(buf, {unload=true, force=true})
|
||||
api.nvim_buf_set_lines(buf, 0, -1, false, {''})
|
||||
@ -5537,12 +5540,12 @@ l5
|
||||
end)
|
||||
]])
|
||||
|
||||
screen:expect{grid=[[
|
||||
S1^l1 |
|
||||
S2l2 |
|
||||
S4l3 |
|
||||
screen:expect([[
|
||||
{7:S1}^l1 |
|
||||
{7:S2}l2 |
|
||||
{7:S4}l3 |
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('no crash with sign after many marks #27137', function()
|
||||
@ -5553,11 +5556,11 @@ l5
|
||||
end
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text = 'S1'})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S1{9:^a} |
|
||||
screen:expect([[
|
||||
{7:S1}{9:^a} |
|
||||
{1:~ }|*2
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct sort order with multiple namespaces and same id', function()
|
||||
@ -5565,11 +5568,11 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text = 'S1', id = 1})
|
||||
api.nvim_buf_set_extmark(0, ns2, 0, 0, {sign_text = 'S2', id = 1})
|
||||
|
||||
screen:expect{grid=[[
|
||||
S2S1^ |
|
||||
screen:expect([[
|
||||
{7:S2S1}^ |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]]}
|
||||
]])
|
||||
end)
|
||||
|
||||
it('correct number of signs after deleting text (#27046)', function()
|
||||
@ -5586,12 +5589,12 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 30, 0, {end_row = 30, end_col = 3, hl_group = 'Error'})
|
||||
command('0d29')
|
||||
|
||||
screen:expect{grid=[[
|
||||
S4S3S2S1{9:^foo} |
|
||||
S5{7: }{9:foo} |
|
||||
screen:expect([[
|
||||
{7:S4S3S2S1}{9:^foo} |
|
||||
{7:S5 }{9:foo} |
|
||||
{1:~ }|*7
|
||||
29 fewer lines |
|
||||
]]}
|
||||
]])
|
||||
|
||||
api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
end)
|
||||
@ -5599,21 +5602,17 @@ l5
|
||||
it([[correct numberwidth with 'signcolumn' set to "number" #28984]], function()
|
||||
command('set number numberwidth=1 signcolumn=number')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { sign_text = 'S1' })
|
||||
screen:expect({
|
||||
grid = [[
|
||||
S1 ^ |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]]
|
||||
})
|
||||
screen:expect([[
|
||||
{7:S1 }^ |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]])
|
||||
api.nvim_buf_del_extmark(0, ns, 1)
|
||||
screen:expect({
|
||||
grid = [[
|
||||
{8:1 }^ |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]]
|
||||
})
|
||||
screen:expect([[
|
||||
{8:1 }^ |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('supports emoji as signs', function()
|
||||
@ -5626,10 +5625,10 @@ l5
|
||||
api.nvim_buf_set_extmark(0, ns, 4, 0, {sign_text='❤x'})
|
||||
screen:expect([[
|
||||
{7: }^l1 |
|
||||
🧑🌾l2 |
|
||||
❤️l3 |
|
||||
❤ l4 |
|
||||
❤xl5 |
|
||||
{7:🧑🌾}l2 |
|
||||
{7:❤️}l3 |
|
||||
{7:❤ }l4 |
|
||||
{7:❤x}l5 |
|
||||
{7: } |
|
||||
{1:~ }|*3
|
||||
|
|
||||
|
@ -1046,6 +1046,8 @@ describe('float window', function()
|
||||
[26] = {blend = 80, background = Screen.colors.Gray0};
|
||||
[27] = {foreground = Screen.colors.Black, background = Screen.colors.LightGrey};
|
||||
[28] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey};
|
||||
[29] = {background = Screen.colors.Yellow1, foreground = Screen.colors.Blue4};
|
||||
[30] = {background = Screen.colors.Grey, foreground = Screen.colors.Blue4, bold = true};
|
||||
}
|
||||
screen:set_default_attr_ids(attrs)
|
||||
end)
|
||||
@ -1451,14 +1453,14 @@ describe('float window', function()
|
||||
[2:----------------------------------------]|*6
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{14: 2 }{22:y} |
|
||||
{19: }{14: 3 }{22: } |
|
||||
{0:~ }|*3
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x }|
|
||||
{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x }|
|
||||
{19: }{15:y }|
|
||||
{19: }{15: }|
|
||||
{15: }|
|
||||
@ -1466,9 +1468,9 @@ describe('float window', function()
|
||||
|
||||
else
|
||||
screen:expect([[
|
||||
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{14: 2 }{22:y} |
|
||||
{19: }{14: 3 }{22: } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
|
||||
{19: }{14: 3 }{22: } {29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
|
||||
{0:~ }{19: }{15:y }{0: }|
|
||||
{0:~ }{19: }{15: }{0: }|
|
||||
{0:~ }{15: }{0: }|
|
||||
@ -1551,14 +1553,14 @@ describe('float window', function()
|
||||
[2:----------------------------------------]|*6
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{14: 2 }{22:y} |
|
||||
{19: }{14: 3 }{22: } |
|
||||
{0:~ }|*3
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x }|
|
||||
{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x }|
|
||||
{19: }{15:y }|
|
||||
{19: }{15: }|
|
||||
{15: }|
|
||||
@ -1566,9 +1568,9 @@ describe('float window', function()
|
||||
|
||||
else
|
||||
screen:expect([[
|
||||
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
|
||||
{19: }{14: 2 }{22:y} |
|
||||
{19: }{14: 3 }{22: } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
|
||||
{19: }{14: 3 }{22: } {29:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
|
||||
{0:~ }{19: }{15:y }{0: }|
|
||||
{0:~ }{19: }{15: }{0: }|
|
||||
{0:~ }{15: }{0: }|
|
||||
@ -1621,7 +1623,7 @@ describe('float window', function()
|
||||
[2:----------------------------------------]|*6
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
{20: 1}{19: }{22:^x}{21: }|
|
||||
{20: 1}{30: }{22:^x}{21: }|
|
||||
{14: 2}{19: }{22:y} |
|
||||
{14: 3}{19: }{22: } |
|
||||
{0:~ }|*3
|
||||
@ -1634,7 +1636,7 @@ describe('float window', function()
|
||||
]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}}
|
||||
else
|
||||
screen:expect{grid=[[
|
||||
{20: 1}{19: }{22:^x}{21: }|
|
||||
{20: 1}{30: }{22:^x}{21: }|
|
||||
{14: 2}{19: }{22:y} |
|
||||
{14: 3}{19: }{22: } {15:x } |
|
||||
{0:~ }{15:y }{0: }|
|
||||
|
@ -227,7 +227,7 @@ describe('ext_hlstate detailed highlights', function()
|
||||
command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
{1: } |
|
||||
|
|
||||
|*5
|
||||
{7: }|
|
||||
]])
|
||||
@ -242,7 +242,7 @@ describe('ext_hlstate detailed highlights', function()
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
x {5:y z} |
|
||||
{1: } |
|
||||
|
|
||||
|*4
|
||||
{7: }|
|
||||
]])
|
||||
@ -250,7 +250,7 @@ describe('ext_hlstate detailed highlights', function()
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
x {2:y }{3:z} |
|
||||
{1: } |
|
||||
|
|
||||
|*4
|
||||
{7: }|
|
||||
]])
|
||||
@ -268,7 +268,7 @@ describe('ext_hlstate detailed highlights', function()
|
||||
else
|
||||
screen:expect([[
|
||||
^tty ready |
|
||||
x {4:y}{2: }{3:z} |
|
||||
x {2:y }{3:z} |
|
||||
|*5
|
||||
{7: }|
|
||||
]])
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user