mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
ff85e54939
Problem: The default builtin UI client does not declare its client info. This reduces discoverability and makes it difficult for plugins to identify the UI. Solution: - Call nvim_set_client_info after attaching, as recommended by `:help dev-ui`. - Also set the "pid" field. - Also change `ui_active()` to return a count. Not directly relevant to this commit, but will be useful later.
471 lines
22 KiB
Plaintext
471 lines
22 KiB
Plaintext
*tui.txt* Nvim
|
|
|
|
|
|
NVIM REFERENCE MANUAL
|
|
|
|
|
|
Terminal UI *TUI* *tui*
|
|
|
|
By default when you run `nvim` (without |--embed| or |--headless|) it starts
|
|
the builtin "terminal UI" (TUI). This default UI is optional: you can run Nvim
|
|
as a "headless" server, or you can use a |GUI|.
|
|
|
|
Type |gO| to see the table of contents.
|
|
|
|
==============================================================================
|
|
Startup *startup-tui* *startup-terminal*
|
|
|
|
Nvim has a client-server architecture: by default when you run `nvim`, this
|
|
starts the builtin UI client, which starts a `nvim --embed` server (child)
|
|
process that the UI client connects to. After attaching to the server, the UI
|
|
client calls |nvim_set_client_info()| (as recommended for all UIs |dev-ui|)
|
|
and sets these fields on its channel: >
|
|
|
|
client = {
|
|
attributes = {
|
|
license = 'Apache 2',
|
|
pid = …,
|
|
website = 'https://neovim.io',
|
|
},
|
|
name = 'nvim-tui',
|
|
type = 'ui',
|
|
version = { … },
|
|
}
|
|
|
|
Nvim guesses the terminal type when it starts (except in |--embed| and
|
|
|--headless| modes). The |$TERM| environment variable is the primary hint that
|
|
determines the terminal type.
|
|
|
|
*terminfo* *E557* *E558* *E559*
|
|
To display its user interface, Nvim reads a list of "terminal capabilities"
|
|
from the system terminfo database (or builtin defaults if terminfo is not
|
|
found). If that information is wrong, the screen may be messed up or keys may
|
|
not be recognized.
|
|
|
|
The Unibilium library (used to read terminfo) allows you to override the
|
|
system terminfo with one in the "$HOME/.terminfo/" directory. Building your
|
|
own terminfo is usually as simple as running this:
|
|
>
|
|
curl -LO https://invisible-island.net/datafiles/current/terminfo.src.gz
|
|
gunzip terminfo.src.gz
|
|
tic -x terminfo.src
|
|
<
|
|
*$TERM*
|
|
The $TERM environment variable must match the terminal you are using!
|
|
Otherwise Nvim cannot know what sequences your terminal expects, and weird
|
|
or sub-optimal behavior will result (scrolling quirks, wrong colors, etc.).
|
|
|
|
$TERM is also important because it is forwarded by SSH to the remote session,
|
|
unlike most other environment variables.
|
|
|
|
>
|
|
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*
|
|
If a |terminfo| database is not available or there is no entry for the current
|
|
terminal, Nvim will map |$TERM| to a builtin entry according to the above
|
|
table, or "ansi" if there is no match. For example "TERM=putty-256color" will
|
|
be mapped to the builtin "putty" entry. See also |tui-colors|.
|
|
|
|
The builtin terminfo is not combined with any external terminfo database, nor
|
|
can it be used in preference to one. You can thus entirely override any
|
|
omissions or out-of-date information in the builtin terminfo database by
|
|
supplying an external one with entries for the terminal type.
|
|
|
|
Settings depending on terminal *term-dependent-settings*
|
|
|
|
If you want to set terminal-dependent options or mappings, you can do this in
|
|
your init.vim. Example: >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*
|
|
Where possible, Nvim will use the terminal's ability to set a scroll region in
|
|
order to redraw faster when a window is scrolled. If the terminal's terminfo
|
|
description describes an ability to set top and bottom scroll margins, that is
|
|
used.
|
|
|
|
This will not speed up scrolling in a window that is not the full width of the
|
|
terminal. Xterm has an extra ability, not described by terminfo, to set left
|
|
and right scroll margins as well. If Nvim detects that the terminal is Xterm,
|
|
it will make use of this ability to speed up scrolling that is not the full
|
|
width of the terminal.
|
|
|
|
*tui-input*
|
|
Historically, terminal emulators could not distinguish between certain control
|
|
key modifiers and other keys. For example, <C-I> and <Tab> are represented in
|
|
the same way, as are <Esc> and <C-[>, <CR> and <C-M>, and <NL> and <C-J>.
|
|
|
|
Modern terminal emulators are able to distinguish between these pairs of keys
|
|
by encoding control modifiers differently. There are two common but distinct
|
|
ways of doing this, known as "modifyOtherKeys" and "CSI u". Nvim supports both
|
|
encoding methods and at startup will tell the terminal emulator that it
|
|
understands these key encodings. If your terminal emulator supports it then
|
|
this will allow you to map the key pairs listed above separately. |<Tab>|
|
|
|
|
Nvim uses libtermkey to convert terminal escape sequences to key codes.
|
|
|terminfo| is used first, and CSI sequences not in |terminfo| (including
|
|
extended keys a.k.a. "modifyOtherKeys" or "CSI u") can also be parsed.
|
|
|
|
For example, when running Nvim in tmux, this makes Nvim leave Insert mode and
|
|
go to the window below: >
|
|
tmux send-keys 'Escape' [ 2 7 u 'C-W' j
|
|
Where `'Escape' [ 2 7 u` is an unambiguous "CSI u" sequence for the <Esc> key.
|
|
|
|
The kitty keyboard protocol https://sw.kovidgoyal.net/kitty/keyboard-protocol/
|
|
is partially supported, including keypad keys in Unicode Private Use Area.
|
|
For example, this sequence is recognized by Nvim as <C-kEnter>: >
|
|
CSI 57414 ; 5 u
|
|
and can be used differently from <C-CR> in mappings.
|
|
|
|
*tui-modifyOtherKeys* *tui-csiu*
|
|
At startup Nvim will query your terminal to see if it supports the "CSI u"
|
|
encoding by writing the sequence >
|
|
CSI ? u CSI c
|
|
If your terminal emulator responds with >
|
|
CSI ? <flags> u
|
|
this means your terminal supports the "CSI u" encoding and Nvim will tell your
|
|
terminal to enable it by writing the sequence >
|
|
CSI > 1 u
|
|
If your terminal does not support "CSI u" then Nvim will instead enable the
|
|
"modifyOtherKeys" encoding by writing the sequence >
|
|
CSI > 4 ; 2 m
|
|
|
|
When Nvim exits cleanly it will send the corresponding sequence to disable the
|
|
special key encoding. If Nvim does not exit cleanly then your terminal
|
|
emulator could be in a bad state. If this happens, simply run "reset".
|
|
|
|
*tui-colors*
|
|
Nvim uses 256 colours by default, ignoring |terminfo| for most terminal types,
|
|
including "linux" (whose virtual terminals have had 256-colour support since
|
|
4.8) and anything claiming to be "xterm". Also when $COLORTERM or $TERM
|
|
contain the string "256".
|
|
|
|
Nvim similarly assumes that any terminal emulator that sets $COLORTERM to any
|
|
value, is capable of at least 16-colour operation.
|
|
|
|
*true-color* *xterm-true-color*
|
|
Nvim emits true (24-bit) colours in the terminal, if 'termguicolors' is set.
|
|
|
|
It uses the "setrgbf" and "setrgbb" |terminfo| extensions (proposed by Rüdiger
|
|
Sonderfeld in 2013). If your terminfo definition is missing them, then Nvim
|
|
will decide whether to add them to your terminfo definition, using the ISO
|
|
8613-6:1994/ITU T.416:1993 control sequences for setting RGB colours (but
|
|
modified to use semicolons instead of colons unless the terminal is known to
|
|
follow the standard).
|
|
|
|
Another convention, pioneered in 2016 by tmux, is the "Tc" terminfo extension.
|
|
If terminfo has this flag, Nvim will add constructed "setrgbf" and "setrgbb"
|
|
capabilities as if they had been in the terminfo definition.
|
|
|
|
If terminfo does not (yet) have this flag, Nvim will fall back to $TERM and
|
|
other environment variables. It will add constructed "setrgbf" and "setrgbb"
|
|
capabilities in the case of the "rxvt", "linux", "st", "tmux", and "iterm"
|
|
terminal types, or when Konsole, genuine Xterm, a libvte terminal emulator
|
|
version 0.36 or later, or a terminal emulator that sets the COLORTERM
|
|
environment variable to "truecolor" is detected.
|
|
|
|
*xterm-resize*
|
|
Nvim can resize the terminal display on some terminals that implement an
|
|
extension pioneered by dtterm. |terminfo| does not have a flag for this
|
|
extension. So Nvim simply assumes that (all) "dtterm", "xterm", "teraterm",
|
|
"rxvt" terminal types, and Konsole, are capable of this.
|
|
|
|
*tui-cursor-shape*
|
|
Nvim will adjust the shape of the cursor from a block to a line when in insert
|
|
mode (or as specified by the 'guicursor' option), on terminals that support
|
|
it. It uses the same |terminfo| extensions that were pioneered by tmux for
|
|
this: "Ss" and "Se".
|
|
Similarly, if you set the cursor highlight group with blend=100, Nvim hides
|
|
the cursor through the "cvvis" and "civis" extensions.
|
|
|
|
If your terminfo definition is missing them, then Nvim will decide whether to
|
|
add them to your terminfo definition, by looking at $TERM and other
|
|
environment variables. For the "rxvt", "putty", "linux", "screen",
|
|
"teraterm", and "iterm" terminal types, or when Konsole, a libvte-based
|
|
terminal emulator, or genuine Xterm are detected, it will add constructed
|
|
"Ss" and "Se" capabilities.
|
|
|
|
*tui-cursor-tmux*
|
|
Within tmux it may appear that Nvim is not changing the cursor, but in fact it
|
|
is tmux receiving instructions from Nvim to change the cursor and not knowing
|
|
what to do in turn. tmux must translate what it receives from Nvim into
|
|
whatever control sequence is appropriate for the host terminal. It shares
|
|
a common mechanism with Nvim, of using the "Ss" and "Se" capabilities from
|
|
terminfo (for the output terminal) if they are present. Unlike Nvim, if they
|
|
are not in terminfo you must add them by setting "terminal-overrides" in
|
|
~/.tmux.conf .
|
|
|
|
See the tmux(1) manual page for the details of how and what to do in the tmux
|
|
configuration file. It will look something like: >bash
|
|
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
|
|
or (alas!) for Konsole 18.07.70 or older, something more complex like: >bash
|
|
set -ga terminal-overrides 'xterm*:\E]50;CursorShape=%?%p1%{3}%<%t%{0}%e%{1}%;%d\007'
|
|
<
|
|
==============================================================================
|
|
Window size *window-size*
|
|
|
|
[This is about the size of the whole window Vim is using, not a window that is
|
|
created with the ":split" command.]
|
|
|
|
On Unix systems, three methods are tried to get the window size:
|
|
|
|
- an ioctl call (TIOCGSIZE or TIOCGWINSZ, depends on your system)
|
|
- the environment variables "LINES" and "COLUMNS"
|
|
- from the |terminfo| entries "lines" and "columns"
|
|
|
|
If everything fails a default size of 24 lines and 80 columns is assumed. If
|
|
a window-resize signal is received the size will be set again. If the window
|
|
size is wrong you can use the 'lines' and 'columns' options to set the
|
|
correct values. See |:mode|.
|
|
|
|
==============================================================================
|
|
Slow and fast terminals *slow-fast-terminal*
|
|
*slow-terminal*
|
|
|
|
If you have a slow terminal you may want to reset the 'showcmd' and 'ruler'
|
|
options. The command characters and cursor positions will not be shown in the
|
|
status line (which involves a lot of cursor motions and attribute changes for
|
|
every keypress or movement). If the terminal scrolls very slowly, set the
|
|
'scrolljump' to 5 or so. If the cursor is moved off the screen (e.g., with
|
|
"j") Vim will scroll 5 lines at a time. Another possibility is to reduce the
|
|
number of lines that Vim uses with the command "z{height}<CR>".
|
|
|
|
If the characters from the terminal are arriving with more than 1 second
|
|
between them you might want to set the 'timeout' and/or 'ttimeout' option.
|
|
|
|
If you are using a color terminal that is slow when displaying lines beyond
|
|
the end of a buffer, this is because Nvim is drawing the whitespace twice, in
|
|
two sets of colours and attributes. To prevent this, use this command: >vim
|
|
hi NonText cterm=NONE ctermfg=NONE
|
|
This draws the spaces with the default colours and attributes, which allows the
|
|
second pass of drawing to be optimized away. Note: Although in theory the
|
|
colours of whitespace are immaterial, in practice they change the colours of
|
|
cursors and selections that cross them. This may have a visible, but minor,
|
|
effect on some UIs.
|
|
|
|
==============================================================================
|
|
Using the mouse *mouse-using*
|
|
|
|
*mouse-mode-table* *mouse-overview*
|
|
Overview of what the mouse buttons do, when 'mousemodel' is "extend":
|
|
|
|
*<S-LeftMouse>* *<A-RightMouse>* *<S-RightMouse>* *<RightDrag>*
|
|
*<RightRelease>* *<LeftDrag>*
|
|
Normal Mode: >
|
|
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
|
|
|
|
Insert or Replace Mode: >
|
|
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"
|
|
|
|
In a help window: >
|
|
event position selection change action
|
|
cursor window
|
|
---------------------------------------------------------------------------
|
|
<2-LeftMouse> yes (cannot be active) no "^]" (jump to help tag)
|
|
|
|
When 'mousemodel' is "popup", these are different:
|
|
|
|
*<A-LeftMouse>*
|
|
Normal Mode: >
|
|
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
|
|
|
|
Insert or Replace Mode: >
|
|
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) only if mouse pointer moved since press
|
|
(2) only if click is in same buffer
|
|
|
|
Clicking the left mouse button causes the cursor to be positioned. If the
|
|
click is in another window that window is made the active window. When
|
|
editing the command-line the cursor can only be positioned on the
|
|
command-line. When in Insert mode Vim remains in Insert mode. If 'scrolloff'
|
|
is set, and the cursor is positioned within 'scrolloff' lines from the window
|
|
border, the text is scrolled.
|
|
|
|
A selection can be started by pressing the left mouse button on the first
|
|
character, moving the mouse to the last character, then releasing the mouse
|
|
button. You will not always see the selection until you release the button,
|
|
only in some versions (GUI, Win32) will the dragging be shown immediately.
|
|
Note that you can make the text scroll by moving the mouse at least one
|
|
character in the first/last line in the window when 'scrolloff' is non-zero.
|
|
|
|
In Normal, Visual and Select mode clicking the right mouse button causes the
|
|
Visual area to be extended. When 'mousemodel' is "popup", the left button has
|
|
to be used while keeping the shift key pressed. When clicking in a window
|
|
which is editing another buffer, the Visual or Select mode is stopped.
|
|
|
|
In Normal, Visual and Select mode clicking the right mouse button with the alt
|
|
key pressed causes the Visual area to become blockwise. When 'mousemodel' is
|
|
"popup" the left button has to be used with the alt key. Note that this won't
|
|
work on systems where the window manager consumes the mouse events when the
|
|
alt key is pressed (it may move the window).
|
|
|
|
*double-click* *<2-LeftMouse>* *<3-LeftMouse>* *<4-LeftMouse>*
|
|
Double, triple and quadruple clicks are supported when the GUI is active, for
|
|
Win32 and for an xterm. For selecting text, extra clicks extend the
|
|
selection: >
|
|
|
|
click select
|
|
---------------------------------
|
|
double word or % match
|
|
triple line
|
|
quadruple rectangular block
|
|
|
|
Exception: In a Help window a double click jumps to help for the word that is
|
|
clicked on.
|
|
|
|
A double click on a word selects that word. 'iskeyword' is used to specify
|
|
which characters are included in a word. A double click on a character
|
|
that has a match selects until that match (like using "v%"). If the match is
|
|
an #if/#else/#endif block, the selection becomes linewise.
|
|
For MS-Windows and xterm the time for double clicking can be set with the
|
|
'mousetime' option. For the other systems this time is defined outside of Vim.
|
|
An example, for using a double click to jump to the tag under the cursor: >vim
|
|
:map <2-LeftMouse> :exe "tag " .. expand("<cword>")<CR>
|
|
|
|
Dragging the mouse with a double click (button-down, button-up, button-down
|
|
and then drag) will result in whole words to be selected. This continues
|
|
until the button is released, at which point the selection is per character
|
|
again.
|
|
|
|
For scrolling with the mouse see |scroll-mouse-wheel|.
|
|
|
|
In Insert mode, when a selection is started, Vim goes into Normal mode
|
|
temporarily. When Visual or Select mode ends, it returns to Insert mode.
|
|
This is like using CTRL-O in Insert mode. Select mode is used when the
|
|
'selectmode' option contains "mouse".
|
|
|
|
*X1Mouse* *X1Drag* *X1Release*
|
|
*X2Mouse* *X2Drag* *X2Release*
|
|
*<MiddleRelease>* *<MiddleDrag>*
|
|
Mouse clicks can be mapped. The codes for mouse clicks are: >
|
|
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 -
|
|
|
|
The X1 and X2 buttons refer to the extra buttons found on some mice. The
|
|
'Microsoft Explorer' mouse has these buttons available to the right thumb.
|
|
Currently X1 and X2 only work on Win32 and X11 environments.
|
|
|
|
Examples: >vim
|
|
:noremap <MiddleMouse> <LeftMouse><MiddleMouse>
|
|
Paste at the position of the middle mouse button click (otherwise the paste
|
|
would be done at the cursor position). >vim
|
|
|
|
:noremap <LeftRelease> <LeftRelease>y
|
|
Immediately yank the selection, when using Visual mode.
|
|
|
|
Note the use of ":noremap" instead of "map" to avoid a recursive mapping.
|
|
>vim
|
|
:map <X1Mouse> <C-O>
|
|
:map <X2Mouse> <C-I>
|
|
Map the X1 and X2 buttons to go forwards and backwards in the jump list, see
|
|
|CTRL-O| and |CTRL-I|.
|
|
|
|
*mouse-swap-buttons*
|
|
To swap the meaning of the left and right mouse buttons: >vim
|
|
: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>
|
|
<
|
|
vim:et:sw=2:tw=78:ts=8:ft=help:norl:
|