mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 02:34:59 -07:00
Compare commits
17 Commits
3d0c47ce14
...
630e8b8919
Author | SHA1 | Date | |
---|---|---|---|
|
630e8b8919 | ||
|
02bc40c194 | ||
|
160cbd0ef4 | ||
|
3db3947b0e | ||
|
7121983c45 | ||
|
888a803755 | ||
|
07d5dc8938 | ||
|
f9eb68f340 | ||
|
738320188f | ||
|
38f554e9c4 | ||
|
f7c42433c5 | ||
|
51c380238c | ||
|
b7da54aa9e | ||
|
2f7b385f2e | ||
|
c830901e8c | ||
|
0dd933265f | ||
|
2e94406ba0 |
@ -60,6 +60,7 @@ hi('PmenuMatch', { link = 'Pmenu' })
|
||||
hi('PmenuMatchSel', { link = 'PmenuSel' })
|
||||
hi('PmenuExtra', { link = 'Pmenu' })
|
||||
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
||||
hi('ComplMatchIns', {})
|
||||
hi('Substitute', { link = 'Search' })
|
||||
hi('Whitespace', { link = 'NonText' })
|
||||
hi('MsgSeparator', { link = 'StatusLine' })
|
||||
|
@ -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
|
||||
|
@ -101,7 +101,8 @@ The result of foldexpr then determines the fold level as follows:
|
||||
"<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|.
|
||||
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
|
||||
@ -141,7 +142,7 @@ 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*
|
||||
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.
|
||||
@ -149,13 +150,15 @@ 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.
|
||||
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|:
|
||||
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
|
||||
@ -406,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*
|
||||
|
@ -1126,6 +1126,9 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
|
||||
server sent on `initialize` describing the
|
||||
server's capabilities.
|
||||
• {server_info} (`lsp.ServerInfo?`) Response from the server
|
||||
sent on `initialize` describing information
|
||||
about the server.
|
||||
• {progress} (`vim.lsp.Client.Progress`) A ring buffer
|
||||
(|vim.ringbuf()|) containing progress messages
|
||||
sent by the server. See
|
||||
|
@ -118,8 +118,8 @@ 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 visual selction includes the expected text and
|
||||
can be acted upon.
|
||||
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|
|
||||
@ -110,6 +115,7 @@ LSP
|
||||
• |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()|
|
||||
and |vim.lsp.util.make_given_range_params()| now require the `position_encoding`
|
||||
parameter.
|
||||
• `:checkhealth vim.lsp` displays the server version (if available).
|
||||
|
||||
LUA
|
||||
|
||||
@ -211,6 +217,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 +288,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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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'
|
||||
|
@ -1,19 +1,8 @@
|
||||
local api, fn = vim.api, vim.fn
|
||||
|
||||
local FIND_ARG = '-w'
|
||||
local localfile_arg = true -- Always use -l if possible. #6683
|
||||
|
||||
---@type table[]
|
||||
local buf_hls = {}
|
||||
|
||||
local M = {}
|
||||
|
||||
local function man_error(msg)
|
||||
M.errormsg = 'man.lua: ' .. vim.inspect(msg)
|
||||
error(M.errormsg)
|
||||
end
|
||||
|
||||
-- Run a system command and timeout after 30 seconds.
|
||||
--- Run a system command and timeout after 10 seconds.
|
||||
--- @param cmd string[]
|
||||
--- @param silent boolean?
|
||||
--- @param env? table<string,string|number>
|
||||
@ -24,7 +13,7 @@ local function system(cmd, silent, env)
|
||||
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))
|
||||
error(string.format("command error '%s': %s", cmd_str, r.stderr))
|
||||
end
|
||||
assert(r.stdout ~= '')
|
||||
end
|
||||
@ -32,65 +21,64 @@ local function system(cmd, silent, env)
|
||||
return assert(r.stdout)
|
||||
end
|
||||
|
||||
--- @enum Man.Attribute
|
||||
local Attrs = {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Underline = 2,
|
||||
Italic = 3,
|
||||
}
|
||||
|
||||
--- @param line string
|
||||
---@param linenr integer
|
||||
local function highlight_line(line, linenr)
|
||||
--- @param row integer
|
||||
--- @param hls {attr:Man.Attribute,row:integer,start:integer,final:integer}[]
|
||||
--- @return string
|
||||
local function render_line(line, row, hls)
|
||||
--- @type string[]
|
||||
local chars = {}
|
||||
local prev_char = ''
|
||||
local overstrike, escape, osc8 = false, false, false
|
||||
|
||||
---@type table<integer,{attr:integer,start:integer,final:integer}>
|
||||
local hls = {} -- Store highlight groups as { attr, start, final }
|
||||
|
||||
local NONE, BOLD, UNDERLINE, ITALIC = 0, 1, 2, 3
|
||||
local hl_groups = { [BOLD] = 'manBold', [UNDERLINE] = 'manUnderline', [ITALIC] = 'manItalic' }
|
||||
local attr = NONE
|
||||
local attr = Attrs.None
|
||||
local byte = 0 -- byte offset
|
||||
|
||||
local function end_attr_hl(attr_)
|
||||
for i, hl in ipairs(hls) do
|
||||
if hl.attr == attr_ and hl.final == -1 then
|
||||
hl.final = byte
|
||||
hls[i] = hl
|
||||
end
|
||||
end
|
||||
end
|
||||
local hls_start = #hls + 1
|
||||
|
||||
--- @param code integer
|
||||
local function add_attr_hl(code)
|
||||
local continue_hl = true
|
||||
if code == 0 then
|
||||
attr = NONE
|
||||
attr = Attrs.None
|
||||
continue_hl = false
|
||||
elseif code == 1 then
|
||||
attr = BOLD
|
||||
attr = Attrs.Bold
|
||||
elseif code == 22 then
|
||||
attr = BOLD
|
||||
attr = Attrs.Bold
|
||||
continue_hl = false
|
||||
elseif code == 3 then
|
||||
attr = ITALIC
|
||||
attr = Attrs.Italic
|
||||
elseif code == 23 then
|
||||
attr = ITALIC
|
||||
attr = Attrs.Italic
|
||||
continue_hl = false
|
||||
elseif code == 4 then
|
||||
attr = UNDERLINE
|
||||
attr = Attrs.Underline
|
||||
elseif code == 24 then
|
||||
attr = UNDERLINE
|
||||
attr = Attrs.Underline
|
||||
continue_hl = false
|
||||
else
|
||||
attr = NONE
|
||||
attr = Attrs.None
|
||||
return
|
||||
end
|
||||
|
||||
if continue_hl then
|
||||
hls[#hls + 1] = { attr = attr, start = byte, final = -1 }
|
||||
hls[#hls + 1] = { attr = attr, row = row, start = byte, final = -1 }
|
||||
else
|
||||
if attr == NONE then
|
||||
for a, _ in pairs(hl_groups) do
|
||||
end_attr_hl(a)
|
||||
for _, a in pairs(attr == Attrs.None and Attrs or { attr }) do
|
||||
for i = hls_start, #hls do
|
||||
if hls[i].attr == a and hls[i].final == -1 then
|
||||
hls[i].final = byte
|
||||
end
|
||||
end
|
||||
else
|
||||
end_attr_hl(attr)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -103,11 +91,11 @@ local function highlight_line(line, linenr)
|
||||
if overstrike then
|
||||
local last_hl = hls[#hls]
|
||||
if char == prev_char then
|
||||
if char == '_' and attr == ITALIC and last_hl and last_hl.final == byte then
|
||||
if char == '_' and attr == Attrs.Italic and last_hl and last_hl.final == byte then
|
||||
-- This underscore is in the middle of an italic word
|
||||
attr = ITALIC
|
||||
attr = Attrs.Italic
|
||||
else
|
||||
attr = BOLD
|
||||
attr = Attrs.Bold
|
||||
end
|
||||
elseif prev_char == '_' then
|
||||
-- Even though underline is strictly what this should be. <bs>_ was used by nroff to
|
||||
@ -116,26 +104,26 @@ local function highlight_line(line, linenr)
|
||||
-- See:
|
||||
-- - https://unix.stackexchange.com/questions/274658/purpose-of-ascii-text-with-overstriking-file-format/274795#274795
|
||||
-- - https://cmd.inp.nsk.su/old/cmd2/manuals/unix/UNIX_Unleashed/ch08.htm
|
||||
-- attr = UNDERLINE
|
||||
attr = ITALIC
|
||||
-- attr = Attrs.Underline
|
||||
attr = Attrs.Italic
|
||||
elseif prev_char == '+' and char == 'o' then
|
||||
-- bullet (overstrike text '+^Ho')
|
||||
attr = BOLD
|
||||
attr = Attrs.Bold
|
||||
char = '·'
|
||||
elseif prev_char == '·' and char == 'o' then
|
||||
-- bullet (additional handling for '+^H+^Ho^Ho')
|
||||
attr = BOLD
|
||||
attr = Attrs.Bold
|
||||
char = '·'
|
||||
else
|
||||
-- use plain char
|
||||
attr = NONE
|
||||
attr = Attrs.None
|
||||
end
|
||||
|
||||
-- Grow the previous highlight group if possible
|
||||
if last_hl and last_hl.attr == attr and last_hl.final == byte then
|
||||
last_hl.final = byte + #char
|
||||
else
|
||||
hls[#hls + 1] = { attr = attr, start = byte, final = byte + #char }
|
||||
hls[#hls + 1] = { attr = attr, row = row, start = byte, final = byte + #char }
|
||||
end
|
||||
|
||||
overstrike = false
|
||||
@ -158,10 +146,11 @@ local function highlight_line(line, linenr)
|
||||
local sgr = prev_char:match('^%[([\032-\063]*)m$')
|
||||
-- Ignore escape sequences with : characters, as specified by ITU's T.416
|
||||
-- Open Document Architecture and interchange format.
|
||||
if sgr and not string.find(sgr, ':') then
|
||||
if sgr and not sgr:find(':') then
|
||||
local match --- @type string?
|
||||
while sgr and #sgr > 0 do
|
||||
-- Match against SGR parameters, which may be separated by ';'
|
||||
--- @type string?, string?
|
||||
match, sgr = sgr:match('^(%d*);?(.*)')
|
||||
add_attr_hl(match + 0) -- coerce to number
|
||||
end
|
||||
@ -187,55 +176,40 @@ local function highlight_line(line, linenr)
|
||||
end
|
||||
end
|
||||
|
||||
for _, hl in ipairs(hls) do
|
||||
if hl.attr ~= NONE then
|
||||
buf_hls[#buf_hls + 1] = {
|
||||
0,
|
||||
-1,
|
||||
hl_groups[hl.attr],
|
||||
linenr - 1,
|
||||
hl.start,
|
||||
hl.final,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(chars, '')
|
||||
end
|
||||
|
||||
local HlGroups = {
|
||||
[Attrs.Bold] = 'manBold',
|
||||
[Attrs.Underline] = 'manUnderline',
|
||||
[Attrs.Italic] = 'manItalic',
|
||||
}
|
||||
|
||||
local function highlight_man_page()
|
||||
local mod = vim.bo.modifiable
|
||||
vim.bo.modifiable = true
|
||||
|
||||
local lines = api.nvim_buf_get_lines(0, 0, -1, false)
|
||||
|
||||
--- @type {attr:Man.Attribute,row:integer,start:integer,final:integer}[]
|
||||
local hls = {}
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
lines[i] = highlight_line(line, i)
|
||||
lines[i] = render_line(line, i - 1, hls)
|
||||
end
|
||||
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, lines)
|
||||
|
||||
for _, args in ipairs(buf_hls) do
|
||||
api.nvim_buf_add_highlight(unpack(args))
|
||||
for _, hl in ipairs(hls) do
|
||||
api.nvim_buf_add_highlight(0, -1, HlGroups[hl.attr], hl.row, hl.start, hl.final)
|
||||
end
|
||||
buf_hls = {}
|
||||
|
||||
vim.bo.modifiable = mod
|
||||
end
|
||||
|
||||
-- replace spaces in a man page name with underscores
|
||||
-- intended for PostgreSQL, which has man pages like 'CREATE_TABLE(7)';
|
||||
-- while editing SQL source code, it's nice to visually select 'CREATE TABLE'
|
||||
-- and hit 'K', which requires this transformation
|
||||
---@param str string
|
||||
---@return string
|
||||
local function spaces_to_underscores(str)
|
||||
local res = str:gsub('%s', '_')
|
||||
return res
|
||||
end
|
||||
|
||||
---@param sect string|nil
|
||||
---@param name string|nil
|
||||
---@param silent boolean
|
||||
local function get_path(sect, name, silent)
|
||||
--- @param name? string
|
||||
--- @param sect? string
|
||||
local function get_path(name, sect)
|
||||
name = name or ''
|
||||
sect = sect or ''
|
||||
-- Some man implementations (OpenBSD) return all available paths from the
|
||||
@ -258,12 +232,12 @@ local function get_path(sect, name, silent)
|
||||
-- inconsistently supported. Instead, call -w with a section and a name.
|
||||
local cmd --- @type string[]
|
||||
if sect == '' then
|
||||
cmd = { 'man', FIND_ARG, name }
|
||||
cmd = { 'man', '-w', name }
|
||||
else
|
||||
cmd = { 'man', FIND_ARG, sect, name }
|
||||
cmd = { 'man', '-w', sect, name }
|
||||
end
|
||||
|
||||
local lines = system(cmd, silent)
|
||||
local lines = system(cmd, true)
|
||||
local results = vim.split(lines, '\n', { trimempty = true })
|
||||
|
||||
if #results == 0 then
|
||||
@ -282,7 +256,7 @@ local function get_path(sect, name, silent)
|
||||
--- @param v string
|
||||
local namematches = vim.tbl_filter(function(v)
|
||||
local tail = fn.fnamemodify(v, ':t')
|
||||
return string.find(tail, name, 1, true)
|
||||
return tail:find(name, 1, true) ~= nil
|
||||
end, results) or {}
|
||||
local sectmatches = {}
|
||||
|
||||
@ -293,73 +267,59 @@ local function get_path(sect, name, silent)
|
||||
end, namematches)
|
||||
end
|
||||
|
||||
return fn.substitute(sectmatches[1] or namematches[1] or results[1], [[\n\+$]], '', '')
|
||||
return (sectmatches[1] or namematches[1] or results[1]):gsub('\n+$', '')
|
||||
end
|
||||
|
||||
---@param text string
|
||||
---@param pat_or_re string
|
||||
local function matchstr(text, pat_or_re)
|
||||
local re = type(pat_or_re) == 'string' and vim.regex(pat_or_re) or pat_or_re
|
||||
|
||||
---@type integer, integer
|
||||
local s, e = re:match_str(text)
|
||||
|
||||
if s == nil then
|
||||
return
|
||||
end
|
||||
|
||||
return text:sub(vim.str_utfindex(text, 'utf-32', s) + 1, vim.str_utfindex(text, 'utf-32', e))
|
||||
end
|
||||
|
||||
-- attempt to extract the name and sect out of 'name(sect)'
|
||||
-- otherwise just return the largest string of valid characters in ref
|
||||
--- Attempt to extract the name and sect out of 'name(sect)'
|
||||
--- otherwise just return the largest string of valid characters in ref
|
||||
--- @param ref string
|
||||
---@return string, string
|
||||
local function extract_sect_and_name_ref(ref)
|
||||
ref = ref or ''
|
||||
if ref:sub(1, 1) == '-' then -- try ':Man -pandoc' with this disabled.
|
||||
man_error("manpage name cannot start with '-'")
|
||||
--- @return string? name
|
||||
--- @return string? sect
|
||||
--- @return string? err
|
||||
local function parse_ref(ref)
|
||||
if ref == '' or ref:sub(1, 1) == '-' then
|
||||
return nil, nil, ('invalid manpage reference "%s"'):format(ref)
|
||||
end
|
||||
local ref1 = ref:match('[^()]+%([^()]+%)')
|
||||
if not ref1 then
|
||||
local name = ref:match('[^()]+')
|
||||
if not name then
|
||||
man_error('manpage reference cannot contain only parentheses: ' .. ref)
|
||||
end
|
||||
return '', name
|
||||
end
|
||||
local parts = vim.split(ref1, '(', { plain = true })
|
||||
|
||||
-- match "<name>(<sect>)"
|
||||
-- note: name can contain spaces
|
||||
local name, sect = ref:match('([^()]+)%(([^()]+)%)')
|
||||
if name then
|
||||
-- see ':Man 3X curses' on why tolower.
|
||||
-- TODO(nhooyr) Not sure if this is portable across OSs
|
||||
-- but I have not seen a single uppercase section.
|
||||
local sect = vim.split(parts[2] or '', ')', { plain = true })[1]:lower()
|
||||
local name = parts[1]
|
||||
return sect, name
|
||||
return name, sect:lower()
|
||||
end
|
||||
|
||||
-- find_path attempts to find the path to a manpage
|
||||
-- based on the passed section and name.
|
||||
--
|
||||
-- 1. If manpage could not be found with the given sect and name,
|
||||
-- then try all the sections in b:man_default_sects.
|
||||
-- 2. If it still could not be found, then we try again without a section.
|
||||
-- 3. If still not found but $MANSECT is set, then we try again with $MANSECT
|
||||
-- unset.
|
||||
-- 4. If a path still wasn't found, return nil.
|
||||
name = ref:match('[^()]+')
|
||||
if not name then
|
||||
return nil, nil, ('invalid manpage reference "%s"'):format(ref)
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
--- Attempts to find the path to a manpage based on the passed section and name.
|
||||
---
|
||||
--- 1. If manpage could not be found with the given sect and name,
|
||||
--- then try all the sections in b:man_default_sects.
|
||||
--- 2. If it still could not be found, then we try again without a section.
|
||||
--- 3. If still not found but $MANSECT is set, then we try again with $MANSECT
|
||||
--- unset.
|
||||
--- 4. If a path still wasn't found, return nil.
|
||||
--- @param name string?
|
||||
--- @param sect string?
|
||||
---@param name string
|
||||
function M.find_path(sect, name)
|
||||
--- @return string? path
|
||||
function M._find_path(name, sect)
|
||||
if sect and sect ~= '' then
|
||||
local ret = get_path(sect, name, true)
|
||||
local ret = get_path(name, sect)
|
||||
if ret then
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
if vim.b.man_default_sects ~= nil then
|
||||
local sects = vim.split(vim.b.man_default_sects, ',', { plain = true, trimempty = true })
|
||||
for _, sec in ipairs(sects) do
|
||||
local ret = get_path(sec, name, true)
|
||||
for sec in vim.gsplit(vim.b.man_default_sects, ',', { trimempty = true }) do
|
||||
local ret = get_path(name, sec)
|
||||
if ret then
|
||||
return ret
|
||||
end
|
||||
@ -367,17 +327,18 @@ function M.find_path(sect, name)
|
||||
end
|
||||
|
||||
-- if none of the above worked, we will try with no section
|
||||
local res_empty_sect = get_path('', name, true)
|
||||
if res_empty_sect then
|
||||
return res_empty_sect
|
||||
local ret = get_path(name)
|
||||
if ret then
|
||||
return ret
|
||||
end
|
||||
|
||||
-- if that still didn't work, we will check for $MANSECT and try again with it
|
||||
-- unset
|
||||
if vim.env.MANSECT then
|
||||
--- @type string
|
||||
local mansect = vim.env.MANSECT
|
||||
vim.env.MANSECT = nil
|
||||
local res = get_path('', name, true)
|
||||
local res = get_path(name)
|
||||
vim.env.MANSECT = mansect
|
||||
if res then
|
||||
return res
|
||||
@ -388,21 +349,24 @@ function M.find_path(sect, name)
|
||||
return nil
|
||||
end
|
||||
|
||||
local EXT_RE = vim.regex([[\.\%([glx]z\|bz2\|lzma\|Z\)$]])
|
||||
|
||||
-- Extracts the name/section from the 'path/name.sect', because sometimes the actual section is
|
||||
-- more specific than what we provided to `man` (try `:Man 3 App::CLI`).
|
||||
-- Also on linux, name seems to be case-insensitive. So for `:Man PRIntf`, we
|
||||
-- still want the name of the buffer to be 'printf'.
|
||||
--- Extracts the name/section from the 'path/name.sect', because sometimes the
|
||||
--- actual section is more specific than what we provided to `man`
|
||||
--- (try `:Man 3 App::CLI`). Also on linux, name seems to be case-insensitive.
|
||||
--- So for `:Man PRIntf`, we still want the name of the buffer to be 'printf'.
|
||||
--- @param path string
|
||||
---@return string, string
|
||||
local function extract_sect_and_name_path(path)
|
||||
--- @return string name
|
||||
--- @return string sect
|
||||
local function parse_path(path)
|
||||
local tail = fn.fnamemodify(path, ':t')
|
||||
if EXT_RE:match_str(path) then -- valid extensions
|
||||
if
|
||||
path:match('%.[glx]z$')
|
||||
or path:match('%.bz2$')
|
||||
or path:match('%.lzma$')
|
||||
or path:match('%.Z$')
|
||||
then
|
||||
tail = fn.fnamemodify(tail, ':r')
|
||||
end
|
||||
local name, sect = tail:match('^(.+)%.([^.]+)$')
|
||||
return sect, name
|
||||
return tail:match('^(.+)%.([^.]+)$')
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
@ -433,6 +397,10 @@ local function set_options()
|
||||
vim.bo.filetype = 'man'
|
||||
end
|
||||
|
||||
--- Always use -l if possible. #6683
|
||||
--- @type boolean?
|
||||
local localfile_arg
|
||||
|
||||
--- @param path string
|
||||
--- @param silent boolean?
|
||||
--- @return string
|
||||
@ -444,11 +412,17 @@ local function get_page(path, silent)
|
||||
if (vim.g.man_hardwrap or 1) ~= 1 then
|
||||
manwidth = 999
|
||||
elseif vim.env.MANWIDTH then
|
||||
manwidth = vim.env.MANWIDTH
|
||||
manwidth = vim.env.MANWIDTH --- @type string|integer
|
||||
else
|
||||
manwidth = api.nvim_win_get_width(0) - vim.o.wrapmargin
|
||||
end
|
||||
|
||||
if localfile_arg == nil then
|
||||
local mpath = get_path('man')
|
||||
-- Check for -l support.
|
||||
localfile_arg = (mpath and system({ 'man', '-l', mpath }, true) or '') ~= ''
|
||||
end
|
||||
|
||||
local cmd = localfile_arg and { 'man', '-l', path } or { 'man', path }
|
||||
|
||||
-- Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).
|
||||
@ -461,47 +435,17 @@ local function get_page(path, silent)
|
||||
})
|
||||
end
|
||||
|
||||
---@param lnum integer
|
||||
---@return string
|
||||
local function getline(lnum)
|
||||
---@diagnostic disable-next-line
|
||||
return fn.getline(lnum)
|
||||
end
|
||||
|
||||
---@param page string
|
||||
local function put_page(page)
|
||||
vim.bo.modifiable = true
|
||||
vim.bo.readonly = false
|
||||
vim.bo.swapfile = false
|
||||
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, vim.split(page, '\n'))
|
||||
|
||||
while getline(1):match('^%s*$') do
|
||||
api.nvim_buf_set_lines(0, 0, 1, false, {})
|
||||
end
|
||||
-- XXX: nroff justifies text by filling it with whitespace. That interacts
|
||||
-- badly with our use of $MANWIDTH=999. Hack around this by using a fixed
|
||||
-- size for those whitespace regions.
|
||||
-- Use try/catch to avoid setting v:errmsg.
|
||||
vim.cmd([[
|
||||
try
|
||||
keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g
|
||||
catch
|
||||
endtry
|
||||
]])
|
||||
vim.cmd('1') -- Move cursor to first line
|
||||
highlight_man_page()
|
||||
set_options()
|
||||
end
|
||||
|
||||
--- @param path string
|
||||
--- @param psect string
|
||||
local function format_candidate(path, psect)
|
||||
if matchstr(path, [[\.\%(pdf\|in\)$]]) then -- invalid extensions
|
||||
if vim.endswith(path, '.pdf') or vim.endswith(path, '.in') then
|
||||
-- invalid extensions
|
||||
return ''
|
||||
end
|
||||
local sect, name = extract_sect_and_name_path(path)
|
||||
local name, sect = parse_path(path)
|
||||
if sect == psect then
|
||||
return name
|
||||
elseif sect and name and matchstr(sect, psect .. '.\\+$') then -- invalid extensions
|
||||
elseif sect:match(psect .. '.+$') then -- invalid extensions
|
||||
-- We include the section if the user provided section is a prefix
|
||||
-- of the actual section.
|
||||
return ('%s(%s)'):format(name, sect)
|
||||
@ -509,63 +453,54 @@ local function format_candidate(path, psect)
|
||||
return ''
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@param list T[]
|
||||
---@param elem T
|
||||
---@return T[]
|
||||
local function move_elem_to_head(list, elem)
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
local list1 = vim.tbl_filter(function(v)
|
||||
return v ~= elem
|
||||
end, list)
|
||||
return { elem, unpack(list1) }
|
||||
end
|
||||
|
||||
---@param sect string
|
||||
--- @param name string
|
||||
---@return string[]
|
||||
local function get_paths(sect, name)
|
||||
--- @param sect? string
|
||||
--- @return string[] paths
|
||||
--- @return string? err
|
||||
local function get_paths(name, sect)
|
||||
-- Try several sources for getting the list man directories:
|
||||
-- 1. `man -w` (works on most systems)
|
||||
-- 2. `manpath`
|
||||
-- 1. `manpath -q`
|
||||
-- 2. `man -w` (works on most systems)
|
||||
-- 3. $MANPATH
|
||||
local mandirs_raw = vim.F.npcall(system, { 'man', FIND_ARG })
|
||||
or vim.F.npcall(system, { 'manpath', '-q' })
|
||||
--
|
||||
-- Note we prefer `manpath -q` because `man -w`:
|
||||
-- - does not work on MacOS 14 and later.
|
||||
-- - only returns '/usr/bin/man' on MacOS 13 and earlier.
|
||||
--- @type string?
|
||||
local mandirs_raw = vim.F.npcall(system, { 'manpath', '-q' })
|
||||
or vim.F.npcall(system, { 'man', '-w' })
|
||||
or vim.env.MANPATH
|
||||
|
||||
if not mandirs_raw then
|
||||
man_error("Could not determine man directories from: 'man -w', 'manpath' or $MANPATH")
|
||||
return {}, "Could not determine man directories from: 'man -w', 'manpath' or $MANPATH"
|
||||
end
|
||||
|
||||
local mandirs = table.concat(vim.split(mandirs_raw, '[:\n]', { trimempty = true }), ',')
|
||||
|
||||
sect = sect or ''
|
||||
|
||||
--- @type string[]
|
||||
local paths = fn.globpath(mandirs, 'man[^\\/]*/' .. name .. '*.' .. sect .. '*', false, true)
|
||||
|
||||
-- Prioritize the result from find_path as it obeys b:man_default_sects.
|
||||
local first = M.find_path(sect, name)
|
||||
local first = M._find_path(name, sect)
|
||||
if first then
|
||||
paths = move_elem_to_head(paths, first)
|
||||
--- @param v string
|
||||
paths = vim.tbl_filter(function(v)
|
||||
return v ~= first
|
||||
end, paths)
|
||||
table.insert(paths, 1, first)
|
||||
end
|
||||
|
||||
return paths
|
||||
end
|
||||
|
||||
---@param sect string
|
||||
---@param psect string
|
||||
---@param name string
|
||||
---@return string[]
|
||||
local function complete(sect, psect, name)
|
||||
local pages = get_paths(sect, name)
|
||||
-- We remove duplicates in case the same manpage in different languages was found.
|
||||
return fn.uniq(fn.sort(vim.tbl_map(function(v)
|
||||
return format_candidate(v, psect)
|
||||
end, pages) or {}, 'i'))
|
||||
end
|
||||
|
||||
-- see extract_sect_and_name_ref on why tolower(sect)
|
||||
--- @param arg_lead string
|
||||
--- @param cmd_line string
|
||||
function M.man_complete(arg_lead, cmd_line, _)
|
||||
--- @return string? sect
|
||||
--- @return string? psect
|
||||
--- @return string? name
|
||||
local function parse_cmdline(arg_lead, cmd_line)
|
||||
local args = vim.split(cmd_line, '%s+', { trimempty = true })
|
||||
local cmd_offset = fn.index(args, 'Man')
|
||||
if cmd_offset > 0 then
|
||||
@ -575,13 +510,13 @@ function M.man_complete(arg_lead, cmd_line, _)
|
||||
end
|
||||
|
||||
if #args > 3 then
|
||||
return {}
|
||||
return
|
||||
end
|
||||
|
||||
if #args == 1 then
|
||||
-- returning full completion is laggy. Require some arg_lead to complete
|
||||
-- return complete('', '', '')
|
||||
return {}
|
||||
-- return '', '', ''
|
||||
return
|
||||
end
|
||||
|
||||
if arg_lead:match('^[^()]+%([^()]*$') then
|
||||
@ -590,14 +525,15 @@ function M.man_complete(arg_lead, cmd_line, _)
|
||||
-- It will offer 'priclass.d(1m)' even though section is specified as 1.
|
||||
local tmp = vim.split(arg_lead, '(', { plain = true })
|
||||
local name = tmp[1]
|
||||
-- See extract_sect_and_name_ref on why :lower()
|
||||
local sect = (tmp[2] or ''):lower()
|
||||
return complete(sect, '', name)
|
||||
return sect, '', name
|
||||
end
|
||||
|
||||
if not args[2]:match('^[^()]+$') then
|
||||
-- cursor (|) is at ':Man 3() |' or ':Man (3|' or ':Man 3() pri|'
|
||||
-- or ':Man 3() pri |'
|
||||
return {}
|
||||
return
|
||||
end
|
||||
|
||||
if #args == 2 then
|
||||
@ -617,52 +553,77 @@ function M.man_complete(arg_lead, cmd_line, _)
|
||||
name = arg_lead
|
||||
sect = ''
|
||||
end
|
||||
return complete(sect, sect, name)
|
||||
return sect, sect, name
|
||||
end
|
||||
|
||||
if not arg_lead:match('[^()]+$') then
|
||||
-- cursor (|) is at ':Man 3 printf |' or ':Man 3 (pr)i|'
|
||||
return {}
|
||||
return
|
||||
end
|
||||
|
||||
-- cursor (|) is at ':Man 3 pri|'
|
||||
local name = arg_lead
|
||||
local sect = args[2]:lower()
|
||||
return complete(sect, sect, name)
|
||||
local name, sect = arg_lead, args[2]:lower()
|
||||
return sect, sect, name
|
||||
end
|
||||
|
||||
--- @param arg_lead string
|
||||
--- @param cmd_line string
|
||||
function M.man_complete(arg_lead, cmd_line)
|
||||
local sect, psect, name = parse_cmdline(arg_lead, cmd_line)
|
||||
if not (sect and psect and name) then
|
||||
return {}
|
||||
end
|
||||
|
||||
local pages = get_paths(name, sect)
|
||||
|
||||
-- We check for duplicates in case the same manpage in different languages
|
||||
-- was found.
|
||||
local pages_fmt = {} --- @type string[]
|
||||
local pages_fmt_keys = {} --- @type table<string,true>
|
||||
for _, v in ipairs(pages) do
|
||||
local x = format_candidate(v, psect)
|
||||
local xl = x:lower() -- ignore case when searching avoiding duplicates
|
||||
if not pages_fmt_keys[xl] then
|
||||
pages_fmt[#pages_fmt + 1] = x
|
||||
pages_fmt_keys[xl] = true
|
||||
end
|
||||
end
|
||||
table.sort(pages_fmt)
|
||||
|
||||
return pages_fmt
|
||||
end
|
||||
|
||||
--- @param pattern string
|
||||
--- @return {name:string,filename:string,cmd:string}[]
|
||||
function M.goto_tag(pattern, _, _)
|
||||
local sect, name = extract_sect_and_name_ref(pattern)
|
||||
local name, sect, err = parse_ref(pattern)
|
||||
if err then
|
||||
error(err)
|
||||
end
|
||||
|
||||
local paths = get_paths(sect, name)
|
||||
---@type {name:string,title:string}[]
|
||||
local structured = {}
|
||||
local paths, err2 = get_paths(assert(name), sect)
|
||||
if err2 then
|
||||
error(err2)
|
||||
end
|
||||
|
||||
--- @type table[]
|
||||
local ret = {}
|
||||
|
||||
for _, path in ipairs(paths) do
|
||||
sect, name = extract_sect_and_name_path(path)
|
||||
if sect and name then
|
||||
structured[#structured + 1] = {
|
||||
name = name,
|
||||
title = name .. '(' .. sect .. ')',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
---@param entry {name:string,title:string}
|
||||
return vim.tbl_map(function(entry)
|
||||
return {
|
||||
name = entry.name,
|
||||
filename = 'man://' .. entry.title,
|
||||
local pname, psect = parse_path(path)
|
||||
ret[#ret + 1] = {
|
||||
name = pname,
|
||||
filename = ('man://%s(%s)'):format(pname, psect),
|
||||
cmd = '1',
|
||||
}
|
||||
end, structured)
|
||||
end
|
||||
|
||||
-- Called when Nvim is invoked as $MANPAGER.
|
||||
return ret
|
||||
end
|
||||
|
||||
--- Called when Nvim is invoked as $MANPAGER.
|
||||
function M.init_pager()
|
||||
if getline(1):match('^%s*$') then
|
||||
if fn.getline(1):match('^%s*$') then
|
||||
api.nvim_buf_set_lines(0, 0, 1, false, {})
|
||||
else
|
||||
vim.cmd('keepjumps 1')
|
||||
@ -670,9 +631,10 @@ function M.init_pager()
|
||||
highlight_man_page()
|
||||
-- Guess the ref from the heading (which is usually uppercase, so we cannot
|
||||
-- know the correct casing, cf. `man glDrawArraysInstanced`).
|
||||
local ref = fn.substitute(matchstr(getline(1), [[^[^)]\+)]]) or '', ' ', '_', 'g')
|
||||
local ok, res = pcall(extract_sect_and_name_ref, ref)
|
||||
vim.b.man_sect = ok and res or ''
|
||||
--- @type string
|
||||
local ref = (fn.getline(1):match('^[^)]+%)') or ''):gsub(' ', '_')
|
||||
local _, sect, err = pcall(parse_ref, ref)
|
||||
vim.b.man_sect = err ~= nil and sect or ''
|
||||
|
||||
if not fn.bufname('%'):match('man://') then -- Avoid duplicate buffers, E95.
|
||||
vim.cmd.file({ 'man://' .. fn.fnameescape(ref):lower(), mods = { silent = true } })
|
||||
@ -681,21 +643,14 @@ function M.init_pager()
|
||||
set_options()
|
||||
end
|
||||
|
||||
---@param count integer
|
||||
--- Combine the name and sect into a manpage reference so that all
|
||||
--- verification/extraction can be kept in a single function.
|
||||
--- @param args string[]
|
||||
function M.open_page(count, smods, args)
|
||||
local ref ---@type string
|
||||
if #args == 0 then
|
||||
ref = vim.bo.filetype == 'man' and fn.expand('<cWORD>') or fn.expand('<cword>')
|
||||
if ref == '' then
|
||||
man_error('no identifier under cursor')
|
||||
end
|
||||
elseif #args == 1 then
|
||||
ref = args[1]
|
||||
else
|
||||
-- Combine the name and sect into a manpage reference so that all
|
||||
-- verification/extraction can be kept in a single function.
|
||||
if args[1]:match('^%d$') or args[1]:match('^%d%a') or args[1]:match('^%a$') then
|
||||
--- @return string? ref
|
||||
local function ref_from_args(args)
|
||||
if #args <= 1 then
|
||||
return args[1]
|
||||
elseif args[1]:match('^%d$') or args[1]:match('^%d%a') or args[1]:match('^%a$') then
|
||||
-- NB: Valid sections are not only digits, but also:
|
||||
-- - <digit><word> (see POSIX mans),
|
||||
-- - and even <letter> and <word> (see, for example, by tcl/tk)
|
||||
@ -704,27 +659,48 @@ function M.open_page(count, smods, args)
|
||||
local sect = args[1]
|
||||
table.remove(args, 1)
|
||||
local name = table.concat(args, ' ')
|
||||
ref = ('%s(%s)'):format(name, sect)
|
||||
else
|
||||
ref = table.concat(args, ' ')
|
||||
return ('%s(%s)'):format(name, sect)
|
||||
end
|
||||
|
||||
return table.concat(args, ' ')
|
||||
end
|
||||
|
||||
--- @param count integer
|
||||
--- @param args string[]
|
||||
--- @return string? err
|
||||
function M.open_page(count, smods, args)
|
||||
local ref = ref_from_args(args)
|
||||
if not ref then
|
||||
ref = vim.bo.filetype == 'man' and fn.expand('<cWORD>') or fn.expand('<cword>')
|
||||
if ref == '' then
|
||||
return 'no identifier under cursor'
|
||||
end
|
||||
end
|
||||
|
||||
local sect, name = extract_sect_and_name_ref(ref)
|
||||
local name, sect, err = parse_ref(ref)
|
||||
if err then
|
||||
return err
|
||||
end
|
||||
assert(name)
|
||||
|
||||
if count >= 0 then
|
||||
sect = tostring(count)
|
||||
end
|
||||
|
||||
-- Try both spaces and underscores, use the first that exists.
|
||||
local path = M.find_path(sect, name)
|
||||
if path == nil then
|
||||
path = M.find_path(sect, spaces_to_underscores(name))
|
||||
if path == nil then
|
||||
man_error('no manual entry for ' .. name)
|
||||
local path = M._find_path(name, sect)
|
||||
if not path then
|
||||
--- Replace spaces in a man page name with underscores
|
||||
--- intended for PostgreSQL, which has man pages like 'CREATE_TABLE(7)';
|
||||
--- while editing SQL source code, it's nice to visually select 'CREATE TABLE'
|
||||
--- and hit 'K', which requires this transformation
|
||||
path = M._find_path(name:gsub('%s', '_'), sect)
|
||||
if not path then
|
||||
return 'no manual entry for ' .. name
|
||||
end
|
||||
end
|
||||
|
||||
sect, name = extract_sect_and_name_path(path)
|
||||
name, sect = parse_path(path)
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local save_tfu = vim.bo[buf].tagfunc
|
||||
vim.bo[buf].tagfunc = "v:lua.require'man'.goto_tag"
|
||||
@ -747,24 +723,51 @@ function M.open_page(count, smods, args)
|
||||
|
||||
if not ok then
|
||||
error(ret)
|
||||
else
|
||||
end
|
||||
set_options()
|
||||
end
|
||||
|
||||
vim.b.man_sect = sect
|
||||
end
|
||||
|
||||
-- Called when a man:// buffer is opened.
|
||||
--- Called when a man:// buffer is opened.
|
||||
--- @return string? err
|
||||
function M.read_page(ref)
|
||||
local sect, name = extract_sect_and_name_ref(ref)
|
||||
local path = M.find_path(sect, name)
|
||||
if path == nil then
|
||||
man_error('no manual entry for ' .. name)
|
||||
local name, sect, err = parse_ref(ref)
|
||||
if err then
|
||||
return err
|
||||
end
|
||||
sect = extract_sect_and_name_path(path)
|
||||
|
||||
local path = M._find_path(name, sect)
|
||||
if not path then
|
||||
return 'no manual entry for ' .. name
|
||||
end
|
||||
|
||||
local _, sect1 = parse_path(path)
|
||||
local page = get_page(path)
|
||||
vim.b.man_sect = sect
|
||||
put_page(page)
|
||||
|
||||
vim.b.man_sect = sect1
|
||||
vim.bo.modifiable = true
|
||||
vim.bo.readonly = false
|
||||
vim.bo.swapfile = false
|
||||
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, vim.split(page, '\n'))
|
||||
|
||||
while fn.getline(1):match('^%s*$') do
|
||||
api.nvim_buf_set_lines(0, 0, 1, false, {})
|
||||
end
|
||||
-- XXX: nroff justifies text by filling it with whitespace. That interacts
|
||||
-- badly with our use of $MANWIDTH=999. Hack around this by using a fixed
|
||||
-- size for those whitespace regions.
|
||||
-- Use try/catch to avoid setting v:errmsg.
|
||||
vim.cmd([[
|
||||
try
|
||||
keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g
|
||||
catch
|
||||
endtry
|
||||
]])
|
||||
vim.cmd('1') -- Move cursor to first line
|
||||
highlight_man_page()
|
||||
set_options()
|
||||
end
|
||||
|
||||
function M.show_toc()
|
||||
@ -781,24 +784,13 @@ function M.show_toc()
|
||||
|
||||
local lnum = 2
|
||||
local last_line = fn.line('$') - 1
|
||||
local section_title_re = vim.regex([[^\%( \{3\}\)\=\S.*$]])
|
||||
local flag_title_re = vim.regex([[^\s\+\%(+\|-\)\S\+]])
|
||||
while lnum and lnum < last_line do
|
||||
local text = getline(lnum)
|
||||
if section_title_re:match_str(text) then
|
||||
-- if text is a section title
|
||||
local text = fn.getline(lnum)
|
||||
if text:match('^%s+[-+]%S') or text:match('^ %S') or text:match('^%S') then
|
||||
toc[#toc + 1] = {
|
||||
bufnr = bufnr,
|
||||
lnum = lnum,
|
||||
text = text,
|
||||
}
|
||||
elseif flag_title_re:match_str(text) then
|
||||
-- if text is a flag title. we strip whitespaces and prepend two
|
||||
-- spaces to have a consistent format in the loclist.
|
||||
toc[#toc + 1] = {
|
||||
bufnr = bufnr,
|
||||
lnum = lnum,
|
||||
text = ' ' .. fn.substitute(text, [[^\s*\(.\{-}\)\s*$]], [[\1]], ''),
|
||||
text = text:gsub('^%s+', ''):gsub('%s+$', ''),
|
||||
}
|
||||
end
|
||||
lnum = fn.nextnonblank(lnum + 1)
|
||||
@ -810,19 +802,4 @@ function M.show_toc()
|
||||
vim.w.qf_toc = bufname
|
||||
end
|
||||
|
||||
local function init()
|
||||
local path = get_path('', 'man', true)
|
||||
local page ---@type string?
|
||||
if path ~= nil then
|
||||
-- Check for -l support.
|
||||
page = get_page(path, true)
|
||||
end
|
||||
|
||||
if page == '' or page == nil then
|
||||
localfile_arg = false
|
||||
end
|
||||
end
|
||||
|
||||
init()
|
||||
|
||||
return M
|
||||
|
6
runtime/lua/vim/_meta/options.lua
generated
6
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
|
||||
|
@ -211,7 +211,7 @@ local function reuse_client_default(client, config)
|
||||
|
||||
for _, config_folder in ipairs(config_folders) do
|
||||
local found = false
|
||||
for _, client_folder in ipairs(client.workspace_folders) do
|
||||
for _, client_folder in ipairs(client.workspace_folders or {}) do
|
||||
if config_folder.uri == client_folder.uri then
|
||||
found = true
|
||||
break
|
||||
|
@ -174,6 +174,10 @@ local validate = vim.validate
|
||||
--- capabilities.
|
||||
--- @field server_capabilities lsp.ServerCapabilities?
|
||||
---
|
||||
--- Response from the server sent on `initialize` describing information about
|
||||
--- the server.
|
||||
--- @field server_info lsp.ServerInfo?
|
||||
---
|
||||
--- A ring buffer (|vim.ringbuf()|) containing progress messages
|
||||
--- sent by the server.
|
||||
--- @field progress vim.lsp.Client.Progress
|
||||
@ -556,6 +560,8 @@ function Client:initialize()
|
||||
self.offset_encoding = self.server_capabilities.positionEncoding
|
||||
end
|
||||
|
||||
self.server_info = result.serverInfo
|
||||
|
||||
if next(self.settings) then
|
||||
self:notify(ms.workspace_didChangeConfiguration, { settings = self.settings })
|
||||
end
|
||||
|
@ -40,6 +40,8 @@ local function check_active_clients()
|
||||
local clients = vim.lsp.get_clients()
|
||||
if next(clients) then
|
||||
for _, client in pairs(clients) do
|
||||
local server_version = vim.tbl_get(client, 'server_info', 'version')
|
||||
or '? (no serverInfo.version response)'
|
||||
local cmd ---@type string
|
||||
local ccmd = client.config.cmd
|
||||
if type(ccmd) == 'table' then
|
||||
@ -62,6 +64,7 @@ local function check_active_clients()
|
||||
end
|
||||
report_info(table.concat({
|
||||
string.format('%s (id: %d)', client.name, client.id),
|
||||
string.format('- Version: %s', server_version),
|
||||
dirs_info,
|
||||
string.format('- Command: %s', cmd),
|
||||
string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
|
||||
|
@ -8,9 +8,9 @@ vim.api.nvim_create_user_command('Man', function(params)
|
||||
if params.bang then
|
||||
man.init_pager()
|
||||
else
|
||||
local ok, err = pcall(man.open_page, params.count, params.smods, params.fargs)
|
||||
if not ok then
|
||||
vim.notify(man.errormsg or err, vim.log.levels.ERROR)
|
||||
local err = man.open_page(params.count, params.smods, params.fargs)
|
||||
if err then
|
||||
vim.notify('man.lua: ' .. err, vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
end, {
|
||||
@ -31,6 +31,9 @@ vim.api.nvim_create_autocmd('BufReadCmd', {
|
||||
pattern = 'man://*',
|
||||
nested = true,
|
||||
callback = function(params)
|
||||
require('man').read_page(vim.fn.matchstr(params.match, 'man://\\zs.*'))
|
||||
local err = require('man').read_page(assert(params.match:match('man://(.*)')))
|
||||
if err then
|
||||
vim.notify('man.lua: ' .. err, vim.log.levels.ERROR)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -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
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nvim/mbyte.h"
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/ops.h"
|
||||
#include "nvim/optionstr.h"
|
||||
#include "nvim/pos_defs.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/strings.h"
|
||||
@ -317,7 +318,6 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena
|
||||
char *cmdline = NULL;
|
||||
char *cmdname = NULL;
|
||||
ArrayOf(String) args = ARRAY_DICT_INIT;
|
||||
|
||||
String retv = (String)STRING_INIT;
|
||||
|
||||
#define OBJ_TO_BOOL(var, value, default, varname) \
|
||||
@ -633,6 +633,24 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena
|
||||
build_cmdline_str(&cmdline, &ea, &cmdinfo, args);
|
||||
ea.cmdlinep = &cmdline;
|
||||
|
||||
// set when Not Implemented
|
||||
const int ni = is_cmd_ni(ea.cmdidx);
|
||||
|
||||
// Check for "++opt=val" argument.
|
||||
if (ea.argt & EX_ARGOPT) {
|
||||
while (ea.arg[0] == '+' && ea.arg[1] == '+') {
|
||||
if (getargopt(&ea) == FAIL && !ni) {
|
||||
api_set_error(err, kErrorTypeValidation, "Invalid argument");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for "+command" argument.
|
||||
if ((ea.argt & EX_CMDARG) && !ea.usefilter) {
|
||||
ea.do_ecmd_cmd = getargcmd(&ea.arg);
|
||||
}
|
||||
|
||||
garray_T capture_local;
|
||||
const int save_msg_silent = msg_silent;
|
||||
garray_T * const save_capture_ga = capture_ga;
|
||||
|
@ -229,10 +229,9 @@ static Object _call_function(String fn, Array args, dict_T *self, Arena *arena,
|
||||
funcexe.fe_selfdict = self;
|
||||
|
||||
TRY_WRAP(err, {
|
||||
// call_func() retval is deceptive, ignore it. Instead we set `msg_list`
|
||||
// (see above) to capture abort-causing non-exception errors.
|
||||
call_func(fn.data, (int)fn.size, &rettv, (int)args.size,
|
||||
vim_args, &funcexe);
|
||||
// call_func() retval is deceptive, ignore it. Instead TRY_WRAP sets `msg_list` to capture
|
||||
// abort-causing non-exception errors.
|
||||
(void)call_func(fn.data, (int)fn.size, &rettv, (int)args.size, vim_args, &funcexe);
|
||||
});
|
||||
|
||||
if (!ERROR_SET(err)) {
|
||||
@ -280,18 +279,23 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Arena *arena,
|
||||
typval_T rettv;
|
||||
bool mustfree = false;
|
||||
switch (dict.type) {
|
||||
case kObjectTypeString:
|
||||
case kObjectTypeString: {
|
||||
int eval_ret;
|
||||
TRY_WRAP(err, {
|
||||
eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE);
|
||||
eval_ret = eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE);
|
||||
clear_evalarg(&EVALARG_EVALUATE, NULL);
|
||||
});
|
||||
if (ERROR_SET(err)) {
|
||||
return rv;
|
||||
}
|
||||
if (eval_ret != OK) {
|
||||
abort(); // Should not happen.
|
||||
}
|
||||
// Evaluation of the string arg created a new dict or increased the
|
||||
// refcount of a dict. Not necessary for a RPC dict.
|
||||
mustfree = true;
|
||||
break;
|
||||
}
|
||||
case kObjectTypeDict:
|
||||
object_to_vim(dict, &rettv, err);
|
||||
break;
|
||||
|
@ -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"
|
||||
@ -934,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;
|
||||
|
||||
@ -953,7 +955,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
bool area_highlighting = false; // Visual or incsearch highlighting in this line
|
||||
int vi_attr = 0; // attributes for Visual and incsearch highlighting
|
||||
int area_attr = 0; // attributes desired by highlighting
|
||||
int search_attr = 0; // attributes desired by 'hlsearch'
|
||||
int search_attr = 0; // attributes desired by 'hlsearch' or ComplMatchIns
|
||||
int vcol_save_attr = 0; // saved attr for 'cursorcolumn'
|
||||
int decor_attr = 0; // attributes desired by syntax and extmarks
|
||||
bool has_syntax = false; // this buffer has syntax highl.
|
||||
@ -967,7 +969,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
int spell_attr = 0; // attributes desired by spelling
|
||||
int word_end = 0; // last byte with same spell_attr
|
||||
int cur_checked_col = 0; // checked column for current line
|
||||
bool extra_check = 0; // has syntax or linebreak
|
||||
bool extra_check = false; // has extra highlighting
|
||||
int multi_attr = 0; // attributes desired by multibyte
|
||||
int mb_l = 1; // multi-byte byte length
|
||||
int mb_c = 0; // decoded multi-byte character
|
||||
@ -1117,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;
|
||||
}
|
||||
@ -1493,6 +1495,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
ptr = line + v; // "line" may have been updated
|
||||
}
|
||||
|
||||
if ((State & MODE_INSERT) && in_curline && ins_compl_active()) {
|
||||
area_highlighting = true;
|
||||
}
|
||||
|
||||
win_line_start(wp, &wlv);
|
||||
bool draw_cols = true;
|
||||
int leftcols_width = 0;
|
||||
@ -1629,8 +1635,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);
|
||||
@ -1739,6 +1744,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
if (*ptr == NUL) {
|
||||
has_match_conc = 0;
|
||||
}
|
||||
|
||||
// Check if ComplMatchIns highlight is needed.
|
||||
if ((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) {
|
||||
search_attr = hl_combine_attr(search_attr, ins_match_attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wlv.diff_hlf != (hlf_T)0) {
|
||||
@ -2446,8 +2459,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) {
|
||||
@ -2640,7 +2652,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;
|
||||
|
@ -4135,7 +4135,7 @@ void separate_nextcmd(exarg_T *eap)
|
||||
}
|
||||
|
||||
/// get + command from ex argument
|
||||
static char *getargcmd(char **argp)
|
||||
char *getargcmd(char **argp)
|
||||
{
|
||||
char *arg = *argp;
|
||||
char *command = NULL;
|
||||
@ -4210,7 +4210,7 @@ static char *get_bad_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
||||
/// Get "++opt=arg" argument.
|
||||
///
|
||||
/// @return FAIL or OK.
|
||||
static int getargopt(exarg_T *eap)
|
||||
int getargopt(exarg_T *eap)
|
||||
{
|
||||
char *arg = eap->arg + 2;
|
||||
int *pp = NULL;
|
||||
|
@ -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 NONE",
|
||||
"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)
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/// 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
|
||||
@ -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)
|
||||
{
|
||||
@ -1678,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);
|
||||
@ -1802,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) {
|
||||
@ -2121,6 +2147,8 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
|
||||
&& pum_visible()) {
|
||||
word = xstrdup(compl_shown_match->cp_str);
|
||||
retval = true;
|
||||
// May need to remove ComplMatchIns highlight.
|
||||
redrawWinline(curwin, curwin->w_cursor.lnum);
|
||||
}
|
||||
|
||||
// CTRL-E means completion is Ended, go back to the typed text.
|
||||
@ -2137,7 +2165,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();
|
||||
@ -3622,6 +3650,7 @@ void ins_compl_delete(bool new_leader)
|
||||
return;
|
||||
}
|
||||
backspace_until_column(col);
|
||||
compl_ins_end_col = curwin->w_cursor.col;
|
||||
}
|
||||
|
||||
// TODO(vim): is this sufficient for redrawing? Redrawing everything
|
||||
@ -3639,7 +3668,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);
|
||||
|
||||
@ -3888,14 +3917,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();
|
||||
|
@ -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.
|
||||
|
@ -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,25 @@ bool terminal_enter(void)
|
||||
curwin->w_p_so = 0;
|
||||
curwin->w_p_siso = 0;
|
||||
|
||||
// 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();
|
||||
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 +671,9 @@ bool terminal_enter(void)
|
||||
RedrawingDisabled = s->save_rd;
|
||||
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
|
||||
|
||||
// Restore the terminal cursor to what is set in 'guicursor'
|
||||
(void)parse_shape_opt(SHAPE_CURSOR);
|
||||
|
||||
if (save_curwin == curwin->handle) { // Else: window was closed.
|
||||
curwin->w_p_cul = save_w_p_cul;
|
||||
if (save_w_p_culopt) {
|
||||
@ -649,8 +688,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 +699,11 @@ bool terminal_enter(void)
|
||||
} else {
|
||||
unshowmode(true);
|
||||
}
|
||||
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 +854,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 +914,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 +1120,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 +1134,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 +1166,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 +1194,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 +1240,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 +1929,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 +1990,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);
|
||||
}
|
||||
|
||||
|
@ -3785,7 +3785,7 @@ describe('API', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{1:~}{102: }{4: }{1: }|
|
||||
{1:~}{4:^ }{1: }|
|
||||
{1:~}{4: }{1: }|*4
|
||||
{1:~ }|*3
|
||||
{5:-- TERMINAL --} |
|
||||
@ -3801,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 --} |
|
||||
@ -5388,4 +5388,156 @@ describe('API', function()
|
||||
api.nvim__redraw({ win = 0, range = { 0, -1 } })
|
||||
n.assert_alive()
|
||||
end)
|
||||
|
||||
describe('nvim_cmd with plus #flags', function()
|
||||
it('handles +flags correctly', function()
|
||||
-- Write a file for testing +flags
|
||||
command(':call writefile(["Line 1", "Line 2", "Line 3"], "testfile")')
|
||||
|
||||
-- Test + command (go to the last line)
|
||||
local result = exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit + testfile', {}))
|
||||
return vim.fn.line('.')
|
||||
]])
|
||||
eq(3, result)
|
||||
|
||||
-- Test +{num} command (go to line number)
|
||||
result = exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit +1 testfile', {}))
|
||||
return vim.fn.line('.')
|
||||
]])
|
||||
eq(1, result)
|
||||
|
||||
-- Test +/{pattern} command (go to line with pattern)
|
||||
result = exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit +/Line\\ 2 testfile', {}))
|
||||
return vim.fn.line('.')
|
||||
]])
|
||||
eq(2, result)
|
||||
|
||||
-- Test +{command} command (execute a command after opening the file)
|
||||
result = exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit +set\\ nomodifiable testfile', {}))
|
||||
return vim.bo.modifiable
|
||||
]])
|
||||
eq(false, result)
|
||||
|
||||
-- Clean up
|
||||
os.remove('testfile')
|
||||
end)
|
||||
|
||||
it('handles various ++ flags correctly', function()
|
||||
-- Test ++ff flag
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++ff=mac test_ff_mac.txt', {}))
|
||||
]]
|
||||
eq('mac', api.nvim_get_option_value('fileformat', {}))
|
||||
eq('test_ff_mac.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++fileformat=unix test_ff_unix.txt', {}))
|
||||
]]
|
||||
eq('unix', api.nvim_get_option_value('fileformat', {}))
|
||||
eq('test_ff_unix.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
|
||||
-- Test ++enc flag
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++enc=utf-32 test_enc.txt', {}))
|
||||
]]
|
||||
eq('ucs-4', api.nvim_get_option_value('fileencoding', {}))
|
||||
eq('test_enc.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
|
||||
-- Test ++bin and ++nobin flags
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++bin test_bin.txt', {}))
|
||||
]]
|
||||
eq(true, api.nvim_get_option_value('binary', {}))
|
||||
eq('test_bin.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++nobin test_nobin.txt', {}))
|
||||
]]
|
||||
eq(false, api.nvim_get_option_value('binary', {}))
|
||||
eq('test_nobin.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
|
||||
-- Test multiple flags together
|
||||
exec_lua [[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit ++ff=mac ++enc=utf-32 ++bin test_multi.txt', {}))
|
||||
]]
|
||||
eq(true, api.nvim_get_option_value('binary', {}))
|
||||
eq('mac', api.nvim_get_option_value('fileformat', {}))
|
||||
eq('ucs-4', api.nvim_get_option_value('fileencoding', {}))
|
||||
eq('test_multi.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||
end)
|
||||
|
||||
it('handles invalid and incorrect ++ flags gracefully', function()
|
||||
-- Test invalid ++ff flag
|
||||
local result = exec_lua [[
|
||||
local cmd = vim.api.nvim_parse_cmd('edit ++ff=invalid test_invalid_ff.txt', {})
|
||||
local _, err = pcall(vim.cmd, cmd)
|
||||
return err
|
||||
]]
|
||||
eq('Invalid argument', result)
|
||||
|
||||
-- Test incorrect ++ syntax
|
||||
result = exec_lua [[
|
||||
local cmd = vim.api.nvim_parse_cmd('edit ++unknown=test_unknown.txt', {})
|
||||
local _, err = pcall(vim.cmd, cmd)
|
||||
return err
|
||||
]]
|
||||
eq('Invalid argument', result)
|
||||
|
||||
-- Test invalid ++bin flag
|
||||
result = exec_lua [[
|
||||
local cmd = vim.api.nvim_parse_cmd('edit ++binabc test_invalid_bin.txt', {})
|
||||
local _, err = pcall(vim.cmd, cmd)
|
||||
return err
|
||||
]]
|
||||
eq('Invalid argument', result)
|
||||
end)
|
||||
|
||||
it('handles ++p for creating parent directory', function()
|
||||
exec_lua [[
|
||||
vim.cmd('edit flags_dir/test_create.txt')
|
||||
vim.cmd(vim.api.nvim_parse_cmd('write! ++p', {}))
|
||||
]]
|
||||
eq(true, fn.isdirectory('flags_dir') == 1)
|
||||
fn.delete('flags_dir', 'rf')
|
||||
end)
|
||||
|
||||
it('tests editing files with bad utf8 sequences', function()
|
||||
-- Write a file with bad utf8 sequences
|
||||
local file = io.open('Xfile', 'wb')
|
||||
file:write('[\255][\192][\226\137\240][\194\194]')
|
||||
file:close()
|
||||
|
||||
exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 Xfile', {}))
|
||||
]])
|
||||
eq('[?][?][???][??]', api.nvim_get_current_line())
|
||||
|
||||
exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=_ Xfile', {}))
|
||||
]])
|
||||
eq('[_][_][___][__]', api.nvim_get_current_line())
|
||||
|
||||
exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=drop Xfile', {}))
|
||||
]])
|
||||
eq('[][][][]', api.nvim_get_current_line())
|
||||
|
||||
exec_lua([[
|
||||
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=keep Xfile', {}))
|
||||
]])
|
||||
eq('[\255][\192][\226\137\240][\194\194]', api.nvim_get_current_line())
|
||||
|
||||
local result = exec_lua([[
|
||||
local _, err = pcall(vim.cmd, vim.api.nvim_parse_cmd('edit ++enc=utf8 ++bad=foo Xfile', {}))
|
||||
return err
|
||||
]])
|
||||
eq('Invalid argument', result)
|
||||
-- Clean up
|
||||
os.remove('Xfile')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
@ -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')
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
|
@ -1854,6 +1854,20 @@ describe('LSP', function()
|
||||
end,
|
||||
}
|
||||
end)
|
||||
|
||||
it('vim.lsp.start when existing client has no workspace_folders', function()
|
||||
exec_lua(create_server_definition)
|
||||
eq(
|
||||
{ 2, 'foo', 'foo' },
|
||||
exec_lua(function()
|
||||
local server = _G._create_server()
|
||||
vim.lsp.start { cmd = server.cmd, name = 'foo' }
|
||||
vim.lsp.start { cmd = server.cmd, name = 'foo', root_dir = 'bar' }
|
||||
local foos = vim.lsp.get_clients()
|
||||
return { #foos, foos[1].name, foos[2].name }
|
||||
end)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('parsing tests', function()
|
||||
|
@ -21,13 +21,12 @@ local function get_search_history(name)
|
||||
local man = require('man')
|
||||
local res = {}
|
||||
--- @diagnostic disable-next-line:duplicate-set-field
|
||||
man.find_path = function(sect, name0)
|
||||
man._find_path = function(name0, sect)
|
||||
table.insert(res, { sect, name0 })
|
||||
return nil
|
||||
end
|
||||
local ok, rv = pcall(man.open_page, -1, { tab = 0 }, args)
|
||||
assert(not ok)
|
||||
assert(rv and rv:match('no manual entry'))
|
||||
local err = man.open_page(-1, { tab = 0 }, args)
|
||||
assert(err and err:match('no manual entry'))
|
||||
return res
|
||||
end)
|
||||
end
|
||||
@ -225,7 +224,7 @@ describe(':Man', function()
|
||||
matches('^/.+', actual_file)
|
||||
local args = { nvim_prog, '--headless', '+:Man ' .. actual_file, '+q' }
|
||||
matches(
|
||||
('Error detected while processing command line:\r\n' .. 'man.lua: "no manual entry for %s"'):format(
|
||||
('Error detected while processing command line:\r\n' .. 'man.lua: no manual entry for %s'):format(
|
||||
pesc(actual_file)
|
||||
),
|
||||
fn.system(args, { '' })
|
||||
@ -235,8 +234,8 @@ describe(':Man', function()
|
||||
|
||||
it('tries variants with spaces, underscores #22503', function()
|
||||
eq({
|
||||
{ '', 'NAME WITH SPACES' },
|
||||
{ '', 'NAME_WITH_SPACES' },
|
||||
{ vim.NIL, 'NAME WITH SPACES' },
|
||||
{ vim.NIL, 'NAME_WITH_SPACES' },
|
||||
}, get_search_history('NAME WITH SPACES'))
|
||||
eq({
|
||||
{ '3', 'some other man' },
|
||||
@ -255,8 +254,8 @@ describe(':Man', function()
|
||||
{ 'n', 'some_other_man' },
|
||||
}, get_search_history('n some other man'))
|
||||
eq({
|
||||
{ '', '123some other man' },
|
||||
{ '', '123some_other_man' },
|
||||
{ vim.NIL, '123some other man' },
|
||||
{ vim.NIL, '123some_other_man' },
|
||||
}, get_search_history('123some other man'))
|
||||
eq({
|
||||
{ '1', 'other_man' },
|
||||
@ -265,11 +264,10 @@ describe(':Man', function()
|
||||
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
|
||||
return #require('man').man_complete('f', 'Man f') > 0
|
||||
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
|
||||
@ -16,16 +15,27 @@ local skip = t.skip
|
||||
describe(':terminal cursor', function()
|
||||
local screen
|
||||
|
||||
local terminal_mode_idx ---@type number
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
screen = tt.setup_screen()
|
||||
|
||||
if terminal_mode_idx == nil then
|
||||
for i, v in ipairs(screen._mode_info) do
|
||||
if v.name == 'terminal' then
|
||||
terminal_mode_idx = i
|
||||
end
|
||||
end
|
||||
assert(terminal_mode_idx)
|
||||
end
|
||||
end)
|
||||
|
||||
it('moves the screen cursor when focused', function()
|
||||
tt.feed_data('testing cursor')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
testing cursor{1: } |
|
||||
testing cursor^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
@ -35,7 +45,7 @@ describe(':terminal cursor', function()
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
end)
|
||||
@ -49,7 +59,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 +71,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 +82,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 +92,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,59 +103,251 @@ 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([[
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
show_cursor()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
|*5
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('cursor with customized highlighting', function()
|
||||
local screen
|
||||
|
||||
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 },
|
||||
]],
|
||||
unchanged = true,
|
||||
})
|
||||
show_cursor()
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]],
|
||||
unchanged = true,
|
||||
})
|
||||
command('call termopen(["' .. testprg('tty-test') .. '"])')
|
||||
feed('i')
|
||||
poke_eventloop()
|
||||
end)
|
||||
|
||||
it('overrides the default highlighting', function()
|
||||
it('becomes visible when exiting Terminal mode', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
hide_cursor()
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{1: } |
|
||||
|*4
|
||||
|*5
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<c-\\><c-n>')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
{2:^ } |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
|*5
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
it('can be modified by application #3681', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
|
||||
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[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
else
|
||||
eq(0, screen._mode_info[terminal_mode_idx].blinkon)
|
||||
eq(0, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
end
|
||||
eq(v.shape, screen._mode_info[terminal_mode_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[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('block', screen._mode_info[terminal_mode_idx].cursor_shape)
|
||||
end)
|
||||
|
||||
it('can be modified per terminal', function()
|
||||
skip(is_os('win'), '#31587')
|
||||
|
||||
-- Set cursor to vertical bar with blink
|
||||
tt.feed_csi('5 q')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
^ |
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[terminal_mode_idx].cursor_shape)
|
||||
end,
|
||||
})
|
||||
|
||||
tt.hide_cursor()
|
||||
screen:expect({
|
||||
grid = [[
|
||||
tty ready |
|
||||
|
|
||||
|*4
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
condition = function()
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[terminal_mode_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[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('block', screen._mode_info[terminal_mode_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[terminal_mode_idx].blinkon)
|
||||
eq(0, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('horizontal', screen._mode_info[terminal_mode_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[terminal_mode_idx].blinkon)
|
||||
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
|
||||
eq('vertical', screen._mode_info[terminal_mode_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)
|
||||
|
||||
it('preserves guicursor value on TermLeave #31612', function()
|
||||
eq(3, screen._mode_info[terminal_mode_idx].hl_id)
|
||||
|
||||
-- Change 'guicursor' while terminal mode is active
|
||||
command('set guicursor+=t:Error')
|
||||
|
||||
local error_hl_id = call('hlID', 'Error')
|
||||
|
||||
screen:expect({
|
||||
condition = function()
|
||||
eq(error_hl_id, screen._mode_info[terminal_mode_idx].hl_id)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Exit terminal mode
|
||||
feed([[<C-\><C-N>]])
|
||||
|
||||
screen:expect([[
|
||||
tty ready |
|
||||
^ |
|
||||
|*5
|
||||
]])
|
||||
|
||||
eq(error_hl_id, screen._mode_info[terminal_mode_idx].hl_id)
|
||||
end)
|
||||
end)
|
||||
|
||||
@ -171,19 +373,13 @@ describe('buffer cursor position is correct in terminal without number column',
|
||||
}, {
|
||||
cols = 70,
|
||||
})
|
||||
screen:set_default_attr_ids({
|
||||
[1] = { foreground = 253, background = 11 },
|
||||
[2] = { reverse = true },
|
||||
[3] = { bold = true },
|
||||
[4] = { background = 11 },
|
||||
})
|
||||
-- Also check for real cursor position, as it is used for stuff like input methods
|
||||
screen._handle_busy_start = function() end
|
||||
screen._handle_busy_stop = function() end
|
||||
screen:expect([[
|
||||
|*4
|
||||
Entering Ex mode. Type "visual" to go to Normal mode. |
|
||||
:{2:^ } |
|
||||
:^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]])
|
||||
end
|
||||
@ -200,7 +396,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 +404,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 +415,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 +423,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 +434,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 +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. |
|
||||
:^a{4:a}aaaaaa |
|
||||
:^aaaaaaaa |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -263,7 +459,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 +467,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 +478,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 +486,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 +497,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 +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. |
|
||||
:^µ{4:µ}µµµµµµ |
|
||||
:^µµµµµµµµ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -326,7 +522,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 +530,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 +542,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 +550,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 +562,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 +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. |
|
||||
:^µ̳{4:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
:^µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳ |
|
||||
|
|
||||
]])
|
||||
eq({ 6, 1 }, eval('nvim_win_get_cursor(0)'))
|
||||
@ -391,7 +587,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 +595,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 +606,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 +614,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 +625,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 +633,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 +646,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 +655,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)'))
|
||||
@ -488,13 +684,6 @@ describe('buffer cursor position is correct in terminal with number column', fun
|
||||
}, {
|
||||
cols = 70,
|
||||
})
|
||||
screen:set_default_attr_ids({
|
||||
[1] = { foreground = 253, background = 11 },
|
||||
[2] = { reverse = true },
|
||||
[3] = { bold = true },
|
||||
[4] = { background = 11 },
|
||||
[7] = { foreground = 130 },
|
||||
})
|
||||
-- Also check for real cursor position, as it is used for stuff like input methods
|
||||
screen._handle_busy_start = function() end
|
||||
screen._handle_busy_stop = function() end
|
||||
@ -504,7 +693,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 +716,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 +727,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 +741,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 +752,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 +766,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 +777,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 +797,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 +808,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 +822,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 +833,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 +847,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 +858,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 +878,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 +889,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 +904,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 +915,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 +930,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 +941,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 +961,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 +972,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 +986,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 +997,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 +1011,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 +1022,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 +1038,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 +1050,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: } |
|
||||
{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: } |
|
||||
{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: }|
|
||||
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)
|
||||
|
@ -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: }|
|
||||
]])
|
||||
|
@ -49,7 +49,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { '\ntest\n[O]k: ', 6, 11 } },
|
||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
||||
kind = 'confirm',
|
||||
},
|
||||
},
|
||||
@ -77,7 +77,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { '\ntest\n[O]k: ', 6, 11 } },
|
||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
||||
kind = 'confirm',
|
||||
},
|
||||
},
|
||||
@ -91,7 +91,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { '\ntest\n[O]k: ', 6, 11 } },
|
||||
content = { { '\ntest\n[O]k: ', 6, 10 } },
|
||||
kind = 'confirm',
|
||||
},
|
||||
{
|
||||
@ -99,7 +99,7 @@ describe('ui/ext_messages', function()
|
||||
kind = 'echo',
|
||||
},
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -116,7 +116,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'replace with X (y/n/a/q/l/^E/^Y)?', 6, 19 } },
|
||||
content = { { 'replace with X (y/n/a/q/l/^E/^Y)?', 6, 18 } },
|
||||
kind = 'confirm_sub',
|
||||
},
|
||||
},
|
||||
@ -135,7 +135,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'W10: Warning: Changing a readonly file', 19, 27 } },
|
||||
content = { { 'W10: Warning: Changing a readonly file', 19, 26 } },
|
||||
kind = 'wmsg',
|
||||
},
|
||||
},
|
||||
@ -151,7 +151,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'search hit BOTTOM, continuing at TOP', 19, 27 } },
|
||||
content = { { 'search hit BOTTOM, continuing at TOP', 19, 26 } },
|
||||
kind = 'wmsg',
|
||||
},
|
||||
},
|
||||
@ -167,15 +167,15 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Error detected while processing :', 9, 7 } },
|
||||
content = { { 'Error detected while processing :', 9, 6 } },
|
||||
kind = 'emsg',
|
||||
},
|
||||
{
|
||||
content = { { 'E605: Exception not caught: foo', 9, 7 } },
|
||||
content = { { 'E605: Exception not caught: foo', 9, 6 } },
|
||||
kind = 'emsg',
|
||||
},
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -225,15 +225,15 @@ describe('ui/ext_messages', function()
|
||||
{
|
||||
content = {
|
||||
{ '\nErrorMsg ' },
|
||||
{ 'xxx', 9, 7 },
|
||||
{ 'xxx', 9, 6 },
|
||||
{ ' ' },
|
||||
{ 'ctermfg=', 18, 6 },
|
||||
{ 'ctermfg=', 18, 5 },
|
||||
{ '15 ' },
|
||||
{ 'ctermbg=', 18, 6 },
|
||||
{ 'ctermbg=', 18, 5 },
|
||||
{ '1 ' },
|
||||
{ 'guifg=', 18, 6 },
|
||||
{ 'guifg=', 18, 5 },
|
||||
{ 'White ' },
|
||||
{ 'guibg=', 18, 6 },
|
||||
{ 'guibg=', 18, 5 },
|
||||
{ 'Red' },
|
||||
},
|
||||
kind = 'list_cmd',
|
||||
@ -280,7 +280,7 @@ describe('ui/ext_messages', function()
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { {
|
||||
content = { { 'raa', 9, 7 } },
|
||||
content = { { 'raa', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
} },
|
||||
}
|
||||
@ -307,15 +307,15 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'bork', 9, 7 } },
|
||||
content = { { 'bork', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
{
|
||||
content = { { 'fail', 9, 7 } },
|
||||
content = { { 'fail', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -329,19 +329,19 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'bork', 9, 7 } },
|
||||
content = { { 'bork', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
{
|
||||
content = { { 'fail', 9, 7 } },
|
||||
content = { { 'fail', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
{
|
||||
content = { { 'extrafail', 9, 7 } },
|
||||
content = { { 'extrafail', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -363,7 +363,7 @@ describe('ui/ext_messages', function()
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { {
|
||||
content = { { 'problem', 9, 7 } },
|
||||
content = { { 'problem', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
} },
|
||||
cmdline = {
|
||||
@ -391,15 +391,15 @@ describe('ui/ext_messages', function()
|
||||
{1:~ }|*4
|
||||
]],
|
||||
msg_history = {
|
||||
{ kind = 'echoerr', content = { { 'raa', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'bork', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'fail', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'extrafail', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'problem', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'raa', 9, 6 } } },
|
||||
{ kind = 'echoerr', content = { { 'bork', 9, 6 } } },
|
||||
{ kind = 'echoerr', content = { { 'fail', 9, 6 } } },
|
||||
{ kind = 'echoerr', content = { { 'extrafail', 9, 6 } } },
|
||||
{ kind = 'echoerr', content = { { 'problem', 9, 6 } } },
|
||||
},
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -424,7 +424,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'bork\nfail', 9, 7 } },
|
||||
content = { { 'bork\nfail', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
},
|
||||
@ -438,13 +438,13 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
msg_history = {
|
||||
{
|
||||
content = { { 'bork\nfail', 9, 7 } },
|
||||
content = { { 'bork\nfail', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
},
|
||||
},
|
||||
@ -492,7 +492,7 @@ describe('ui/ext_messages', function()
|
||||
{ content = { { 'x #1' } }, kind = 'list_cmd' },
|
||||
{ content = { { 'y #2' } }, kind = 'list_cmd' },
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -507,7 +507,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { '-- INSERT --', 5, 12 } },
|
||||
showmode = { { '-- INSERT --', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('alphpabet<cr>alphanum<cr>')
|
||||
@ -518,7 +518,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*2
|
||||
]],
|
||||
showmode = { { '-- INSERT --', 5, 12 } },
|
||||
showmode = { { '-- INSERT --', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('<c-x>')
|
||||
@ -529,7 +529,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*2
|
||||
]],
|
||||
showmode = { { '-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)', 5, 12 } },
|
||||
showmode = { { '-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('<c-p>')
|
||||
@ -545,7 +545,7 @@ describe('ui/ext_messages', function()
|
||||
items = { { 'alphpabet', '', '', '' }, { 'alphanum', '', '', '' } },
|
||||
pos = 1,
|
||||
},
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 12 }, { 'match 1 of 2', 6, 19 } },
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 11 }, { 'match 1 of 2', 6, 18 } },
|
||||
}
|
||||
|
||||
-- echomsg and showmode don't overwrite each other, this is the same
|
||||
@ -567,7 +567,7 @@ describe('ui/ext_messages', function()
|
||||
content = { { 'stuff' } },
|
||||
kind = 'echomsg',
|
||||
} },
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 12 }, { 'match 1 of 2', 6, 19 } },
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 11 }, { 'match 1 of 2', 6, 18 } },
|
||||
}
|
||||
|
||||
feed('<c-p>')
|
||||
@ -587,7 +587,7 @@ describe('ui/ext_messages', function()
|
||||
content = { { 'stuff' } },
|
||||
kind = 'echomsg',
|
||||
} },
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 12 }, { 'match 2 of 2', 6, 19 } },
|
||||
showmode = { { '-- Keyword Local completion (^N^P) ', 5, 11 }, { 'match 2 of 2', 6, 18 } },
|
||||
}
|
||||
|
||||
feed('<esc>:messages<cr>')
|
||||
@ -604,7 +604,7 @@ describe('ui/ext_messages', function()
|
||||
} },
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -618,7 +618,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { 'recording @q', 5, 12 } },
|
||||
showmode = { { 'recording @q', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('i')
|
||||
@ -627,7 +627,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { '-- INSERT --recording @q', 5, 12 } },
|
||||
showmode = { { '-- INSERT --recording @q', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('<esc>')
|
||||
@ -636,7 +636,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { 'recording @q', 5, 12 } },
|
||||
showmode = { { 'recording @q', 5, 11 } },
|
||||
}
|
||||
|
||||
feed('q')
|
||||
@ -655,7 +655,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { 'recording @q', 5, 12 } },
|
||||
showmode = { { 'recording @q', 5, 11 } },
|
||||
mode = 'normal',
|
||||
}
|
||||
|
||||
@ -665,7 +665,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { 'recording @q', 5, 12 } },
|
||||
showmode = { { 'recording @q', 5, 11 } },
|
||||
mode = 'insert',
|
||||
}
|
||||
|
||||
@ -675,7 +675,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { 'recording @q', 5, 12 } },
|
||||
showmode = { { 'recording @q', 5, 11 } },
|
||||
mode = 'normal',
|
||||
}
|
||||
|
||||
@ -697,7 +697,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
ruler = { { '0,0-1 All', 9, 62 } },
|
||||
ruler = { { '0,0-1 All', 9, 61 } },
|
||||
})
|
||||
command('hi clear MsgArea')
|
||||
feed('i')
|
||||
@ -706,7 +706,7 @@ describe('ui/ext_messages', function()
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
showmode = { { '-- INSERT --', 5, 12 } },
|
||||
showmode = { { '-- INSERT --', 5, 11 } },
|
||||
ruler = { { '0,1 All' } },
|
||||
}
|
||||
feed('abcde<cr>12345<esc>')
|
||||
@ -744,7 +744,7 @@ describe('ui/ext_messages', function()
|
||||
{17:123}45 |
|
||||
{1:~ }|*3
|
||||
]],
|
||||
showmode = { { '-- VISUAL BLOCK --', 5, 12 } },
|
||||
showmode = { { '-- VISUAL BLOCK --', 5, 11 } },
|
||||
showcmd = { { '2x3' } },
|
||||
ruler = { { '1,3 All' } },
|
||||
})
|
||||
@ -825,7 +825,7 @@ describe('ui/ext_messages', function()
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { {
|
||||
content = { { 'bork', 9, 7 } },
|
||||
content = { { 'bork', 9, 6 } },
|
||||
kind = 'echoerr',
|
||||
} },
|
||||
}
|
||||
@ -850,7 +850,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'E117: Unknown function: nosuchfunction', 9, 7 } },
|
||||
content = { { 'E117: Unknown function: nosuchfunction', 9, 6 } },
|
||||
kind = 'emsg',
|
||||
},
|
||||
},
|
||||
@ -865,12 +865,12 @@ describe('ui/ext_messages', function()
|
||||
msg_history = {
|
||||
{ kind = 'echomsg', content = { { 'howdy' } } },
|
||||
{ kind = '', content = { { 'Type :qa and press <Enter> to exit Nvim' } } },
|
||||
{ kind = 'echoerr', content = { { 'bork', 9, 7 } } },
|
||||
{ kind = 'emsg', content = { { 'E117: Unknown function: nosuchfunction', 9, 7 } } },
|
||||
{ kind = 'echoerr', content = { { 'bork', 9, 6 } } },
|
||||
{ kind = 'emsg', content = { { 'E117: Unknown function: nosuchfunction', 9, 6 } } },
|
||||
},
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
@ -943,7 +943,7 @@ stack traceback:
|
||||
[C]: in function 'error'
|
||||
[string ":lua"]:1: in main chunk]],
|
||||
9,
|
||||
7,
|
||||
6,
|
||||
},
|
||||
},
|
||||
kind = 'lua_error',
|
||||
@ -963,7 +963,7 @@ stack traceback:
|
||||
messages = {
|
||||
{
|
||||
content = {
|
||||
{ "Error invoking 'test_method' on channel 1:\ncomplete\nerror\n\nmessage", 9, 7 },
|
||||
{ "Error invoking 'test_method' on channel 1:\ncomplete\nerror\n\nmessage", 9, 6 },
|
||||
},
|
||||
kind = 'rpc_error',
|
||||
},
|
||||
@ -1092,7 +1092,7 @@ stack traceback:
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'wow, ', 10, 9 }, { 'such\n\nvery ', 9, 7 }, { 'color', 8, 13 } },
|
||||
content = { { 'wow, ', 10, 8 }, { 'such\n\nvery ', 9, 6 }, { 'color', 8, 12 } },
|
||||
kind = 'echomsg',
|
||||
},
|
||||
},
|
||||
@ -1117,13 +1117,13 @@ stack traceback:
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
msg_history = {
|
||||
{
|
||||
content = { { 'wow, ', 10, 9 }, { 'such\n\nvery ', 9, 7 }, { 'color', 8, 13 } },
|
||||
content = { { 'wow, ', 10, 8 }, { 'such\n\nvery ', 9, 6 }, { 'color', 8, 12 } },
|
||||
kind = 'echomsg',
|
||||
},
|
||||
},
|
||||
@ -1783,7 +1783,7 @@ describe('ui/ext_messages', function()
|
||||
{1:~ }type :help iccf{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*5
|
||||
]]
|
||||
local showmode = { { '-- INSERT --', 5, 12 } }
|
||||
local showmode = { { '-- INSERT --', 5, 11 } }
|
||||
screen:expect(introscreen)
|
||||
|
||||
-- <c-l> (same as :mode) does _not_ clear intro message
|
||||
@ -1858,7 +1858,7 @@ describe('ui/ext_messages', function()
|
||||
]],
|
||||
messages = {
|
||||
{
|
||||
content = { { 'Press ENTER or type command to continue', 6, 19 } },
|
||||
content = { { 'Press ENTER or type command to continue', 6, 18 } },
|
||||
kind = 'return_prompt',
|
||||
},
|
||||
},
|
||||
|
@ -94,6 +94,46 @@ describe('ui mode_change event', function()
|
||||
}
|
||||
end)
|
||||
|
||||
-- oldtest: Test_mouse_shape_indent_norm_with_gq()
|
||||
it('is restored to Normal mode after "gq" indents using :normal #12309', function()
|
||||
screen:try_resize(60, 6)
|
||||
n.exec([[
|
||||
func Indent()
|
||||
exe "normal! \<Ignore>"
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
setlocal indentexpr=Indent()
|
||||
call setline(1, [repeat('a', 80), repeat('b', 80)])
|
||||
]])
|
||||
|
||||
feed('ggVG')
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{17:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
|
||||
{17:aaaaaaaaaaaaaaaaaaaa} |
|
||||
^b{17:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}|
|
||||
{17:bbbbbbbbbbbbbbbbbbbb} |
|
||||
{1:~ }|
|
||||
{5:-- VISUAL LINE --} |
|
||||
]],
|
||||
mode = 'visual',
|
||||
}
|
||||
|
||||
feed('gq')
|
||||
screen:expect {
|
||||
grid = [[
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aaaaaaaaaaaaaaaaaaaa |
|
||||
^bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|
|
||||
bbbbbbbbbbbbbbbbbbbb |
|
||||
{1:~ }|
|
||||
|
|
||||
]],
|
||||
mode = 'normal',
|
||||
}
|
||||
end)
|
||||
|
||||
it('works in insert mode', function()
|
||||
feed('i')
|
||||
screen:expect {
|
||||
|
@ -34,7 +34,7 @@ describe('shell command :!', function()
|
||||
n.nvim_set .. ' notermguicolors',
|
||||
})
|
||||
screen:expect([[
|
||||
{1: } |
|
||||
^ |
|
||||
{4:~ }|*4
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
@ -78,7 +78,7 @@ describe('shell command :!', function()
|
||||
29999: foo |
|
||||
30000: foo |
|
||||
|
|
||||
{10:Press ENTER or type command to continue}{1: } |
|
||||
{10:Press ENTER or type command to continue}^ |
|
||||
{3:-- TERMINAL --} |
|
||||
]],
|
||||
{
|
||||
|
@ -1162,6 +1162,8 @@ describe('builtin popupmenu', function()
|
||||
[6] = { foreground = Screen.colors.White, background = Screen.colors.Red },
|
||||
[7] = { background = Screen.colors.Yellow }, -- Search
|
||||
[8] = { foreground = Screen.colors.Red },
|
||||
[9] = { foreground = Screen.colors.Yellow, background = Screen.colors.Green },
|
||||
[10] = { foreground = Screen.colors.White, background = Screen.colors.Green },
|
||||
ks = { foreground = Screen.colors.Red, background = Screen.colors.Grey },
|
||||
kn = { foreground = Screen.colors.Red, background = Screen.colors.Plum1 },
|
||||
xs = { foreground = Screen.colors.Black, background = Screen.colors.Grey },
|
||||
@ -5561,6 +5563,179 @@ describe('builtin popupmenu', function()
|
||||
]])
|
||||
feed('<C-E><ESC>')
|
||||
end)
|
||||
|
||||
-- oldtest: Test_pum_matchins_highlight()
|
||||
it('with ComplMatchIns highlight', function()
|
||||
exec([[
|
||||
func Omni_test(findstart, base)
|
||||
if a:findstart
|
||||
return col(".")
|
||||
endif
|
||||
return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
|
||||
endfunc
|
||||
set omnifunc=Omni_test
|
||||
hi ComplMatchIns guifg=red
|
||||
]])
|
||||
|
||||
feed('Sαβγ <C-X><C-O>')
|
||||
screen:expect([[
|
||||
αβγ {8:foo}^ |
|
||||
{1:~ }{s: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 1 of 3} |
|
||||
]])
|
||||
feed('<C-E><Esc>')
|
||||
|
||||
feed('Sαβγ <C-X><C-O><C-N>')
|
||||
screen:expect([[
|
||||
αβγ {8:bar}^ |
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{s: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 2 of 3} |
|
||||
]])
|
||||
feed('<C-E><Esc>')
|
||||
|
||||
feed('Sαβγ <C-X><C-O><C-N><C-N>')
|
||||
screen:expect([[
|
||||
αβγ {8:你好}^ |
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{s: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 3 of 3} |
|
||||
]])
|
||||
feed('<C-E><Esc>')
|
||||
|
||||
-- restore after accept
|
||||
feed('Sαβγ <C-X><C-O><C-Y>')
|
||||
screen:expect([[
|
||||
αβγ foo^ |
|
||||
{1:~ }|*18
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
|
||||
-- restore after cancel completion
|
||||
feed('Sαβγ <C-X><C-O><Space>')
|
||||
screen:expect([[
|
||||
αβγ foo ^ |
|
||||
{1:~ }|*18
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
|
||||
-- text after the inserted text shouldn't be highlighted
|
||||
feed('0ea <C-X><C-O>')
|
||||
screen:expect([[
|
||||
αβγ {8:foo}^ foo |
|
||||
{1:~ }{s: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 1 of 3} |
|
||||
]])
|
||||
feed('<C-P>')
|
||||
screen:expect([[
|
||||
αβγ ^ foo |
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{8:Back at original} |
|
||||
]])
|
||||
feed('<C-P>')
|
||||
screen:expect([[
|
||||
αβγ {8:你好}^ foo |
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{s: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 3 of 3} |
|
||||
]])
|
||||
feed('<C-Y>')
|
||||
screen:expect([[
|
||||
αβγ 你好^ foo |
|
||||
{1:~ }|*18
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
end)
|
||||
|
||||
-- oldtest: Test_pum_matchins_highlight_combine()
|
||||
it('with ComplMatchIns, Normal and CursorLine highlights', function()
|
||||
exec([[
|
||||
func Omni_test(findstart, base)
|
||||
if a:findstart
|
||||
return col(".")
|
||||
endif
|
||||
return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
|
||||
endfunc
|
||||
set omnifunc=Omni_test
|
||||
hi Normal guibg=blue
|
||||
hi CursorLine guibg=green guifg=white
|
||||
set cursorline
|
||||
call setline(1, 'aaa bbb')
|
||||
]])
|
||||
|
||||
-- when ComplMatchIns is not set, CursorLine applies normally
|
||||
feed('0ea <C-X><C-O>')
|
||||
screen:expect([[
|
||||
{10:aaa foo^ bbb }|
|
||||
{1:~ }{s: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 1 of 3} |
|
||||
]])
|
||||
feed('<C-E>')
|
||||
screen:expect([[
|
||||
{10:aaa ^ bbb }|
|
||||
{1:~ }|*18
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<BS><Esc>')
|
||||
|
||||
-- when ComplMatchIns is set, it is applied over CursorLine
|
||||
command('hi ComplMatchIns guifg=Yellow')
|
||||
feed('0ea <C-X><C-O>')
|
||||
screen:expect([[
|
||||
{10:aaa }{9:foo}{10:^ bbb }|
|
||||
{1:~ }{s: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 1 of 3} |
|
||||
]])
|
||||
feed('<C-P>')
|
||||
screen:expect([[
|
||||
{10:aaa ^ bbb }|
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{n: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{8:Back at original} |
|
||||
]])
|
||||
feed('<C-P>')
|
||||
screen:expect([[
|
||||
{10:aaa }{9:你好}{10:^ bbb }|
|
||||
{1:~ }{n: foo }{1: }|
|
||||
{1:~ }{n: bar }{1: }|
|
||||
{1:~ }{s: 你好 }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- }{5:match 3 of 3} |
|
||||
]])
|
||||
feed('<C-E>')
|
||||
screen:expect([[
|
||||
{10:aaa ^ bbb }|
|
||||
{1:~ }|*18
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -967,11 +967,11 @@ function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info)
|
||||
self._cursor_style_enabled = cursor_style_enabled
|
||||
for _, item in pairs(mode_info) do
|
||||
-- attr IDs are not stable, but their value should be
|
||||
if item.attr_id ~= nil then
|
||||
if item.attr_id ~= nil and self._attr_table[item.attr_id] ~= nil then
|
||||
item.attr = self._attr_table[item.attr_id][1]
|
||||
item.attr_id = nil
|
||||
end
|
||||
if item.attr_id_lm ~= nil then
|
||||
if item.attr_id_lm ~= nil and self._attr_table[item.attr_id_lm] ~= nil then
|
||||
item.attr_lm = self._attr_table[item.attr_id_lm][1]
|
||||
item.attr_id_lm = nil
|
||||
end
|
||||
|
@ -1,5 +1,8 @@
|
||||
" Test for various indent options
|
||||
|
||||
source shared.vim
|
||||
source check.vim
|
||||
|
||||
func Test_preserveindent()
|
||||
new
|
||||
" Test for autoindent copying indent from the previous line
|
||||
@ -303,4 +306,50 @@ func Test_indent_overflow_count2()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test that mouse shape is restored to Normal mode after using "gq" when
|
||||
" 'indentexpr' executes :normal.
|
||||
func Test_mouse_shape_indent_norm_with_gq()
|
||||
CheckFeature mouseshape
|
||||
CheckCanRunGui
|
||||
|
||||
let lines =<< trim END
|
||||
func Indent()
|
||||
exe "normal! \<Ignore>"
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
setlocal indentexpr=Indent()
|
||||
END
|
||||
call writefile(lines, 'Xindentexpr.vim', 'D')
|
||||
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
var mouse_shapes = []
|
||||
|
||||
setline(1, [repeat('a', 80), repeat('b', 80)])
|
||||
|
||||
feedkeys('ggVG')
|
||||
timer_start(50, (_) => {
|
||||
mouse_shapes += [getmouseshape()]
|
||||
timer_start(50, (_) => {
|
||||
feedkeys('gq')
|
||||
timer_start(50, (_) => {
|
||||
mouse_shapes += [getmouseshape()]
|
||||
timer_start(50, (_) => {
|
||||
writefile(mouse_shapes, 'Xmouseshapes')
|
||||
quit!
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
END
|
||||
call writefile(lines, 'Xmouseshape.vim', 'D')
|
||||
|
||||
call RunVim([], [], "-g -S Xindentexpr.vim -S Xmouseshape.vim")
|
||||
call WaitForAssert({-> assert_equal(['rightup-arrow', 'arrow'],
|
||||
\ readfile('Xmouseshapes'))}, 300)
|
||||
|
||||
call delete('Xmouseshapes')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1713,4 +1713,103 @@ func Test_pum_keep_select()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_pum_matchins_highlight()
|
||||
CheckScreendump
|
||||
let lines =<< trim END
|
||||
func Omni_test(findstart, base)
|
||||
if a:findstart
|
||||
return col(".")
|
||||
endif
|
||||
return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
|
||||
endfunc
|
||||
set omnifunc=Omni_test
|
||||
hi ComplMatchIns ctermfg=red
|
||||
END
|
||||
call writefile(lines, 'Xscript', 'D')
|
||||
let buf = RunVimInTerminal('-S Xscript', {})
|
||||
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "Sαβγ \<C-X>\<C-O>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_01', {})
|
||||
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "Sαβγ \<C-X>\<C-O>\<C-N>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_02', {})
|
||||
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "Sαβγ \<C-X>\<C-O>\<C-N>\<C-N>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_03', {})
|
||||
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||
|
||||
" restore after accept
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "Sαβγ \<C-X>\<C-O>\<C-Y>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_04', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
" restore after cancel completion
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "Sαβγ \<C-X>\<C-O>\<Space>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_05', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
" text after the inserted text shouldn't be highlighted
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "0ea \<C-X>\<C-O>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_07', {})
|
||||
call term_sendkeys(buf, "\<C-P>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_08', {})
|
||||
call term_sendkeys(buf, "\<C-P>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_09', {})
|
||||
call term_sendkeys(buf, "\<C-Y>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_10', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_pum_matchins_highlight_combine()
|
||||
CheckScreendump
|
||||
let lines =<< trim END
|
||||
func Omni_test(findstart, base)
|
||||
if a:findstart
|
||||
return col(".")
|
||||
endif
|
||||
return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
|
||||
endfunc
|
||||
set omnifunc=Omni_test
|
||||
hi Normal ctermbg=blue
|
||||
hi CursorLine cterm=underline ctermbg=green
|
||||
set cursorline
|
||||
call setline(1, 'aaa bbb')
|
||||
END
|
||||
call writefile(lines, 'Xscript', 'D')
|
||||
let buf = RunVimInTerminal('-S Xscript', {})
|
||||
|
||||
" when ComplMatchIns is not set, CursorLine applies normally
|
||||
call term_sendkeys(buf, "0ea \<C-X>\<C-O>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_01', {})
|
||||
call term_sendkeys(buf, "\<C-E>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_02', {})
|
||||
call term_sendkeys(buf, "\<BS>\<Esc>")
|
||||
|
||||
" when ComplMatchIns is set, it is applied over CursorLine
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, ":hi ComplMatchIns ctermbg=red ctermfg=yellow\<CR>")
|
||||
call TermWait(buf)
|
||||
call term_sendkeys(buf, "0ea \<C-X>\<C-O>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_03', {})
|
||||
call term_sendkeys(buf, "\<C-P>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_04', {})
|
||||
call term_sendkeys(buf, "\<C-P>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_05', {})
|
||||
call term_sendkeys(buf, "\<C-E>")
|
||||
call VerifyScreenDump(buf, 'Test_pum_matchins_combine_06', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -59,7 +59,8 @@ func Test_window_preview_terminal()
|
||||
CheckFeature quickfix
|
||||
" CheckFeature terminal
|
||||
|
||||
term " ++curwin
|
||||
" term ++curwin
|
||||
term
|
||||
const buf_num = bufnr('$')
|
||||
call assert_equal(1, winnr('$'))
|
||||
exe 'pbuffer' . buf_num
|
||||
|
Loading…
Reference in New Issue
Block a user