Tui

Nvim :help 頁面,使用 tree-sitter-vimdoc 解析器從 原始碼 產生


終端使用者介面 tui
預設情況下,當您執行 nvim(沒有 --embed--headless)時,它會啟動內建的「終端使用者介面」(TUI)。此預設介面是可選的:您可以將 Nvim 作為「無頭」伺服器執行,或者您可以使用 GUI
Nvim 具有客戶端-伺服器架構:預設情況下,當您執行 nvim 時,這會啟動內建的 UI 客戶端,該客戶端啟動一個 nvim --embed 伺服器(子)進程,UI 客戶端會連接到該進程。在連接到伺服器後,UI 客戶端會呼叫 nvim_set_client_info()(如 dev-ui 中針對所有 UI 建議的那樣),並在其通道上設定以下欄位
client = {
  attributes = {
    license = 'Apache 2',
    pid = …,
    website = 'https://neovim.dev.org.tw',
  },
  name = 'nvim-tui',
  type = 'ui',
  version = { … },
}
Nvim 在啟動時會猜測終端類型(除了在 --embed--headless 模式下)。 $TERM 環境變數是決定終端類型的主要提示。
terminfo E557 E558 E559 為了顯示其使用者介面,Nvim 會從系統 terminfo 資料庫(如果找不到 terminfo,則使用內建預設值)讀取「終端功能」列表。如果該資訊有誤,則螢幕可能會混亂,或者可能無法識別按鍵。
Unibilium 函式庫(用於讀取 terminfo)允許您使用 "$HOME/.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 會在終端中發出 true(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、0.36 或更高版本的 libvte 終端模擬器或將 COLORTERM 環境變數設定為 "truecolor" 的終端模擬器時,它將新增建構的 "setrgbf" 和 "setrgbb" 功能。
xterm-resize
Nvim 可以在某些實作 dtterm 首創的擴展功能的終端上調整終端顯示的大小。 terminfo 沒有此擴展的旗標。因此,Nvim 只是假設(所有)"dtterm"、"xterm"、"teraterm"、"rxvt" 終端類型和 Konsole 都能夠執行此操作。
tui-cursor-shape
當處於插入模式時(或由 'guicursor' 選項指定時),Nvim 會將游標的形狀從方塊調整為線條,如果終端支援此功能。它使用 tmux 首創的相同 terminfo 擴展來執行此操作:"Ss" 和 "Se"。同樣地,如果您使用 blend=100 設定游標醒目提示群組,Nvim 會透過 "cvvis" 和 "civis" 擴展來隱藏游標。
如果您的 terminfo 定義中缺少它們,則 Nvim 將透過查看 $TERM 和其他環境變數來決定是否將它們新增至您的 terminfo 定義。對於 "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(1) 手冊頁,瞭解如何在 tmux 組態檔案中執行操作的詳細資訊。它看起來會像這樣
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

慢速終端
如果您有慢速終端,您可能需要重設 '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>
主頁
指令索引
快速參考