terminal.txt ForVim version 9.2. Last change: 2026 Feb 14VIM REFERENCE MANUAL by Bram MoolenaarTerminalwindow supportterminalterminal-windowTheterminal featureis optional, use this to check if your Vim has it:echo has('terminal')If the resultis "1" you have it.1. Basic useterminal-use Typingterminal-typing Size and colorterminal-size-color Commandsyntax:terminal Resizingterminal-resizing Terminal ModesTerminal-mode Cursor styleterminal-cursor-styleSessionterminal-sessionSpecial keysterminal-special-keysUnixterminal-unixMS-Windowsterminal-ms-windows2. Terminalfunctionsterminal-function-details3. Terminal communicationterminal-communication Vim to job:term_sendkeys()terminal-to-jobJob to Vim: JSON APIterminal-api Using theclient-server featureterminal-client-server4. Remotetestingterminal-testing5. Diffing screen dumpsterminal-diff Writinga screen dump test for Vimterminal-dumptest Creatinga screen dumpterminal-screendump Comparing screen dumpsterminal-diffscreendump6. Debuggingterminal-debug Startingtermdebug-starting Example sessiontermdebug-example Stepping through codetermdebug-stepping Inspectingvariablestermdebug-variables Navigating stack framestermdebug-frames Other commandstermdebug-commands Eventstermdebug-events Prompt modetermdebug-prompt Mappingstermdebug-mappings Communicationtermdebug-communication Remote Debuggingtermdebug-remote Customizingtermdebug-customizing{only available when compiled with the |+terminal| feature}Theterminal feature requires the+job and+channel features.==============================================================================1. Basic useterminal-useThis featureis for runningaterminal emulator ina Vim window.Ajob can bestarted connected to theterminal emulator. For example, to runa shell: :term bashOr to run build command: :term make myprogramThejob runs asynchronously from Vim, thewindow will be updated to showoutput from the job, also while editing in another window.Typingterminal-typingWhen the keyboard focusis in theterminal window, typed keys will be sent tothe job. This usesa pty when possible. You can click outside of theterminalwindow to move keyboard focus elsewhere.t_CTRL-W_CTRL-Wt_CTRL-W_:CTRL-W can be used to navigate betweenwindows and otherCTRL-W commands,e.g.:CTRL-WCTRL-Wmove focus to the nextwindowCTRL-W:enter anEx commandSeeCTRL-W for more commands.Special in theterminal window:t_CTRL-W_.t_CTRL-W_NCTRL-W.sendaCTRL-W to thejob in theterminalCTRL-WCTRL-\sendaCTRL-\ to thejob in theterminalCTRL-WNgo toTerminal-Normal mode, seeTerminal-modeCTRL-\CTRL-Ngo toTerminal-Normal mode, seeTerminal-modeCTRL-W "{reg} paste register{reg}t_CTRL-W_quoteAlso works with the= register toinsert the result ofevaluating an expression.CTRL-WCTRL-Cends the job, see belowt_CTRL-W_CTRL-CCTRL-Wgtgo to next tabpage, sameasgtt_CTRL-W_gtCTRL-WgTgo to previous tabpage, sameasgTt_CTRL-W_gTSee option'termwinkey' for specifying another key instead ofCTRL-W thatwill work likeCTRL-W. However, typing'termwinkey' twice sends'termwinkey'to the job. For example:'termwinkey'CTRL-W move focus to the nextwindow'termwinkey': enter anEx command'termwinkey''termwinkey' send'termwinkey' to thejob in theterminal'termwinkey'. send'termwinkey' to thejob in theterminal'termwinkey'CTRL-\ sendaCTRL-\ to thejob in theterminal'termwinkey'Ngo toterminalNormal mode, see below'termwinkey'CTRL-N sameasCTRL-WNt_CTRL-W_N'termwinkey'CTRL-C sameasCTRL-WCTRL-Ct_CTRL-W_CTRL-Ct_CTRL-\_CTRL-NThe special key combinationCTRL-\CTRL-N can be used to switch toNormalmode, just like this works in any other mode.t_CTRL-W_CTRL-CCTRL-WCTRL-C can be typed to forcefullyend the job. OnMS-WindowsaCTRL-Break will also kill the job.If you typeCTRL-C the effect depends on what the pty has been configured todo. For simple commands this causesa SIGINT to be sent to the job, whichwouldend it. Other commands may ignore the SIGINT or handle theCTRL-Cthemselves (like Vim does).To change the keys you type useterminal mode mappings, see:tmap.These are defined like any mapping, but apply only when typing keys that aresent to thejob running in the terminal. For example, to make F1 switchtoTerminal-Normal mode: tnoremap <F1> <C-W>NYou can use Esc, but you need to make sureit won't cause other keys tobreak (cursor keys start with an Esc, so they may break), this probably onlyworks in the GUI: tnoremap <Esc> <C-W>N set notimeout ttimeout timeoutlen=100You can also createmenus similar toterminal mode mappings, but you have touse:tlmenu instead of:tmenu.options-in-terminalAfter opening theterminalwindow and setting'buftype' to "terminal" theTerminalWinOpenautocommand eventis triggered. This makesit possible to setoptions specifically for theterminalwindow and buffer. Example: au TerminalWinOpen * setlocal bufhidden=hideThis only works properly if theterminalis not hidden.For both hidden and non-hidden terminals this works, both for buffer-local andwindow-local options: au TerminalWinOpen,BufWinEnter * if &buftype == 'terminal' \ | setlocal bufhidden=hide colorcolumn=123 \ | endifNote that fora hiddenterminal theoptions are not set until theterminalisno longer hidden.Thereis also theTerminalOpen event. Keep in mind this may be triggeredfora hidden terminal, then the currentwindow and buffer are not that of thenew terminal.You need to use<abuf>, whichis set to theterminal buffer. Example: au TerminalOpen * call setbufvar(expand('<abuf>')->str2nr(), \ '&termwinscroll', 1000)Fora window-local option, you need to delay setting the option until theterminalwindow has been created (this only works fora hidden terminal): au TerminalOpen * exe printf( \ 'au BufWinEnter <buffer=%d> ++once setlocal colorcolumn=%d', \ expand('<abuf>')->str2nr(), 123)Fora non-hiddenterminal useTerminalWinOpen.Mouse events (click and drag) are passed to the terminal. Mouse move eventsare only passed when Vim itselfis receiving them. Foraterminal thatiswhen'balloonevalterm'is enabled.Size and colorterminal-size-colorSee option'termwinsize' for controlling the size of theterminal window.(TODO:scrolling when theterminalis larger than the window)Thejob running in theterminal can change the colors. The default foregroundand background colors are taken from Vim, theNormal highlight group.Fora colorterminal the'background' optionis used to decide whether theterminalwindow will start witha white or black background.To usea different color the Terminal highlight group can be used, forexample: hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blueInstead of Terminal another group can be specified with the "term_highlight"option forterm_start().g:terminal_ansi_colorsInGUI mode or with'termguicolors', the 16 ANSI colors used by default in newterminalwindows may be configured using the variableg:terminal_ansi_colors, which should bealist of 16 color names orhexadecimal color codes, similar to those accepted byhighlight-guifg. Whennot usingGUI colors, theterminalwindow always uses the 16 ANSI colors ofthe underlying terminal.When usingterm_start() the colors can be set with the "ansi_colors" option.Theterm_setansicolors() function can be used to change the colors, andterm_getansicolors() to get the currently used colors.Command syntax:[range]ter[minal][options][command]:ter:terminalOpena newterminal window.If[command]is provided runitasajob and connectthe input and output to the terminal.If[command]is not given the'shell' optionis used.if[command]is NONE nojobis started, the pty of theterminal can be used bya command like gdb.If[command] outputs NUL bytes, those will beconverted to new linesNL-used-for-Nul.terminal-nospecialVim itself only recognizescmdline-specialcharacters inside[command]. Everything else will bepassed untouched. When needed to expand wildcards,environmentvariables or other shell specials considerterm++shell option.If[command]is missing the default behavioris toclose theterminal when the shell exits. This can bechanged with the ++noclose argument.If[command]is present the default behavioris tokeep theterminal open inTerminal-Normal mode. Thiscan be changed with the ++close argument.No Vim command can follow, any |is included in[command]. Use:execute if youmust havea Vimcommand following in the same line.terminal-bufnameA new buffer will be created, using[command] or'shell'as the name, prefixed witha "!". Ifa bufferby this name already existsa numberis added inparentheses. E.g. if "gdb" exists the secondterminalbuffer will use "!gdb (1)".If[range]is given the specified lines are usedasinput for the job. It will not be possible to typekeys in theterminal window. ForMS-Windows see the++eof argument below.term++closeterm++openSupported[options] are:++closeTheterminalwindow will closeautomatically when thejob terminates.terminal-close++nocloseTheterminalwindow will NOT closeautomatically when thejob terminates.++openWhen thejob terminates and nowindowshows it,awindow will be opened.Note that this can be interruptive.The last of ++close, ++noclose and ++openmatters and rules out earlier arguments.++curwinOpen theterminal in the currentwindow,do not split the currentwindow. Fails if the current buffercannot beabandoned.++hiddenOpen theterminal ina hidden buffer,nowindow will be used.++norestoreDo not include thisterminalwindowina session file.term++shell++shellInstead of executing{command}directly, usea shell, like with:!commandE279{only works on Unix and MS-Windows}The resulting command will look like'shell''shellcmdflag'[command]Otheroptions related to:!commandhave no effect.++kill={how}When trying to close theterminalwindow kill thejob with{how}. Seeterm_setkill() for the values.++rows={height} Use{height} for theterminalwindowheight. If theterminal uses the fullVim height (nowindow above or belowtheterminal window) the command lineheight will be reducedas needed.++cols={width} Use{width} for theterminalwindowwidth. If theterminal uses the fullVim width (nowindow left or right oftheterminal window) this valueisignored.++eof={text}When using[range]: text to send afterthe last line was written. Cannotcontain white space.A CRisappended. ForMS-Windows the defaultis to sendCTRL-D.E.g. fora shell use "++eof=exit" andforPython "++eof=exit()".Specialcodes can be used like with:map,e.g. "<C-Z>" forCTRL-Z.++type={pty}(MS-Windows only): Use{pty}as thevirtual console. See'termwintype'for the values.++api={expr}Permit the function namestarting with{expr} to be calledasterminal-apifunction. If{expr}is empty then nofunction can be called.If you want to use moreoptions use theterm_start()function.If you want to split thewindow vertically, use::vertical terminalOr short::vert terWhen the buffer associated with theterminalis forcibly unloaded or wiped outthejobis killed, similar to calling `job_stop(job, "kill")`.Closing thewindow normally results inE947. Whena killmethod was setwith "++kill={how}" orterm_setkill() then closing thewindow will use thatway to kill or interrupt the job. For example::term ++kill=term tail -f /tmp/logSo longas thejobis running thewindow behaves likeit containsa modifiedbuffer. Trying to close thewindow with `CTRL-W :quit` fails. When using`CTRL-W :quit!` thejobis ended. The text in thewindowis lost, the bufferis deleted. With `CTRL-W :bunload!` the buffer remains but will be empty.Trying to close thewindow with `CTRL-W :close` also fails. Using`CTRL-W :close!` will close thewindow and make the buffer hidden.You can use `CTRL-W :hide` to close theterminalwindow and make the bufferhidden, thejob keeps running. The:buffer command can be used to turn thecurrentwindow intoaterminal window. If there are unsaved changes thisfails, use! to force,as usual.terminal-closeWhen theterminaljob finishes and no[command] was given (e.g. the'shell'command was executed), theterminalwindow will be closed by default (unlessthe buffer in nextwindow receiving thespace has the'nobuflisted' optionset, in whichcase theterminalwindow would not be closed automatically, buta new empty buffer would be opened in that window).When theterminalwindowis closed, e.g. when the shell exits and "++close"argument was used, and thisis the last normal Vim window, then Vim will exit.Thisis like using:quit ina normal window. Help and previewwindows arenot counted.To havea backgroundjob run withouta window, and open thewindow when it'sdone, useoptions like this::term ++hidden ++open makeNote that thewindow will openat an unexpected moment, this will interruptwhat you are doing.E947E948So longas thejobis running, the bufferis considered modified and Vimcannot be quit easily, seeabandon.When thejob has finished and no changes were made to the buffer: closing thewindow will wipe out the buffer.Before changes can be made toaterminal buffer, the'modifiable' optionmustbe set. Thisis only possible when thejob has finished. At the first changethe buffer will becomea normal buffer and the highlightingis removed.You may want to change the buffer name with:file to be able to write, sincethe buffer name will still be set to the command.Resizingterminal-resizingThe size of theterminal can be in one of three modes:1. The'termwinsize' optionis empty: Theterminal size follows thewindow size. The minimal sizeis 2 screen lines with 10 cells.2. The'termwinsize' optionis "rows*cols", where "rows"is the minimal number of screen rows and "cols"is the minimal number of cells.3. The'termwinsize' optionis "rowsXcols" (where thexis upper or lower case). Theterminal sizeis fixed to the specified number of screen lines and cells. If thewindowis bigger there will be unused empty space.If thewindowis smaller than theterminal size, only part of theterminal canbe seen (the lower-left part).Theterm_getsize() function can be used to get the current size of theterminal.term_setsize() can be used only when in the first or second mode,not when'termwinsize'is "rowsXcols".Terminal-Job and Terminal-Normal modeTerminal-modeTerminal-JobWhen thejobis running the contents of theterminalis undercontrol of thejob. That includes the cursor position. Typed keys are sent to the job.Theterminal contents can changeat any time. Thisis calledTerminal-Jobmode.UseCTRL-WN (or'termwinkey' N) to switch toTerminal-Normal mode. Now thecontents of theterminalwindowis undercontrol of Vim, thejob outputissuspended.CTRL-\CTRL-N does the same.Terminal-Job modeis where:tmap mappings are applied. Keys sent byterm_sendkeys() are not subject to tmap, but keys fromfeedkeys() are.Itis not possible to enterInsert mode fromTerminal-Job mode.Terminal-NormalE946InTerminal-Normal mode you can move the cursor around with the usual Vimcommands, Visuallymark text,yank text, etc. But you cannot change thecontents of the buffer. The commands that would startinsert mode, suchas'i' and 'a', return toTerminal-Job mode. Thewindow will be updated to showthe contents of the terminal.:startinsertis ineffective.InTerminal-Normal mode the statusline andwindow title show "(Terminal)". Ifthejob ends while inTerminal-Normal mode this changes to"(Terminal-finished)".When thejob outputs lines in the terminal, such that the contents scrolls offthe top, those lines are remembered and can be seen inTerminal-Normal mode.The number of linesis limited by the'termwinscroll' option. When going overthis limit, the first 10% of the scrolled lines are deleted and are lost.Cursor styleterminal-cursor-styleBy default the cursor in theterminalwindow usesa not blinking block. Thenormal xtermescape sequences can be used to change the blinking state and theshape. Once focus leaves theterminalwindow Vim will restore the originalcursor.An exceptionis when xtermis started with the "-bc" argument, or another waythat causes the cursor to blink. This actually means that the blinking flagis inverted. Since Vim cannot detect this, theterminalwindow cursorblinking will also be inverted.Sessionterminal-sessionAterminalwindow will be restored when usinga session file, if possible andwanted.If "terminal" was removed from'sessionoptions' then noterminalwindows willbe restored.If thejob in theterminal was finished thewindow will not be restored.If theterminal can be restored, the command that was used to openit will beused again. To change this use theterm_setrestore() function. This canalso be used to not restorea specificterminal by setting the command to"NONE".Special keysterminal-special-keysSince theterminal emulator simulates an xterm, onlyescape sequences thatboth Vim and xterm recognize will be available in theterminal window. If youwant to pass on otherescape sequences to thejob running in theterminal youneed to set up forwarding. Example:tmap <expr> <Esc>]b SendToTerm("\<Esc>]b")func SendToTerm(what) call term_sendkeys('', a:what) return ''endfuncUnixterminal-unixOnUnixa ptyis used to makeit possible to run all kinds of commands. Youcan even run Vim in the terminal! That's used for debugging, see below.Environmentvariables are used to pass information to the running job:TERMthe name of the terminal, from the'term' option or$TERM in the GUI; falls back to "xterm" ifit does notstart with "xterm" ROWSnumber of rows in theterminal initially LINESsameas ROWS COLUMNSnumber of columns in theterminal initially COLORSnumber of colors,'t_Co' (256*256*256 in the GUI) VIM_SERVERNAMEv:servername VIM_TERMINALv:versionMS-Windowsterminal-ms-windowsOnMS-Windows winptyis used to makeit possible to run all kind of commands.Obviously, theymust be commands that run ina terminal, not open their ownwindow.You need the following two files from winpty: winpty.dll winpty-agent.exeYou candownload them from the following page:https://github.com/rprichard/winptyJustput the files somewhere in your PATH. You can set the'winptydll' optionto point to the right file, if needed. If you have both the 32-bit and 64-bitversion, rename to winpty32.dll and winpty64.dll to match the way Vim wasbuild.ConPTYE982On more recent versions ofMS-Windows 10 (beginning with the "October 2018Update"), winptyis no longer required. On those versions,:terminal will useWindows' built-in support for hostingterminal applications, "ConPTY". WhenConPTYis in use, there may be rendering artifacts regarding ambiguous-widthcharacters. If you encounter any such issues,install "winpty". Until theConPTY problems have been fixed "winpty" will be preferred.Environmentvariables are used to pass information to the running job: VIM_SERVERNAMEv:servernamegit-vimdumpsThere existsa git-difftool extension calledgit-vimdumps that can be usedto conveniently inspect screendump files anddiff them. Please see in the VimRepository the filesrc/testdir/commondumps.vim on how to create and usethis git extension.==============================================================================2. Terminalfunctionsterminal-function-detailsterm_dumpdiff()term_dumpdiff({filename},{filename} [,{options}])Opena newwindow displaying the difference between the twofiles. The filesmust have been created withterm_dumpwrite().Returns the buffer number or zero when thediff fails.Also seeterminal-diff.NOTE: this does not work with double-width characters yet.The top part of the buffer contains the contents of the firstfile, the bottom part of the buffer contains the contents ofthe second file. The middle part shows the differences.The parts are separated bya line of equals.If the{options} argumentis present,itmust beaDict withthese possible members: "term_name" name to use for the buffer name, instead of the first file name. "term_rows" vertical size to use for the terminal, instead of using'termwinsize', but respecting the minimal size; valid rangeis from0 to 1000 "term_cols" horizontal size to use for the terminal, instead of using'termwinsize', but respecting the minimal size; valid rangeis from0 to 1000 "vertical" split thewindow vertically "curwin" use the current window,do not split the window; fails if the current buffer cannot beabandoned "bufnr"do not createa new buffer, use the existing buffer "bufnr". This buffermust have been previously created withterm_dumpdiff() orterm_dumpload() and visible ina window. "norestore"do not add theterminalwindow toa session fileEach character in the middle part indicatesa difference. Ifthere are multiple differences only the first in thislistisused:Xdifferent characterwdifferent widthfdifferent foreground colorbdifferent background coloradifferent attribute+missing position in first file-missing position in second file>cursor position in first file, not in second<cursor position in second file, not in firstUsing the "s" key the top and bottom parts are swapped. Thismakesiteasy to spota difference.Can also be usedasamethod:GetFilename()->term_dumpdiff(otherfile)Return type:Numberterm_dumpload({filename} [,{options}])term_dumpload()Opena newwindow displaying the contents of{filename}The filemust have been created withterm_dumpwrite().Returns the buffer number or zero whenit fails.Also seeterminal-diff.For{options} seeterm_dumpdiff().Can also be usedasamethod:GetFilename()->term_dumpload()Return type:Numberterm_dumpwrite({buf},{filename} [,{options}])term_dumpwrite()Dump the contents of theterminal screen of{buf} in the file{filename}. This usesa format that can be used withterm_dumpload() andterm_dumpdiff().If thejob in theterminal already finished an erroris given:E958If{filename} already exists an erroris given:E953Also seeterminal-diff.{options}isa dictionary with these optional entries:"rows"maximum number of rows to dump"columns"maximum number of columns to dumpCan also be usedasamethod, the baseis used for the filename:GetFilename()->term_dumpwrite(bufnr)Return type:Numberterm_getaltscreen({buf})term_getaltscreen()Returns 1 if theterminal of{buf}is using the alternatescreen.{buf}is usedas withterm_getsize().Can also be usedasamethod:GetBufnr()->term_getaltscreen()Return type:Numberterm_getansicolors({buf})term_getansicolors()Get the ANSI color palette in use byterminal{buf}.ReturnsaList of length 16 where each elementisaStringrepresentinga color in hexadecimal "#rrggbb" format.Also seeterm_setansicolors() andg:terminal_ansi_colors.If neither was used returns the default colors.{buf}is usedas withterm_getsize(). If the buffer does notexist oris notaterminal window, an emptylistis returned.Can also be usedasamethod:GetBufnr()->term_getansicolors()Return type: list<string> or list<any>{only available when compiled withGUI enabled and/or the+termguicolors feature}term_getattr({attr},{what})term_getattr()Given{attr},a value returned byterm_scrape() in the "attr"item, return whether{what}is on.{what} can be one of:bolditalicunderlinestrikereverseCan also be usedasamethod:GetAttr()->term_getattr()Return type:Numberterm_getcursor({buf})term_getcursor()Get the cursor position ofterminal{buf}. Returnsalistwith two numbers anda dictionary: [row, col, dict]."row" and "col" are one based, the first screen cellis row1, column 1. Thisis the cursor position of theterminalitself, not of the Vim window."dict" can have these members: "visible"one when the cursoris visible, zero whenitis hidden. "blink"one when the cursoris blinking, zero whenitis not blinking. "shape"1 fora block cursor, 2 forunderline and 3fora vertical bar. "color"color of the cursor, e.g. "green"{buf}must be the buffer number ofaterminal window. If thebuffer does not exist oris notaterminal window, an emptylistis returned.Can also be usedasamethod:GetBufnr()->term_getcursor()Return type: list<any>term_getjob({buf})term_getjob()Get theJob associated withterminalwindow{buf}.{buf}is usedas withterm_getsize().Returnsv:null when thereis no job. InVim9 script, returnnull_job when thereis no job.Can also be usedasamethod:GetBufnr()->term_getjob()Return type:jobterm_getline({buf},{row})term_getline()Geta line of text from theterminalwindow of{buf}.{buf}is usedas withterm_getsize().The first line has{row} one. When{row}is "." the cursorlineis used. When{row}is invalid an emptystringisreturned.To get attributes of each character useterm_scrape().Can also be usedasamethod:GetBufnr()->term_getline(row)Return type:Stringterm_getscrolled({buf})term_getscrolled()Return the number of lines that scrolled to above the top ofterminal{buf}. Thisis the offset between the row numberused forterm_getline() andgetline(), so that:term_getline(buf, N)is equal to:getline(N + term_getscrolled(buf))(if that line exists).{buf}is usedas withterm_getsize().Can also be usedasamethod:GetBufnr()->term_getscrolled()Return type:Numberterm_getsize({buf})term_getsize()Get the size ofterminal{buf}. Returnsalist with twonumbers: [rows, cols]. Thisis the size of the terminal, notthewindow containing the terminal.{buf}must be the buffer number ofaterminal window. Use anemptystring for the current buffer. If the buffer does notexist oris notaterminal window, an emptylistis returned.Can also be usedasamethod:GetBufnr()->term_getsize()Return type: list<number> or list<any>term_getstatus({buf})term_getstatus()Get the status ofterminal{buf}. This returnsaString witha comma-separatedlist of these items:runningjobis runningfinishedjob has finishednormalinTerminal-Normal modeOne of "running" or "finished"is always present.{buf}must be the buffer number ofaterminal window. If thebuffer does not exist oris notaterminal window, an emptystringis returned.Can also be usedasamethod:GetBufnr()->term_getstatus()Return type:Stringterm_gettitle({buf})term_gettitle()Get the title ofterminal{buf}. Thisis the title that thejob in theterminal has set.{buf}must be the buffer number ofaterminal window. If thebuffer does not exist oris notaterminal window, an emptystringis returned.Can also be usedasamethod:GetBufnr()->term_gettitle()Return type:Stringterm_gettty({buf} [,{input}])term_gettty()Get the name of the controllingterminal associated withterminalwindow{buf}.{buf}is usedas withterm_getsize().When{input}is omitted or 0, return the name forwriting(stdout). When{input}is 1 return the name for reading(stdin). On UNIX, both return same name.Can also be usedasamethod:GetBufnr()->term_gettty()Return type:Stringterm_list()term_list()Returnalist with the buffer numbers of allbuffers forterminal windows.Return type: list<number> or list<any>term_scrape({buf},{row})term_scrape()Get the contents of{row} ofterminal screen of{buf}.For{buf} seeterm_getsize().The first line has{row} one. When{row}is "." the cursorlineis used. When{row}is invalid an emptystringisreturned.ReturnaList containingaDict for each screen cell: "chars"character(s)at the cell "fg"foreground coloras #rrggbb "bg"background coloras #rrggbb "attr"attributes of the cell, useterm_getattr()to get the individual flags "width"cell width: 1 or 2Fora double-width cell thereis one item, thus thelist canbe shorter than the width of the terminal.Can also be usedasamethod:GetBufnr()->term_scrape(row)Return type: list<dict<any>> or list<any>term_sendkeys({buf},{keys})term_sendkeys()Send keystrokes{keys} toterminal{buf}.{buf}is usedas withterm_getsize().{keys} are translatedas key sequences. For example, "\<c-x>"means the characterCTRL-X.Can also be usedasamethod:GetBufnr()->term_sendkeys(keys)Return type:Numberterm_setansicolors({buf},{colors})term_setansicolors()Set the ANSI color palette used byterminal{buf}.{colors}must beaList of 16 valid color names or hexadecimalcolor codes, like those accepted byhighlight-guifg.Also seeterm_getansicolors() andg:terminal_ansi_colors.The colors normally are:0 black1 dark red2 dark green3 brown4 dark blue5 dark magenta6 dark cyan7 light grey8 dark grey9 red10 green11 yellow12 blue13 magenta14 cyan15 whiteThese colors are used in theGUI and in theterminal when'termguicolors'is set. When not usingGUI colors (GUI modeor'termguicolors'), theterminalwindow always uses the 16ANSI colors of the underlying terminal.Can also be usedasamethod:GetBufnr()->term_setansicolors(colors)Return type:Number{only available withGUI enabled and/or the+termguicolorsfeature}term_setapi({buf},{expr})term_setapi()Set the function name prefix to be used for theterminal-apifunction interminal{buf}. For example: :call term_setapi(buf, "Myapi_") :call term_setapi(buf, "")The defaultis "Tapi_". When{expr}is an emptystring thennoterminal-api function can be used for{buf}.When usedasamethod the baseis used for{buf}:GetBufnr()->term_setapi({expr})Return type:Numberterm_setkill({buf},{how})term_setkill()Whenexiting Vim or trying to close theterminalwindow inanother way,{how} defines whether thejob in theterminal canbe stopped.When{how}is empty (the default), thejob will not bestopped, trying to exit will result inE947.Otherwise,{how}specifies what signal to send to the job.Seejob_stop() for the values.After sending the signal Vim will wait for up toa second tocheck that thejob actually stopped.Can also be usedasamethod:GetBufnr()->term_setkill(how)Return type:Numberterm_setrestore({buf},{command})term_setrestore()Set the command to write ina session file to restore thejobin this terminal. The line written in the session file is:terminal ++curwin ++cols=%d ++rows=%d {command}Make sure toescape the command properly.Use an empty{command} to run'shell'.Use "NONE" to not restore this window.Can also be usedasamethod:GetBufnr()->term_setrestore(command)Return type:Numberterm_setsize({buf},{rows},{cols})term_setsize()E955Set the size ofterminal{buf}. The size of thewindowcontaining theterminal will also be adjusted, if possible.If{rows} or{cols}is zero or negative, that dimensionis notchanged.{buf}must be the buffer number ofaterminal window. Use anemptystring for the current buffer. If the buffer does notexist oris notaterminal window, an erroris given.Can also be usedasamethod:GetBufnr()->term_setsize(rows, cols)Return type:Numberterm_start({cmd} [,{options}])term_start()Openaterminalwindow and run{cmd} in it.{cmd} can beastring ora List, like withjob_start(). Thestring "NONE" can be used to openaterminalwindow withoutstartinga job, the pty of theterminal can be used byacommand like gdb.Returns the buffer number of theterminal window. If{cmd}cannot be executed thewindow does open and shows an errormessage.If opening thewindow fails zerois returned.{options} are similar to whatis used forjob_start(), seejob-options. However, not alloptions can be used. Theseare supported: all timeoutoptions "stoponexit", "cwd", "env" "callback", "out_cb", "err_cb", "exit_cb", "close_cb" "in_io", "in_top", "in_bot", "in_name", "in_buf" "out_io", "out_name", "out_buf", "out_modifiable", "out_msg" "err_io", "err_name", "err_buf", "err_modifiable", "err_msg"However,at least one of stdin, stdout or stderrmust beconnected to the terminal. When I/Ois connected to theterminal then the callback function for that partis not used.There are extra options: "term_name" name to use for the buffer name, instead of the command name. "term_rows" vertical size to use for the terminal, instead of using'termwinsize'; valid rangeis from0 to 1000 "term_cols" horizontal size to use for the terminal, instead of using'termwinsize'; valid rangeis from0 to 1000 "vertical" split thewindow vertically;note that otherwindow position can be defined with command modifiers, suchas:belowright. "curwin" use the current window,do not split the window; fails if the current buffer cannot beabandoned "hidden"do not openawindow "norestore"do not add theterminalwindow toa session file "term_kill" what todo when trying to close theterminal window, seeterm_setkill() "term_finish" What todo when thejobis finished:"close": close anywindows"open": openwindow if neededNote that "open" can be interruptive. Seeterm++close andterm++open. "term_opencmd" command to use for opening thewindow when "open"is used for "term_finish";must have "%d" where the buffer number goes, e.g. "10split|buffer %d"; when not specified "botright sbuf %d"is used "term_highlight" highlight group to use instead of "Terminal" "eof_chars" Text to send after all buffer lines were written to the terminal. When not setCTRL-Dis used on MS-Windows. ForPython useCTRL-Z or "exit()". Fora shell use "exit".A CRis always added. "ansi_colors"Alist of 16 color names or hex codes defining the ANSI palette used inGUI color modes. Seeg:terminal_ansi_colors. "tty_type" (MS-Windows only): Specify which pty to use. See'termwintype' for the values. "term_api" function name prefix for theterminal-api function. Seeterm_setapi().Can also be usedasamethod:GetCommand()->term_start()Return type:Numberterm_wait({buf} [,{time}])term_wait()Wait for pending updates of{buf} to be handled.{buf}is usedas withterm_getsize().{time}is how long to wait for updates to arrive in msec. Ifnot set then 10 msec will be used. Queuedmessages will alsobe processed similar to:sleep.Can also be usedasamethod:GetBufnr()->term_wait()Return type:Number==============================================================================3. Terminal communicationterminal-communicationThere are several ways to communicate with thejob running ina terminal:- Useterm_sendkeys() to send text andescape sequences from Vim to the job.- Use the JSON API to send encoded commands from thejob to Vim.- Use theclient-server mechanism. This works on machines with anX server and on MS-Windows.Vim to job: term_sendkeys()terminal-to-jobThis allows for remote controlling thejob running in the terminal. Itisaone-way mechanism. Thejob can update the display to signal back to Vim.For example, ifa shellis running ina terminal, you can do:call term_sendkeys(buf, "ls *.java\<CR>")This requires for thejob to be in the right state whereit willdo the rightthing when receiving the keys. For the above example, the shellmust bewaiting fora command to be typed.Forajob that was written for the purpose, you can use the JSON APIescapesequence in the other direction. E.g.:call term_sendkeys(buf, "\<Esc>]51;["response"]\x07")Job to Vim: JSON APIterminal-apiThejob can send JSON to Vim, usinga specialescape sequence. The JSONencodesa command that Vim understands. Example of sucha message:<Esc>]51;["drop", "README.md"]<07>The bodyis alwaysa list, makingiteasy to find the end: ]<07>.The<Esc>]51;msg<07> sequenceis reserved by xterm for "Emacs shell", whichissimilar to what we are doing here.Currently supported commands:call{funcname}{argument}Calla user defined function with{argument}.The functionis called with two arguments: the buffer numberof theterminal and{argument}, the decoded JSON argument.By default, the function namemust start with "Tapi_" to avoidaccidentally callinga function not meant to be used for theterminal API. This can be changed withterm_setapi().The user function should sanity check the argument.The function can useterm_sendkeys() to send backa reply.Example in JSON:["call", "Tapi_Impression", ["play", 14]]Callsa function defined like this:function Tapi_Impression(bufnum, arglist) if len(a:arglist) == 2 echomsg "impression " .. a:arglist[0] echomsg "count " .. a:arglist[1] endifendfuncOutput from:echo may be erased bya redraw, use:echomsgto be able to seeit with:messages.drop{filename}[options]Let Vim opena file, like the:drop command. If{filename}is already open ina window, switch to that window. Otherwiseopena newwindow to edit{filename}.Note that both thejob and Vim may change the currentdirectory, thus it's best to use the full path.[options]is only used when openinga new window. If present,itmust bea Dict. Similarly to++opt, these entries arerecognized: "ff"file format: "dos", "mac" or "unix" "fileformat"idem "enc"overrides'fileencoding' "encoding"idem "bin"sets'binary' "binary"idem "nobin"resets'binary' "nobinary"idem "bad"specifies behavior for bad characters, see++badExample in JSON:["drop", "path/file.txt", {"ff": "dos"}]You can useechoraw() to make Vim send thisescape sequence:call echoraw("\<ESC>]51;[\"call\", \"Tapi_TryThis\", [\"hello\", 123]]\x07")call echoraw("\<Esc>]51;[\"drop\", \"README.md\"]\x07")Note: JSON requires doublequotes aroundstring values, hence those have to beescaped.Rationale: Why not allow for any command or expression? Because that mightcreatea security problem.terminal-autoshelldirThis can be used to pass the current directory froma shell to Vim.Put this in your .vimrc:def g:Tapi_lcd(_, path: string) if isdirectory(path)execute 'silent lcd ' .. fnameescape(path) endifenddefAnd, ina bash init file:if [[ -n "$VIM_TERMINAL" ]]; then PROMPT_COMMAND='_vim_sync_PWD' function _vim_sync_PWD() {printf '\033]51;["call", "Tapi_lcd", "%q"]\007' "$PWD" }fiOr, for zsh:if [[ -n "$VIM_TERMINAL" ]]; then autoload -Uz add-zsh-hook add-zsh-hook -Uz chpwd _vim_sync_PWD function _vim_sync_PWD() {printf '\033]51;["call", "Tapi_lcd", "%q"]\007' "$PWD" }fiOr, for fish:if test -n "$VIM_TERMINAL" function _vim_sync_PWD --on-variable=PWDprintf '\033]51;["call", "Tapi_lcd", "%s"]\007' "$PWD" endendUsing the client-server featureterminal-client-serverThis only works whenv:servernameis not empty. If needed you can set it,before opening the terminal, with:call remote_startserver('vim-server')$VIM_SERVERNAMEis set in theterminal to pass on the server name.In thejob you can thendo something like:vim --servername $VIM_SERVERNAME --remote +123 some_file.cThis will open the file "some_file.c" andput the cursor on line 123.==============================================================================4. Remotetestingterminal-testingMost Vim tests executeascript inside Vim. For some tests this does notwork, running the test interferes with the code being tested. To avoid thisVimis executed inaterminal window. The test sends keystrokes toit andinspects the resulting screen state.Functionsterm_sendkeys() send keystrokes toaterminal (not subject to tmap)term_wait() wait for screen to be updatedterm_scrape() inspectterminal screen==============================================================================5. Diffing screen dumpsterminal-diffIn some casesit can be bothersome to test that Vim displays the rightcharacters on the screen. E.g. withsyntax highlighting. To make thissimpleritis possible to takea screen dump ofaterminal and compareit toan expected screen dump.Vim uses thewindow size, text, color and other attributesas displayed. TheVim screen size, font and other propertiesdo not matter. Therefore thismechanismis portable across systems.A conventional screenshot would reflectall differences, including font size and family.Writing a screen dump test for Vimterminal-dumptestFor an example see the Test_syntax_c() function insrc/testdir/test_syntax.vim. The main parts are:- Writea file you want to test with. Thisis useful fortestingsyntax highlighting. You can also start Vim with an empty buffer.- Run Vim inaterminal witha specific size. The defaultis 20 lines of 75 characters. This makes sure the dumpis always this size. The function RunVimInTerminal() takes care of this. Passit the arguments for the Vim command.- Send any commands to Vim usingterm_sendkeys(). For example:call term_sendkeys(buf, ":echo &lines &columns\<CR>")- Check that the screenis now in the expected state, using VerifyScreenDump(). This expects thereference screen dump to be in the src/testdir/dumps/ directory. Pass the name without ".dump". Itis recommended to use the name of the test function anda sequence number, so that we know what testis using the file.- Repeat sending commands and checking the state.- Finally stop Vim by calling StopVimInTerminal().The first time youdo this you won't havea screen dump yet. Create an emptyfile for now, e.g.:touch src/testdir/dumps/Test_function_name_01.dumpThe test will then fail, giving you the command to compare thereference dumpand the failed dump, e.g.:call term_dumpdiff("failed/Test_func.dump", "dumps/Test_func.dump")Use this command in Vim, with the current directory set to src/testdir.Once you are satisfied with the test, move the failed dump in place of thereference::!mv failed/Test_func.dump dumps/Test_func.dumpCreating a screen dumpterminal-screendumpTo create the screen dump, run Vim (or any other program) inaterminal andmakeit show the desired state. Then use theterm_dumpwrite() function tocreatea screen dump file. For example::call term_dumpwrite(77, "mysyntax.dump")Here "77"is the buffer number of the terminal. Use:ls! to see it.You canview the screen dump withterm_dumpload()::call term_dumpload("mysyntax.dump")To verify that Vim still shows exactly the same screen, run Vim again withexactly the same way to show the desired state. Then createa screen dumpagain, usinga different file name::call term_dumpwrite(88, "test.dump")To assert that the files are exactly the same useassert_equalfile():call assert_equalfile("mysyntax.dump", "test.dump")If there are differences thenv:errors will contain the error message.Comparing screen dumpsterminal-diffscreendumpassert_equalfile() does not makeiteasy to see whatis different.To spot the problem useterm_dumpdiff():call term_dumpdiff("mysyntax.dump", "test.dump")This will openawindow consisting of three parts:1. The contents of the first dump2. The difference between the first and second dump3. The contents of the second dumpYou can usually see what differs in the second part. Use the'ruler' torelateit to the position in the first or second dump. Letters indicate thekind of difference:Xdifferent character>cursor in first but not in second<cursor in second but not in firstwcharacter width differs (single vs double width)fforeground color differsbbackground color differsaattribute differs (bold, underline, reverse, etc.)?character missing in both+character missing in first-character missing in secondAlternatively, press "s" to swap the first and second dump. Do this severaltimes so that you can spot the difference in the context of the text.==============================================================================6. Debuggingterminal-debugterminal-debuggerpackage-termdebugtermdebugThe Terminal debuggingplugin can be used to debuga program withgdb andviewthe source code ina Vim window. Since thisis completely contained insideVim this also works remotely over an ssh connection.When the+terminal featureis missing, theplugin will use the "prompt"buffer type, if possible. The running program will then usea newly openedterminal window. Seetermdebug-prompt below for details.Startingtermdebug-startingLoad theplugin with this command:packadd termdebugWhen loading theplugin from the.vimrc file, add the "!" attribute:packadd! termdebug:TermdebugTo start debugging use:Termdebug or:TermdebugCommand followed by thecommand name, for example::Termdebug vimThis opens two windows:gdbwindowAterminalwindow in which "gdb vim"is executed. Here youcan directly interact with gdb. The buffer nameis "!gdb".programwindowAterminalwindow for the executed program. When "run"isused ingdb the program I/O will happen in this window, sothatit does not interfere with controlling gdb. The buffernameis "debugged program".The currentwindowis used to show the source code. Whengdb pauses thesource file location will be displayed, if possible.A signis used tohighlight the current position, using highlight group debugPC.If the buffer in the currentwindowis modified, anotherwindow will be openedto display the currentgdb position. You can use:Winbar to addawindowtoolbar there.Focus theterminal of the executed program to interact with it. This worksthe sameas any command running inaterminal window.When the debugger ends, typically by typing "quit" in thegdb window, the twoopenedwindows are closed.Only one debugger can be activeata time.termdebug-timeoutDepending on howgdbis launched,termdebugstartup time may vary.To avoidtermdebug to get stuck if thestartup process ofgdb takes too long,a configurable timeoutis included. Such time outis configurable in terms ofmultiple of 10ms: let g:termdebug_config['timeout'] = 500 # 500 * 10ms = 5 seconds.The default timeoutis 3000 ms.:TermdebugCommandIf you want to give specific commands to the command being debugged, you canuse the:TermdebugCommand command followed by the command name andadditional parameters.:TermdebugCommand vim --clean -c ':set nu'Both the:Termdebug and:TermdebugCommand support an optional "!" bangargument to start the command right away, without pausingat thegdbwindow(and cursor will be in the debugged window). For example::TermdebugCommand! vim --cleanTo attachgdb to an already running executable or usea core file, pass extraarguments. E.g.::Termdebug vim core:Termdebug vim 98343If no argumentis given, you'llend up inagdb window, in which you need tospecify which command to run using e.g. thegdbfile command.Example sessiontermdebug-exampleStart in the Vim "src" directory and build Vim:% makeMake sure that debug symbols are present, usually that means that $CFLAGSincludes "-g".Start Vim:% ./vimLoad thetermdebugplugin and start debugging Vim::packadd termdebug:Termdebug vimYou should now have three windows: source- where you started, hasawindow toolbar with buttonsgdb- you can typegdb commands here program- the executed program will use thiswindowYou can useCTRL-WCTRL-W or the mouse to move focus between windows.Put focus on thegdbwindow and type:break ex_helprunVim will start running in the program window. Put focus there and type::help guiGdb will run into the ex_help breakpoint. The sourcewindow now shows theex_cmds.c file.A red "1 " marker will appear in the signcolumn where thebreakpoint was set. The line where the debugger stoppedis highlighted. Youcan now step through the program. Let's use the mouse: click on the "Next"button in thewindow toolbar. You will see the highlighting moveas thedebugger executesa line of source code.Click "Next"a few times until the for loopis highlighted. Put the cursor ontheend of "eap->arg", then click "Eval" in the toolbar. You will see thisdisplayed:"eap->arg": 0x555555e68855 "gui"This way you can inspect the value of local variables. You can also focus thegdbwindow and usea "print" command, e.g.:print *eapIf mouse pointer movements are working, Vim will also showa balloon when themouse rests on text that can be evaluated by gdb.Nowgo back to the sourcewindow andput the cursor on the first line afterthe for loop, then type::BreakYou will seea ">>" marker appear, this indicates the new breakpoint. Nowclick "Cont" in the toolbar and the code until the breakpoint will beexecuted.You can type more advanced commands in thegdb window. For example, type:watch curbufNow click "Cont" in the toolbar (or type "cont" in thegdb window). Executionwill now continue until the value of "curbuf" changes, whichis in do_ecmd().To remove this watchpoint again type in thegdb window:delete 3You can see the stack by typing in thegdb window:whereMove through the stack frames, e.g. with:frame 3The sourcewindow will show the code,at the point where the call was made toa deeper level.Stepping through codetermdebug-steppingPut focus on thegdbwindow to type commands there. Some common ones are:-CTRL-Cinterrupt the program- nextexecute the current line and stopat the next line- stepexecute the current line and stopat the next statement,enteringfunctions- untilexecute until past the current cursor line or pasta specifiedposition or the current stack frame returns- finishexecute until leaving the current function- whereshow the stack- frameNgo to the Nth stack frame- continuecontinue execution:Run:ArgumentsIn thewindow showing the source code these commands can be used tocontrolgdb::Run[args] run the program with[args] or the previous arguments:Arguments{args} set arguments for the next:Run:Break seta breakpointat the cursor position:Break{position}seta breakpointat the specified position:Tbreak seta temporary breakpointat the cursor position:Tbreak{position}seta temporary breakpointat the specified position:Clear delete the breakpointat the cursor position:ToggleBreak seta breakpointat the cursor position or delete allbreakpointsat the cursor position:Step execute thegdb "step" command:Over execute thegdb "next" command (`:Next`isa Vim command):Until execute thegdb "until" command:Finish execute thegdb "finish" command:Continue execute thegdb "continue" command:RunOrContinue execute thegdb "continue" command if programis running,otherwise run the program:Stop interrupt the programIf'mouse'is set theplugin addsawindow toolbar with these entries: Step:Step Next:Over Finish:Finish Cont:Continue Stop:Stop Eval:EvaluateThis way you can use the mouse to perform the most common commands. You needto have the'mouse' option set to enable mouse clicks.Seetermdebug_winbar for configuring this toolbar.:WinbarYou can add thewindow toolbar in otherwindows you open with: :WinbarIfgdb stopsata source line and thereis nowindow currently showing thesource code,a newwindow will be created for the source code. This alsohappens if the buffer in the source codewindow has been modified and can't beabandoned.Gdb gives each breakpointa number. In Vim the number shows up in the signcolumn, witha red background. You can use thesegdb commands:- info breaklist breakpoints- deleteNdelete breakpointNYou can also use the:Clear command if the cursoris in the line with thebreakpoint, or use the "Clear breakpoint" right-click menu entry.Inspecting variablestermdebug-variables:Evaluate:Evaluate evaluate theexpression under the cursorK same (seetermdebug_map_K to disable):Evaluate{expr} evaluate{expr}:'<,'>Evaluate{Visual}K evaluate the Visually selected textThisis similar to using "print" in thegdb window.You can usually shorten:Evaluate to:Ev.Navigating stack framestermdebug-frames:Frame:Up:Down:Frame[frame] select frame[frame], whichisa frame number,address, or function name (default: current frame):Up[count]go up[count] frames (default: 1; the frame thatcalled the current)+ same (seetermdebug_map_plus to disable):Down[count]go down[count] frames (default: 1; the frame calledby the current)- same (seetermdebug_map_minus to disable)Other commandstermdebug-commands:Gdb jump to thegdbwindow:Program jump to thewindow with the running program:Source jump to thewindow with the source code, createit if there isn't one:Asm jump to thewindow with the disassembly, createit if there isn't one:Var jump to thewindow with the local and argument variables, createit if there isn't one. Thiswindow updates whenever the programis stoppedEventstermdebug-eventsFourautocommands can be used:au User TermdebugStartPre echomsg 'debugging starting'au User TermdebugStartPost echomsg 'debugging started'au User TermdebugStopPre echomsg 'debugging stopping'au User TermdebugStopPost echomsg 'debugging stopped'TermdebugStartPreTermdebugStartPreBeforestarting debugging.Not triggered if the debuggeris alreadyrunning or the debugger command cannot beexecuted.TermdebugStartPostTermdebugStartPostAfter debugging has initialized.Ifa "!" bangis passed to:Termdebug or:TermdebugCommand the eventis triggeredbefore running the provided command in gdb.TermdebugStopPreTermdebugStopPreBefore debugging ends, whengdbis terminated,most likely after issuinga "quit" command inthegdb window.TermdebugStopPostTermdebugStopPostAfter debugging has ended, gdb-relatedwindowsare closed, debugbuffers wiped out andthe state before the debugging was restored.Customizingtermdebug-customizingg:termdebug_configIn the past several globalvariables were used for configuration. These aredeprecated and using theg:termdebug_config dictionaryis preferred. Wheng:termdebug_config exists the other globalvariables will NOT be used.The recommended wayis to start with an empty dictionary:let g:termdebug_config = {}Then you can add entries to the dictionaryas mentioned below. Thedeprecated global variable names are mentioned for completeness. If you areswitching over to usingg:termdebug_config you can find the old variable nameand take over the value, then delete the deprecated variable.Prompt modetermdebug-promptWhen the+terminal featureis not supported and on MS-Windows,gdb will runina buffer with'buftype' set to "prompt". This works slightly differently:- Thegdbwindow will be inInsert mode while typing commands. Go toNormal mode with<Esc>, then you can move around in the buffer, copy/paste, etc. Go back to editing thegdb command with any command that startsInsert mode, suchasa ori.- The program being debugged will run ina separate window. OnMS-Windows thisisa new console window. On Unix, if the+terminal featureis availablea Terminalwindow will be opened to run the debugged program in.termdebug_use_promptPrompt mode can be used even when the+terminal featureis present with:let g:termdebug_config['use_prompt'] = v:trueIf thereis nog:termdebug_config you can use:let g:termdebug_use_prompt = v:trueHowever, the latter form will be deprecated in future releases.MappingsThetermdebugplugin enablesa few default mappings. All those mappingsare reset to their original values once thetermdebug session concludes.termdebug_map_Ktermdebug-mappingsTheK keyis normally mapped to:Evaluate unlessa buffer local(:map-local)mapping toK already exists. If youdo not want this use:let g:termdebug_config['map_K'] = v:falseIf thereis nog:termdebug_config you can use:let g:termdebug_map_K = v:falseHowever, the latter form will be deprecated in future releases.termdebug_map_minusThe- keyis normally mapped to:Down unlessa buffer localmapping to the-key already exists. If youdo not want this use:let g:termdebug_config['map_minus'] = v:falsetermdebug_map_plusThe+ keyis normally mapped to:Up unlessa buffer localmapping to the+key already exists. If youdo not want this use:let g:termdebug_config['map_plus'] = v:falsetermdebug_disasm_windowIf you want the Asmwindow shown by default, set the "disasm_window" flag to1. The "disasm_window_height" entry can be used to set thewindow height:let g:termdebug_config['disasm_window'] = v:truelet g:termdebug_config['disasm_window_height'] = 15If thereis nog:termdebug_config you can use:let g:termdebug_disasm_window = 15However, the latter form will be deprecated in future releases.Any value greater than 1 will set the Asmwindow height to that value.If the currentwindow has enough horizontal space,it will be vertically splitand the Asmwindow will be shown side by side with the source codewindow (andthe height option won't be used).termdebug_variables_windowIf you want the Varwindow shown by default, set the "variables_window" flagto 1. The "variables_window_height" entry can be used to set thewindowheight:let g:termdebug_config['variables_window'] = v:truelet g:termdebug_config['variables_window_height'] = 15If thereis nog:termdebug_config you can use:let g:termdebug_variables_window = 15However, the latter form will be deprecated in future releases.Any value greater than 1 will set the Varwindow height to that value.If the currentwindow has enough horizontal space,it will be vertically splitand the Varwindow will be shown side by side with the source codewindow (andthe heightoptions won't be used).Communicationtermdebug-communicationThereis another, hidden, buffer, whichis used for Vim to communicate withgdb. The buffer nameis "gdb communication". Do not delete this buffer,itwill break the debugger.Gdb has some weird behavior, theplugin does its best to work around that.For example, after typing "continue" in thegdbwindowaCTRL-C can be used tointerrupt the running program. But after using the MI command"-exec-continue" pressingCTRL-C does not interrupt. Therefore you will see"continue" being used for the:Continue command, instead of using thecommunication channel.Remote debuggingtermdebug-remoteOne of the main issues of remote debuggingis the access to the debuggee'ssource files. Theplugin can profit from system and vim's networkingcapabilities to workaround this.termdebug-remote-exampleThetermdebug-example can be replicated by running thegdb debugger todebug Vim ona remote Linux machine accessible viassh.- Build Vimas explained in the local example.- If "socat"is not available in the remote machine'terminal' mode will not work properly. Fall back totermdebug_use_prompt: :let g:termdebug_config = {} :let g:termdebug_config['use_prompt'] = v:true- Specify the command line to run the remotegdb instance: :let g:termdebug_config['command'] = ['ssh', 'hostname', 'gdb'] Explainingsshis beyond the scope of this example, but notice the command line can be greatly simplified by specifying the user, keys and otheroptions into the$HOME/.ssh/config file.- Providea hint for translating remote paths intonetrw paths: :let g:termdebug_config['substitute_path'] = { '/': 'scp://hostname//' }- Load thetermdebugplugin and start debugging Vim: :packadd termdebug :Termdebug vimYou now have the same threewindows of the local example and can follow thevery same steps. The only differenceis that the sourcewindows displaysanetrw buffer instead ofa local one.termdebug-substitute-pathUse theg:termdebug_config['substitute_path'] entry to map remote to localfiles using the same strategy that gdb'ssubstitute-path command uses.For example:- Usenetrw to access files remoting via ssh: let g:termdebug_config['command'] = ['ssh', 'hostname', 'gdb'] let g:termdebug_config['substitute_path'] = { '/': 'scp://hostname//' }Note: that the keyspecifies the remote machine root path and the value the local one.- Use Windows'UNC paths to accessWSL2 sources: let g:termdebug_config['command'] = ['wsl', 'gdb'] let g:termdebug_config['substitute_path'] = {\ '/': '\\wsl.localhost\Ubuntu-22.04\',\ '/mnt/c/': 'C:/' }Note: that several mappings are required: one for each drive unit and one for the linux filesystem (queried viawslpath).In this mode anyssh orwsl command would be detected anda similarcommand would be used to launchsocat ina remotettyterminal sessionand connectit togdb.Ifsocatis not availablea plain remoteterminal would be usedasfallback.The next session shows how to override this default behaviour.termdebug-remote-windowIn order to use another remoteterminal client, set "remote_window" entrying:termdebug_config variable before invoking:Termdebug. For example:- Debugging insidea docker container using "prompt" mode: let g:termdebug_config['use_prompt'] = v:true let g:termdebug_config['command'] = ['docker', 'run', '-i',\ '--rm', '--name', 'container-name', 'image-name', 'gdb'] let g:termdebug_config['remote_window'] =\ ['docker', 'exec', '-ti', 'container-name'\ ,'socat', '-dd', '-', 'PTY,raw,echo=0']- Debugging insidea docker container usinga "terminal buffer". The container should be already running because unlike the previouscase for `terminal mode` "program" and "communication" ptys are created before thegdb one: $ docker run -ti --rm --name container-name immage-name Then, launch the debugger: let g:termdebug_config['use_prompt'] = v:false " default let g:termdebug_config['command'] =\ ['docker', 'exec', '-ti', 'container-name', 'gdb'] let g:termdebug_config['remote_window'] =\ ['docker', 'exec', '-ti', 'container-name'\ ,'socat', '-dd', '-', 'PTY,raw,echo=0']Note: "command" cannot use-t ontermdebug-prompt mode because promptbuffers cannot handletty connections.The "remote_window" commandmust use-t because otherwiseit will lacka `pty slave device` forgdb to connect.Note: "socat"must be available in the remote machine on "terminal" mode.Note: docker container sources can be accessible combiningvolumeswith mappings (seetermdebug-substitute-path).GDB commandg:termdebuggerTo change the name of thegdb command, set "debugger" entry ing:termdebug_config or the "g:termdebugger" variable before invoking:Termdebug:let g:termdebug_config['command'] = "mygdb"If thereis nog:termdebug_config you can use:let g:termdebugger = "mygdb"However, the latter form will be deprecated in future releases.If the command needs an argument usea List:let g:termdebug_config['command'] = ['rr', 'replay', '--']If thereis nog:termdebug_config you can use:let g:termdebugger = ['rr', 'replay', '--']Several arguments will be added to makegdb work well for the debugger.If you want to modify them, adda function tofilter the argument list:let g:termdebug_config['command_filter'] = MyDebugFilterA "command_filter" scenariois solving escaping issues on remote debuggingover "ssh". For conveniencea defaultfilteris provided for escapingwhitespaces inside the arguments. Itis automatically configured for "ssh",but can be employed in other use cases like this:let g:termdebug_config['command_filter'] =/ function('g:Termdebug_escape_whitespace')If youdo not want the arguments to be added, but youdo need to set the"pty", usea function to add the necessary arguments:let g:termdebug_config['command_add_args'] = MyAddArgumentsThe function will be called with thelist of arguments so far, anda secondargument thatis the name of the pty.gdb-versionOnly debuggers fully compatible withgdb will work. Vim uses the GDB/MIinterface. The "new-ui" command requiresgdb version 7.12 or later. If youget this error:Undefined command: "new-ui". Try "help".Then yourgdbis too old.Colorshl-debugPChl-debugBreakpointThe color of thesigns can be adjusted with these highlight groups:- debugPCthe current position- debugBreakpointa breakpointThe defaults are, when'background'is "light": hi debugPC term=reverse ctermbg=lightblue guibg=lightblue hi debugBreakpoint term=reverse ctermbg=red guibg=redWhen'background'is "dark": hi debugPC term=reverse ctermbg=darkblue guibg=darkblue hi debugBreakpoint term=reverse ctermbg=red guibg=redShortcutstermdebug_shortcutsYou can define your own shortcuts (mappings) tocontrol gdb, that can work inany window, using the TermDebugSendCommand() function. Example:map ,w :call TermDebugSendCommand('where')<CR>The argumentis thegdb command.Popup menutermdebug_popupBy default the Termdebugplugin sets'mousemodel' to "popup_setpos" and addsthese entries to thepopup menu:Set breakpoint:BreakClear breakpoint:ClearEvaluate:EvaluateIf you don't want this then disableit with:let g:termdebug_config['popup'] = 0If thereis nog:termdebug_config you can use:let g:termdebug_popup = 0However, the latter form will be deprecated in future releases.Change default signstermdebug_signsTermdebug uses the hex number of the breakpoint ID in the signcolumn torepresent breakpoints. Ifitis greater than "0xFF", thenit will bedisplayedas "F+", because there are only two screen cells available for thesign. You may also use decimal breakpointsigns instead, in whichcase IDsgreater than 99 will be displayedas "9+".If you want to customize the breakpointsigns to show>> in the signcolumn:let g:termdebug_config['sign'] = '>>'You can also specify individualsigns for the first several breakpoints:let g:termdebug_config['signs'] = ['>1', '>2', '>3', '>4', '>5', \ '>6', '>7', '>8', '>9']let g:termdebug_config['sign'] = '>>'If you would like to use decimal (base 10) breakpoint signs:let g:termdebug_config['sign_decimal'] = 1If the variableg:termdebug_config does not yet exist, you can use:let g:termdebug_config = {'sign': '>>'}Likewise, to enable decimal signs:let g:termdebug_config = {'sign_decimal': 1}Window toolbartermdebug_winbarBy default the Termdebugplugin createsawindow toolbar if the mouseisenabled (see:Winbar). If you don't want this then disableit with:let g:termdebug_config['winbar'] = 0Vim window widthtermdebug_wideTo change the width of the Vimwindow when debugging starts and usea verticalsplit:let g:termdebug_config['wide'] = 163If thereis nog:termdebug_config you can use:let g:termdebug_wide = 163However, the latter form will be deprecated in future releases.This will set'columns' to 163 when:Termdebugis used. The valueisrestored when quitting the debugger.If the wide valueis set and'columns'is alreadya greater value, thenavertical split will be used without modifying'columns'.Set the wide value to 1 to usea vertical split without everchanging'columns'. Thisis useful when theterminal can't be resized by Vim.Evaluate in Popup Window at Cursortermdebug_evaluate_in_popupBy default:Evaluate will simply echo its output. For larger entities thismight become difficult to read or even truncated.Alternatively, the evaluation result may be output intoapopupwindowat thecurrent cursor position:let g:termdebug_config['evaluate_in_popup'] = v:trueThis can also be used ina "one-shot" manner:func OnCursorHold() let g:termdebug_config['evaluate_in_popup'] = v:true :Evaluate let g:termdebug_config['evaluate_in_popup'] = v:falseendfuncContributingtermdebug_contributingContributions fortermdebug improvements are welcome.However,itis fairly common that during thedevelopment process you need somemechanisms likeecho statements (or similar) tohelp you in your job.For this reason, you can set: let g:termdebug_config['debug'] = v:trueThis sets theDEBUG variable totrue, which can be referenced in thesource code. An example of its usage follows: if exists('g:termdebug_loaded') if DEBUGEchoerr('Termdebug already loaded.') endif finish endif vim:tw=78:ts=8:noet:ft=help:norl: