Tui

Nvim 的 :help 页面,从 生成源代码,使用 tree-sitter-vimdoc 解析器。


终端 UI tui
默认情况下,当你运行 nvim(不使用 --embed--headless)时,它会启动内置的“终端 UI”(TUI)。此默认 UI 是可选的:你可以将 Nvim 作为“无头”服务器运行,或者你可以使用 GUI
Nvim 具有客户端-服务器架构:默认情况下,当你运行 nvim 时,这将启动内置的 UI 客户端,该客户端会启动一个 nvim --embed 服务器(子)进程,UI 客户端将连接到该进程。在连接到服务器后,UI 客户端会调用 nvim_set_client_info()(如所有 UI dev-ui 所建议的那样)并在其通道上设置这些字段
client = {
  attributes = {
    license = 'Apache 2',
    pid = …,
    website = 'https://neovim.fullstack.org.cn',
  },
  name = 'nvim-tui',
  type = 'ui',
  version = { … },
}
Nvim 在启动时会猜测终端类型(除了 --embed--headless 模式)。$TERM 环境变量是决定终端类型的主要提示。
terminfo E557 E558 E559 为了显示其用户界面,Nvim 从系统 terminfo 数据库中读取一个“终端功能”列表(如果未找到 terminfo,则使用内置默认值)。如果该信息错误,屏幕可能会出现混乱,或者键可能无法识别。
Unibilium 库(用于读取 terminfo)允许你使用 "$HOME/.terminfo/" 目录中的 terminfo 覆盖系统 terminfo。构建自己的 terminfo 通常与运行以下命令一样简单
curl -LO https://invisible-island.net/datafiles/current/terminfo.src.gz
gunzip terminfo.src.gz
tic -x terminfo.src
$TERM
$TERM 环境变量必须与你使用的终端匹配!否则,Nvim 无法知道你的终端期望什么序列,将会导致奇怪或次优的行为(滚动问题、错误颜色等)。
$TERM 也很重要,因为它通过 SSH 传递到远程会话,不像大多数其他环境变量。
For this terminal           Set $TERM to                  |builtin-terms|
-------------------------------------------------------------------------
anything libvte-based       vte, vte-256color                   Y
 (e.g. GNOME Terminal)      (aliases: gnome, gnome-256color)
iTerm (original)            iterm, iTerm.app                    N
iTerm2 (new capabilities)   iterm2, iTerm2.app                  Y
Konsole                     konsole-256color                    N
Linux virtual terminal      linux, linux-256color               Y
PuTTY                       putty, putty-256color               Y
rxvt                        rxvt, rxvt-256color                 Y
screen                      screen, screen-256color             Y
simple terminal (st)        st, st-256color                     Y
Terminal.app                nsterm                              N
tmux                        tmux, tmux-256color                 Y
Windows/ConEmu              conemu                              Y
Windows/Cygwin-built Nvim   cygwin                              Y
Windows/Interix             interix                             Y
Windows/VTP console         vtpcon                              Y
Windows/legacy console      win32con                            Y
xterm or compatible         xterm, xterm-256color               Y
builtin-terms builtin_terms 如果 terminfo 数据库不可用或当前终端没有条目,Nvim 会根据上表将 $TERM 映射到内置条目,或者在没有匹配项的情况下映射到“ansi”。例如,"TERM=putty-256color" 将被映射到内置的“putty”条目。另请参阅 tui-colors
内置 terminfo 不会与任何外部 terminfo 数据库结合,也不会优先于外部数据库使用。因此,你可以通过提供一个包含终端类型条目的外部数据库来完全覆盖内置 terminfo 数据库中任何遗漏或过时的信息。
取决于终端的设置 term-dependent-settings
如果你想在 init.vim 中设置与终端相关的选项或映射,你可以这样做。示例
if $TERM =~ '^\(rxvt\|screen\|interix\|putty\)\(-.*\)\?$'
    set notermguicolors
elseif $TERM =~ '^\(tmux\|iterm\|vte\|gnome\)\(-.*\)\?$'
    set termguicolors
elseif $TERM =~ '^\(xterm\)\(-.*\)\?$'
    if $XTERM_VERSION != ''
        set termguicolors
    elseif $KONSOLE_PROFILE_NAME != ''
        set termguicolors
    elseif $VTE_VERSION != ''
        set termguicolors
    else
        set notermguicolors
    endif
elseif $TERM =~ ...
    ... and so forth ...
endif
scroll-region xterm-scroll-region 尽可能地,Nvim 会使用终端设置滚动区域的功能,以便在窗口滚动时更快地重绘。如果终端的 terminfo 描述说明了设置顶部和底部滚动边距的功能,则会使用该功能。
这不会加快未占用整个终端宽度的窗口的滚动速度。Xterm 具有一个额外的功能,该功能没有在 terminfo 中描述,即设置左右滚动边距。如果 Nvim 检测到终端是 Xterm,它会利用此功能来加快未占用整个终端宽度的滚动的速度。
tui-input
历史上,终端模拟器无法区分某些控制键修饰符和其他键。例如,<C-I><Tab> 在表示方式上相同,<Esc><C-[> 也是如此,<CR><C-M> 也是如此,<NL><C-J> 也是如此。
现代终端模拟器能够通过以不同方式编码控制修饰符来区分这些键对。有两种常见但不同的方法,称为“modifyOtherKeys”和“CSI u”。Nvim 支持这两种编码方法,并在启动时会告诉终端模拟器它理解这些键编码。如果你的终端模拟器支持它,那么这将允许你分别映射上面列出的键对。 <Tab>
Nvim 使用 libtermkey 将终端转义序列转换为键代码。首先使用 terminfo,并且 terminfo 中不存在的 CSI 序列(包括扩展键,也称为“modifyOtherKeys”或“CSI u”)也可以被解析。
例如,在 tmux 中运行 Nvim 时,这会使 Nvim 退出插入模式并转到下面的窗口
tmux send-keys 'Escape' [ 2 7 u 'C-W' j
其中 'Escape' [ 2 7 u<Esc> 键的明确的“CSI u”序列。
kitty 键盘协议 https://sw.kovidgoyal.net/kitty/keyboard-protocol/ 部分支持,包括 Unicode 私用区中的键盘键。例如,Nvim 会将此序列识别为 <C-kEnter>
CSI 57414 ; 5 u
并且可以在映射中与 <C-CR> 区分开来使用。
tui-modifyOtherKeys tui-csiu 在启动时,Nvim 会查询你的终端以查看它是否支持“CSI u”编码,方法是写入序列
CSI ? u CSI c
如果你的终端模拟器以以下方式响应
CSI ? <flags> u
这意味着你的终端支持“CSI u”编码,Nvim 将通过写入序列来告诉你的终端启用它
CSI > 1 u
如果你的终端不支持“CSI u”,那么 Nvim 将改为通过写入序列来启用“modifyOtherKeys”编码
CSI > 4 ; 2 m
当 Nvim 正常退出时,它会发送相应的序列来禁用特殊键编码。如果 Nvim 未正常退出,则你的终端模拟器可能处于错误状态。如果发生这种情况,只需运行“reset”。
tui-colors
Nvim 默认使用 256 色,忽略大多数终端类型的 terminfo,包括“linux”(其虚拟终端自 4.8 版本以来一直具有 256 色支持)和声称自己是“xterm”的任何终端。当 $COLORTERM 或 $TERM 包含字符串“256”时也是如此。
Nvim 同样假设任何将 $COLORTERM 设置为任何值的终端模拟器都至少能够执行 16 色操作。
true-color xterm-true-color 如果设置了 'termguicolors',Nvim 会在终端中发出真彩色(24 位)颜色。
它使用“setrgbf”和“setrgbb” terminfo 扩展(由 Rüdiger Sonderfeld 在 2013 年提出)。如果你的 terminfo 定义中缺少它们,那么 Nvim 将决定是否将它们添加到你的 terminfo 定义中,使用 ISO 8613-6:1994/ITU T.416:1993 控制序列来设置 RGB 颜色(但修改为使用分号而不是冒号,除非已知终端遵循标准)。
另一个由 tmux 在 2016 年开创的惯例是“Tc” terminfo 扩展。如果 terminfo 有此标志,Nvim 将添加构造的“setrgbf”和“setrgbb”功能,就好像它们在 terminfo 定义中一样。
如果 terminfo 还没有此标志,Nvim 将回退到 $TERM 和其他环境变量。在“rxvt”、“linux”、“st”、“tmux”和“iterm”终端类型的情况下,或者在检测到 Konsole、真正的 Xterm、libvte 终端模拟器 0.36 或更高版本,或者将 COLORTERM 环境变量设置为“truecolor”的终端模拟器时,它将添加构造的“setrgbf”和“setrgbb”功能。
xterm-resize
Nvim 可以调整某些终端的终端显示大小,这些终端实现了由 dtterm 开创的扩展。 terminfo 没有此扩展的标志。因此,Nvim 只假设(所有)“dtterm”、“xterm”、“teraterm”、“rxvt”终端类型和 Konsole 都能够做到这一点。
tui-cursor-shape
Nvim 会在支持它的终端上,将光标形状从块状调整为线状,在插入模式下(或由 'guicursor' 选项指定)。它使用与 tmux 为此开创的相同的 terminfo 扩展:“Ss”和“Se”。类似地,如果你使用 blend=100 设置光标高亮组,Nvim 会通过“cvvis”和“civis”扩展隐藏光标。
如果你的 terminfo 定义中缺少它们,那么 Nvim 将决定是否将它们添加到你的 terminfo 定义中,方法是查看 $TERM 和其他环境变量。对于“rxvt”、“putty”、“linux”、“screen”、“teraterm”和“iterm”终端类型,或者在检测到 Konsole、基于 libvte 的终端模拟器或真正的 Xterm 时,它会添加构造的“Ss”和“Se”功能。
tui-cursor-tmux
在 tmux 中,Nvim 看起来似乎没有更改光标,但实际上,是 tmux 收到了 Nvim 的指令来更改光标,并且不知道该怎么做。tmux 必须将它从 Nvim 收到的内容转换为适用于主机终端的任何控制序列。它与 Nvim 共享一个通用机制,即使用 terminfo(对于输出终端)中的“Ss”和“Se”功能(如果存在)。与 Nvim 不同的是,如果它们不在 terminfo 中,你必须通过在 ~/.tmux.conf 中设置“terminal-overrides”来添加它们。
有关如何在 tmux 配置文件中执行操作以及执行哪些操作的详细信息,请参阅 tmux(1) 手册页。它看起来像这样
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
或者(唉!)对于 Konsole 18.07.70 或更早版本,看起来更复杂,像这样
set -ga terminal-overrides 'xterm*:\E]50;CursorShape=%?%p1%{3}%<%t%{0}%e%{1}%;%d\007'

窗口大小 window-size

[这指的是 Vim 使用的整个窗口的大小,而不是使用 ":split" 命令创建的窗口。]
在 Unix 系统上,会尝试使用三种方法来获取窗口大小
一个 ioctl 调用(TIOCGSIZE 或 TIOCGWINSZ,取决于你的系统)
环境变量“LINES”和“COLUMNS”
来自 terminfo 条目“lines”和“columns”
如果所有方法都失败,则假设默认大小为 24 行和 80 列。如果收到窗口大小调整信号,则会重新设置大小。如果窗口大小错误,可以使用 'lines''columns' 选项来设置正确的值。请参阅 :mode

慢速和快速终端 slow-fast-terminal

slow-terminal
如果你有一个慢速终端,你可能需要重置 'showcmd''ruler' 选项。命令字符和光标位置不会显示在状态行中(这涉及到每次按键或移动都需要大量的光标移动和属性更改)。如果终端滚动非常缓慢,请将 'scrolljump' 设置为 5 或更小。如果光标移动到屏幕外(例如,使用“j”),Vim 将一次滚动 5 行。另一个方法是使用命令 "z{height}<CR>" 减少 Vim 使用的行数。
如果来自终端的字符之间间隔超过 1 秒,你可能需要设置 'timeout' 和/或 'ttimeout' 选项。
如果你使用的是彩色终端,并且在显示超出缓冲区末尾的行时速度很慢,这是因为 Nvim 正在以两种颜色和属性绘制两次空白。要防止这种情况,请使用以下命令
hi NonText cterm=NONE ctermfg=NONE
这会使用默认颜色和属性绘制空格,从而使第二遍绘制可以被优化掉。 注意: 虽然从理论上来说,空白处的颜色无关紧要,但在实际应用中,它们会改变跨越它们的游标和选区的颜色。这可能会对某些 UI 产生可见但微小的影响。

使用鼠标 mouse-using

mouse-mode-table mouse-overview'mousemodel' 为 "extend" 时,鼠标按钮的功能概述
<S-LeftMouse> <A-RightMouse> <S-RightMouse> <RightDrag> <RightRelease> <LeftDrag> 正常模式
event         position     selection        change  action
               cursor                       window
---------------------------------------------------------------------------
<LeftMouse>     yes          end              yes
<C-LeftMouse>   yes          end              yes    "CTRL-]" (2)
<S-LeftMouse>   yes       no change           yes    "*" (2)
<LeftDrag>      yes     start or extend (1)   no
<LeftRelease>   yes     start or extend (1)   no
<MiddleMouse>   yes       if not active       no     put
<MiddleMouse>   yes       if active           no     yank and put
<RightMouse>    yes     start or extend       yes
<A-RightMouse>  yes start or extend blockw.   yes
<S-RightMouse>  yes        no change          yes    "#" (2)
<C-RightMouse>  no         no change          no     "CTRL-T"
<RightDrag>     yes         extend            no
<RightRelease>  yes         extend            no
插入或替换模式
event         position     selection        change  action
               cursor                       window
---------------------------------------------------------------------------
<LeftMouse>     yes     (cannot be active)    yes
<C-LeftMouse>   yes     (cannot be active)    yes    "CTRL-O^]" (2)
<S-LeftMouse>   yes     (cannot be active)    yes    "CTRL-O*" (2)
<LeftDrag>      yes     start or extend (1)   no     like CTRL-O (1)
<LeftRelease>   yes     start or extend (1)   no     like CTRL-O (1)
<MiddleMouse>   no      (cannot be active)    no     put register
<RightMouse>    yes     start or extend       yes    like CTRL-O
<A-RightMouse>  yes start or extend blockw.   yes
<S-RightMouse>  yes     (cannot be active)    yes    "CTRL-O#" (2)
<C-RightMouse>  no      (cannot be active)    no     "CTRL-O CTRL-T"
在帮助窗口中
event         position     selection        change  action
               cursor                       window
---------------------------------------------------------------------------
<2-LeftMouse>   yes     (cannot be active)    no     "^]" (jump to help tag)
'mousemodel' 为 "popup" 时,这些操作会有所不同
<A-LeftMouse>
正常模式
event         position     selection        change  action
               cursor                       window
---------------------------------------------------------------------------
<S-LeftMouse>   yes     start or extend (1)   no
<A-LeftMouse>   yes     start/extend blockw   no
<RightMouse>    no      popup menu            no
插入或替换模式
event         position     selection        change  action
               cursor                       window
---------------------------------------------------------------------------
<S-LeftMouse>   yes     start or extend (1)   no     like CTRL-O (1)
<A-LeftMouse>   yes     start/extend blockw   no
<RightMouse>    no      popup menu            no
(1) 仅当鼠标指针自按下后移动 (2) 仅当点击在同一缓冲区内
单击鼠标左键会将光标定位到点击位置。如果点击在另一个窗口,则该窗口将变为活动窗口。在编辑命令行时,光标只能定位在命令行上。处于插入模式时,Vim 将保持在插入模式。如果设置了 'scrolloff',并且光标位于窗口边框距 'scrolloff' 行内,则文本将滚动。
可以通过按下第一个字符上的鼠标左键,将鼠标移动到最后一个字符,然后释放鼠标左键来启动选择。只有在您释放按钮后,才会始终看到选择,只有在某些版本(GUI、Win32)中才会立即显示拖动。请注意,当 'scrolloff' 非零时,您可以通过在窗口中第一行/最后一行移动鼠标至少一个字符来使文本滚动。
在正常、可视和选择模式下,单击鼠标右键会导致可视区域扩展。当 'mousemodel' 为 "popup" 时,必须在按住 Shift 键的同时使用鼠标左键。当点击正在编辑另一个缓冲区的窗口时,可视或选择模式将停止。
在正常、可视和选择模式下,按住 Alt 键并单击鼠标右键会导致可视区域变为块状。当 'mousemodel' 为 "popup" 时,必须使用鼠标左键和 Alt 键。请注意,这在窗口管理器在按下 Alt 键时消耗鼠标事件的系统上将不起作用(它可能会移动窗口)。
double-click <2-LeftMouse> <3-LeftMouse> <4-LeftMouse> 当 GUI 活动时,Win32 和 xterm 支持双击、三击和四击。对于选择文本,额外点击会扩展选择
click           select
---------------------------------
double          word or % match
triple          line
quadruple       rectangular block
例外:在帮助窗口中,双击将跳转到所点击单词的帮助信息。
双击单词会选中该单词。 'iskeyword' 用于指定包含在单词中的字符。双击具有匹配项的字符会选择直到该匹配项(类似于使用 "v%")。如果匹配项是 #if/#else/#endif 块,则选择将变为行级。对于 MS-Windows 和 xterm,双击的时间可以通过 'mousetime' 选项设置。对于其他系统,此时间在 Vim 之外定义。例如,使用双击跳转到光标下的标签
:map <2-LeftMouse> :exe "tag " .. expand("<cword>")<CR>
用双击拖动鼠标(按键按下、按键释放、按键按下,然后拖动)会导致选择整个单词。这将持续到释放按钮为止,此时选择将再次按字符进行。
有关使用鼠标滚动的信息,请参见 scroll-mouse-wheel
在插入模式下,当启动选择时,Vim 会暂时进入正常模式。当可视或选择模式结束时,它会返回到插入模式。这类似于在插入模式下使用 CTRL-O。当 'selectmode' 选项包含 "mouse" 时,将使用选择模式。
X1Mouse X1Drag X1Release X2Mouse X2Drag X2Release <MiddleRelease> <MiddleDrag> 鼠标点击可以被映射。鼠标点击的代码是
    code           mouse button              normal action
---------------------------------------------------------------------------
<LeftMouse>     left pressed               set cursor position
<LeftDrag>      left moved while pressed   extend selection
<LeftRelease>   left released              set selection end
<MiddleMouse>   middle pressed             paste text at cursor position
<MiddleDrag>    middle moved while pressed -
<MiddleRelease> middle released            -
<RightMouse>    right pressed              extend selection
<RightDrag>     right moved while pressed  extend selection
<RightRelease>  right released             set selection end
<X1Mouse>       X1 button pressed          -
<X1Drag>        X1 moved while pressed     -
<X1Release>     X1 button release          -
<X2Mouse>       X2 button pressed          -
<X2Drag>        X2 moved while pressed     -
<X2Release>     X2 button release          -
X1 和 X2 按钮是指某些鼠标上额外的按钮。'Microsoft Explorer' 鼠标在右边的拇指处提供这些按钮。目前,X1 和 X2 仅在 Win32 和 X11 环境中有效。
示例
:noremap <MiddleMouse> <LeftMouse><MiddleMouse>
将粘贴内容粘贴到鼠标中键点击的位置(否则,粘贴内容将粘贴到光标位置)。
:noremap <LeftRelease> <LeftRelease>y
在使用可视模式时,立即将选择内容复制。
请注意使用 ":noremap" 而不是 "map" 以避免递归映射。
:map <X1Mouse> <C-O>
:map <X2Mouse> <C-I>
将 X1 和 X2 按钮映射到跳转列表中的前进和后退,请参见 CTRL-OCTRL-I
mouse-swap-buttons
要交换鼠标左键和右键的含义
:noremap        <LeftMouse>     <RightMouse>
:noremap        <LeftDrag>      <RightDrag>
:noremap        <LeftRelease>   <RightRelease>
:noremap        <RightMouse>    <LeftMouse>
:noremap        <RightDrag>     <LeftDrag>
:noremap        <RightRelease>  <LeftRelease>
:noremap        g<LeftMouse>    <C-RightMouse>
:noremap        g<RightMouse>   <C-LeftMouse>
:noremap!       <LeftMouse>     <RightMouse>
:noremap!       <LeftDrag>      <RightDrag>
:noremap!       <LeftRelease>   <RightRelease>
:noremap!       <RightMouse>    <LeftMouse>
:noremap!       <RightDrag>     <LeftDrag>
:noremap!       <RightRelease>  <LeftRelease>
主要
命令索引
快速参考