vim-jp / vimdoc-ja / terminal

terminal - Vim日本語ドキュメント

メインヘルプファイルに戻る English | 日本語 | 編集
terminal.txt  For Vim バージョン 9.1.  Last change: 2024 Nov 23


                VIMリファレンスマニュアル    by Bram Moolenaar


端末ウィンドウサポート                          terminal terminal-window


端末機能はオプションなので、あなたのVimが対応しているかは次のコマンドを使って
確認できる:
        echo has('terminal')
結果が "1" の場合、対応している。


1. 基本的な使い方               terminal-use
      キー入力                          terminal-typing
      サイズと色                        terminal-size-color
      文法                              :terminal
      サイズ変更                        terminal-resizing
      端末モード                        Terminal-mode
      カーソルスタイル                  terminal-cursor-style
      セッション                        terminal-session
      特別なキー                        terminal-special-keys
      Unix                              terminal-unix
      MS-Windows                        terminal-ms-windows
2. 端末関数                             terminal-function-details
3. 端末通信                             terminal-communication
      Vim からジョブへ: term_sendkeys() terminal-to-job
      ジョブから Vim へ: JSON API       terminal-api
      クライアントサーバー機能を使う    terminal-client-server
4. リモートテスト               terminal-testing
5. 画面ダンプの差分             terminal-diff
      Vimの画面ダンプテストを書く       terminal-dumptest
      画面ダンプを作成する              terminal-screendump
      画面ダンプを比較する              terminal-diffscreendump
6. デバッグ                     terminal-debug
      はじめに                          termdebug-starting
      セッション例                      termdebug-example
      コードをステップ実行する          termdebug-stepping
      変数を検査する                    termdebug-variables
      スタックフレームの移動            termdebug-frames
      その他のコマンド                  termdebug-commands
      イベント                          termdebug-events
      プロンプトモード                  termdebug-prompt
      マッピング                        termdebug-mappings
      通信                              termdebug-communication
      カスタマイズ                      termdebug-customizing

{Vimが +terminal 機能付きでコンパイルされたときのみ有効}
端末機能を使うには +job と +channel 機能が必要である。

==============================================================================
1. 基本的な使い方                                       terminal-use

これは Vim のウィンドウ内で端末エミュレーターを実行する機能である。端末エミュ
レーターに接続すると1つのジョブが開始される。例としてシェルを実行する場合は以
下のようになる:
     :term bash

またビルドコマンドを実行するにはこうなる:
     :term make myprogram

ジョブはVimとは非同期的に動作し、他のウィンドウで編集中であってもジョブからの
出力は随時端末ウィンドウに反映される。


キー入力
                                                        terminal-typing
端末ウィンドウにキーボードのフォーカスがある時には、入力したキーはジョブに送ら
れる。これには可能ならば pty を使用する。端末ウィンドウ外をクリックすれば、キー
ボードフォーカスを外に動かせる。

                                                t_CTRL-W_CTRL-W t_CTRL-W_:
ウィンドウや他の CTRL-W コマンドを操作するために CTRL-W を使える。例えば:
        CTRL-W CTRL-W   次のウィンドウにフォーカスを移動する
        CTRL-W :        Exコマンドに入る
他のコマンドについては CTRL-W を参照。


端末ウィンドウでの特別な操作:                   t_CTRL-W_.  t_CTRL-W_N
        CTRL-W .        端末内のジョブに CTRL-W を送る
        CTRL-W CTRL-\   端末内のジョブに CTRL-\ を送る
        CTRL-W N        端末ノーマルモードに移行、Terminal-mode を参照
        CTRL-\ CTRL-N   端末ノーマルモードに移行、Terminal-mode を参照
        CTRL-W " {reg}  レジスタ {reg} の内容を貼り付け t_CTRL-W_quote
                        式の評価結果を挿入するためのレジスタ = も機能する
        CTRL-W CTRL-C   ジョブを停止する。下記の t_CTRL-W_CTRL-C を参照
        CTRL-W gt       次のタブページに移動する。gt と同じ   t_CTRL-W_gt
        CTRL-W gT       前のタブページに移動する。gT と同じ   t_CTRL-W_gT

CTRL-W の代わりに別のキーを使うにはオプション 'termwinkey' を参照。但し、
'termwinkey' を2回タイプすると 'termwinkey' がジョブへ送信される。例:
        'termwinkey' CTRL-W    次のウィンドウにフォーカスを移動する
        'termwinkey' :         Exコマンドに入る
        'termwinkey' 'termwinkey' 端末内のジョブに 'termwinkey' を送信する
        'termwinkey' .         端末内のジョブに 'termwinkey' を送信する
        'termwinkey' CTRL-\    端末内のジョブに CTRL-\ を送信する
        'termwinkey' N         端末ノーマルモードへ移行する。以下を参照
        'termwinkey' CTRL-N    CTRL-W N と同じ t_CTRL-W_N
        'termwinkey' CTRL-C    CTRL_W CTRL_C と同じ t_CTRL-W_CTRL-C
                                                        t_CTRL-\_CTRL-N
他のモードと同じように、ノーマルモードへ移行するための特別なキーの組み合わせで
ある CTRL-\ CTRL-N が使用できる。
                                                        t_CTRL-W_CTRL-C
ジョブを強制停止するのに CTRL-W CTRL-C を使える。MS-Windowsでは CTRL-Break で
も同様にジョブを停止できる。

CTRL-C を入力した場合、その効果は pty がどのように構成されているかに従う。シン
プルなコマンドにおいては SIGINT がジョブに送られ、結果的にジョブが停止するだろ
う。中には SIGINT を無視するコマンドもあるだろうし、また (Vim がそうしているよ
うに) CTRL-C をプログラム自身で取り扱うものもあるだろう。

入力したキーを別のものに読み替えさせるには端末モードマッピング、詳細は :tmap
を参照。これはどのようなマッピングでも定義できるが、端末内で実行されているジョ
ブに送信されるキー入力にのみ作用する。例えば、F1 キーで端末ノーマルモードに切
り替えるには:
   tnoremap <F1> <C-W>N
Esc を使うことができるが、他のキーが壊れないようにする必要がある (カーソルキー
は Esc で始まるので、それらは壊れるかもしれない)、これはおそらくGUIでしか動作
しない:
   tnoremap <Esc> <C-W>N
   set notimeout ttimeout timeoutlen=100

端末モードマッピングと同様にメニューを作成することもできるが、:tmenu ではな
く :tlmenu を使用する必要がある。

                                                        options-in-terminal
端末ウィンドウを開いて 'buftype' を "terminal" に設定すると、TerminalWinOpen
自動コマンドイベントが発生する。これにより、端末ウィンドウとバッファ専用のオプ
ションを設定することが可能である。例:
   au TerminalWinOpen * setlocal bufhidden=hide
これが適切に動作するのは端末が隠れていない場合に限られる。

端末が隠れている場合と隠れていない場合両方で動作するのは、バッファローカルと
ウィンドウローカルのオプションである:
   au TerminalWinOpen,BufWinEnter * if &buftype == 'terminal'
        \ | setlocal bufhidden=hide colorcolumn=123
        \ | endif
Note この隠れている端末のオプションは端末が隠れている間は値が設定されない。

TerminalOpen イベントもある。これは隠れた端末で発生するかもしれず、その場合
は現在のウィンドウとバッファはこの新しい端末ではないことに注意。
端末バッファに設定する場合、<abuf> を使う必要がある。例:
    au TerminalOpen * call setbufvar(expand('<abuf>')->str2nr(),
            \ '&termwinscroll', 1000)
ウィンドウローカルオプションは、端末ウィンドウが生成されるまで設定が遅延する必
要がある (これは隠れた端末だけで作用する):
    au TerminalOpen * exe printf(
        \    'au BufWinEnter <buffer=%d> ++once setlocal colorcolumn=%d',
        \       expand('<abuf>')->str2nr(), 123)
隠れていない端末では TerminalWinOpen を使う。

マウスイベント (クリックやドラッグ) は端末に渡される。マウス移動イベントは Vim
自身が受け取ったときにのみ渡される。'balloonevalterm' が有効になっている端末の
場合。


サイズと色

                                                        terminal-size-color
端末ウィンドウのサイズを制御するにはオプション 'termwinsize' を参照。
(TODO: 端末がウィンドウよりも大きい場合にはスクロールすることを記述する)

端末内のジョブは端末の色を変更できる。デフォルトの前景色及び背景色はVimの
Normal ハイライトグループにより決定される。

カラー端末を開始する際に、背景に白と黒どちらの系統の色を使用するかは、オプショ
ン 'background' を用いて決定する。

異なる色を使う場合には Terminal ハイライトグループを利用できる。例:
    hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue
もしくは Terminal の代わりとしてterm_start() のオプション "term_highlight"
で別グループを設定できる。

                                                        g:terminal_ansi_colors
新しい端末ウィンドウでデフォルトで使用される 16 個の ANSI カラーは、変数
g:terminal_ansi_colors を使用して設定することができる。これは、16 個の色名ま
たは 16 進数の色コードのリストでなければならない。これは、highlight-guifg で
受け入れられるものと同様である。GUI カラーを使用しない場合、端末ウィンドウは常
に元の端末の 16 個の ANSI カラーを使用する。
term_start() を使う時、"ansi_colors" オプションにより色が設定できる。
term_setansicolors() 関数を使用して色を変更したり、term_getansicolors() を
使用して現在使用されている色を取得することができる。


コマンド文法

:[range]ter[minal] [options] [command]                  :ter :terminal
                        新しい端末ウィンドウを開く。

                        [command] が指定された場合、それをジョブとして実行し、
                        端末の入出力を接続する。
                        [command] が指定されなかった場合、オプション 'shell'
                        を使用する。
                        [command] が NONE の場合ジョブは開始されず、端末の pty
                        は gdb のようなコマンドによって利用できる。

                                                        terminal-nospecial
                        Vim 自体は [command] 内の cmdline-special 文字のみを
                        認識する。その他はすべてそのまま渡される。ワイルドカー
                        ド、環境変数、またはその他のシェル特殊文字を展開する必
                        要がある場合は、term++shell オプションを検討するこ
                        と。

                        [command] がない場合、デフォルトの動作はシェルが終了し
                        たときに端末を閉じる。この動作は ++noclose 引数で変更
                        できる。
                        [command] が指定されている場合、デフォルトの動作は端末
                        を端末ノーマルモードで開いたままにする。この動作は
                        ++close 引数で変更できる。

                        Vimのコマンドを後ろに続けることはできず、どんな | も
                        [command] に含まれてしまう。
                        同じ行で Vim コマンドを続けたい場合、:execute を使用
                        する。

                                                        terminal-bufname
                        新しいバッファが作られ、[command] もしくは 'shell' に
                        "!" が前置された名前が与えられる。すでに同じ名前のバッ
                        ファが存在する場合には、カッコに囲まれた番号が付与され
                        る。例えば "gdb" が存在するなら2つ目の端末には
                        "!gdb (1)" という名前が使われる。

                        [range] が与えられた場合は、指定された範囲の行がジョブ
                        の入力として使われる。その際の端末ウィンドウではキー
                        入力ができなくなる。MS-Windows においては以下の ++eof
                        オプションも参照。

                                                term++close term++open
                        サポートされる [options] は以下の通り:
                        ++close         ジョブが終了した際には自動的に端末ウィ
                                        ンドウを閉じる。 terminal-close
                        ++noclose       ジョブが終了しても自動的に端末ウィンド
                                        ウを閉じない。
                        ++open          ジョブが終了した際にウィンドウが表示さ
                                        れていない場合に、ウィンドウを表示す
                                        る。割り込み的に発生しうることに留意。
                                ++close, ++noclose と ++open は最後に指定され
                                たものが有効である。

                        ++curwin        現在のウィンドウで端末を開き、現在の
                                        ウィンドウを分割しない。現在のバッファ
                                        を放棄 (abandon) できない場合は失敗
                                        する。
                        ++hidden        端末を隠しバッファとして開く。ウィンド
                                        ウは使用されない。
                        ++norestore     セッションファイルに端末ウィンドウを含
                                        めない。

                                                term++shell
                        ++shell         {command} を直接実行するのではなく、
                                        :!command と同様にシェルを使用する。
                                                                E279
                                        {Vim: UnixとMS-Windowsでのみ動作する}
                                        結果のコマンドは次のようになる
                                        'shell' 'shellcmdflag' [command]
                                        :!command に関連するその他のオプショ
                                        ンは効果がない。
                        ++kill={how}    端末ウィンドウを閉じるときに {how} で
                                        ジョブを終了させる。値については
                                        term_setkill() を参照。
                        ++rows={height} 端末ウィンドウの高さとして {height} を
                                        使う。もし、端末がVimの完全な高さ(端末
                                        ウィンドウの上や下にウィンドウがない)
                                        を使用する場合、必要に応じてコマンドラ
                                        インの高さが減少する。
                        ++cols={width}  端末ウィンドウの幅として {width} を使
                                        う。もし、端末がVimの完全な幅(端末ウィ
                                        ンドウの左か右にウィンドウがない)を使
                                        用する場合、この値は無視される。
                        ++eof={text}    [range] を使った場合: 最後の行を送信し
                                        たあとに指定したテキストが送られる。空
                                        白を含むことはできない。CR が 1 つ付け
                                        加えられる。MS-Windows ではデフォルト
                                        では CTRL-D が送られる。
                                        例: シェルには "++eof=exit" を、Python
                                        には "++eof=exit()" を指定する。特殊
                                        コードが :map と同様に利用できる。
                                        例: "<C-Z>" は CTRL-Z を示す。
                        ++type={pty}    (MS-Windowsのみ): 仮想コンソールとして
                                        {pty} を使用する。値については
                                        'termwintype' を参照。
                        ++api={expr}    {expr} で始まる関数名を terminal-api
                                        機能として呼び出すことを許可する。
                                        {expr} が空の場合、関数を呼び出すこと
                                        はできない。

                        より詳細なオプションを使いたい場合は term_start() 関
                        数を使用する。
                        ウィンドウを縦分割するには、次のようにする:
                                :vertical terminal
                        または短縮形:
                                :vert ter

端末に関連付けられたバッファが強制的にアンロードもしくは削除された場合には、
job_stop(job, "kill") を呼んだのと同じようにそのジョブが殺される。
普通にウィンドウを閉じると E947 が返る。killメソッドが "++kill={how}" か
term_setkill() で設定されている時にウィンドウを閉じると、その方法でジョブを
強制終了または中断する。例:
        :term ++kill=term tail -f /tmp/log

ジョブが実行され続けるとウィンドウはそのバッファが変更されたかのように振る舞
う。CTRL-W :quit でウィンドウを閉じようとしても失敗する。CTRL-W :quit! を
使うとジョブは終了する。ウィンドウのテキストは失われ、バッファは削除される。
CTRL-W :bunload! はバッファは残るが、空になる。

CTRL-W :close で閉じようとしても失敗する。CTRL-W :close! はウィンドウを閉
じ、バッファを隠し状態にする。

CTRL-W :hide を使うとジョブを実行したまま、端末ウィンドウを閉じバッファを隠
し状態にできる。:buffer コマンドで現在のウィンドウを端末ウィンドウにすること
ができる。未保存の変更があった場合にはこれは失敗するが、通常と同じように ! で
強制できる。

                                                        terminal-close
端末ジョブが終了し、[commmand] が指定されなかった場合 (例えば、'shell' コマン
ドが実行された)、端末ウィンドウはデフォルトで閉じられる (ただし、空間を受け取
る次のウィンドウのバッファに 'nobuflisted' オプションが設定されている場合を除
く。その場合、端末ウィンドウは自動的に閉じられないが、そのウィンドウで新しい空
のバッファが開かれる)。

端末ウィンドウが閉じられるとき、例えば、シェルが終了し、"++close" 引数が使用さ
れ、これが最後の通常のVimウィンドウである場合、Vimは終了する。これは、通常の
ウィンドウで :quit を使用するようなものだ。ヘルプウィンドウとプレビューウィ
ンドウはカウントされない。

バックグラウンドジョブをウィンドウ無しで実行し、終了したらウィンドウに表示する
には、次のようにオプションを指定する:
        :term ++hidden ++open make
Note ウィンドウが予期せぬタイミングで開かれ、あなたが行っている操作に割り込む
可能性があることに注意。

                                                        E947 E948
ジョブが実行され続けると、バッファが変更されたとみなされ Vim を簡単には終了で
きなくなる。abandon を参照。

ジョブが終了しバッファに何の変更も及ぼさなかった場合、そのウィンドウを閉じると
バッファは削除される。

端末バッファを変更するにはオプション 'modifiable' をセットする必要がある。これ
はジョブが終了した後にのみ行なえる。バッファを最初に変更した瞬間に普通のバッ
ファになりハイライトは削除される。バッファを保存可能にするために :file でバッ
ファの名前を、コマンド名から変更することもできる。


サイズ変更
                                                        terminal-resizing
端末のサイズは3つのモードのいずれか1つで決まる:

1. オプション 'termwinsize' が空の場合: 端末サイズはウィンドウのサイズに従う。
   最小で2行、10桁。

2. オプション 'termwinsize' が "rows*cols" の場合、"rows" を最小行数、"cols"
   を最小桁数とする。

3. オプション 'termwinsize' が "rowsXcols" ("X" は大文字小文字を問わない) の場
   合、端末サイズは指定された行数と桁数で固定される。もしもウィンドウがそれよ
   りも大きい場合には、使用されない空の領域ができる。

ウィンドウサイズが端末サイズよりも小さい場合、端末の一部の領域(左下に相当する
部分)のみが描画される。

端末の現在のサイズを取得するのに関数 term_getsize() が使える。
term_setsize() は 1 か 2 のモードの時にだけ、すなわち 'termwinsize' が
"rowsXcols" 形式ではない時に使える。


端末ジョブモードと端末ノーマルモード
                                                Terminal-mode Terminal-Job
ジョブが実行中には端末の内容はジョブの制御下にある。それにはカーソルの位置も含
まれる。入力したキーはジョブに送られる。端末の内容はいつでも更新されえる。これ
を端末ジョブモードと呼ぶ。

CTRL-W N (もしくは 'termwinkey' N) を入力すると 端末ノーマルモードに遷移する。
このモードでは端末ウィンドウのコンテンツはVimの制御下に置かれ、ジョブの出力は
一時保留される。CTRL-\ CTRL-N でも同様。

:tmap のマッピングは 端末ジョブモードにおいて作用する。term_sendkeys() で
送ったキーには tmap は適用されないが、feedkeys() で送ったキーには適用される。

端末ジョブモードから挿入モードに入ることはできない。

                                                Terminal-Normal E946
端末ノーマルモードでは、Vimの普通のコマンドでカーソルを自由に動かせる。視覚的
にテキストをマークしたり、テキストをヤンクしたり思いのままである。しかしバッ
ファの内容を変更することはできない。'i' や 'a' など挿入モードを開始するコマン
ドを使うと 端末ジョブモードに戻る。結果としてウィンドウは端末のコンテンツを反
映させるために更新される。:startinsert は無効である。

端末ノーマルモードではステータスラインとウィンドウタイトルには "(Terminal)" と
表示される。端末ノーマルモード中にジョブが終了してしまった場合にはそれが
"(Terminal-finished)" に変わる。

ジョブが端末内で行を出力し内容が上からスクロールすると、それらの行は記憶され端
末ノーマルモードで表示される。行数は 'termwinscroll' オプションによって制限さ
れる。この制限を超えると、スクロールされた行の最初の10%が削除されて失われる。


カーソルスタイル
                                                        terminal-cursor-style
デフォルトでは端末ウィンドウのカーソルには点滅しないブロックが使われる。カーソ
ルの点滅状態や形を変更するのに、普通の xterm のエスケープシーケンスが使われる。
端末ウィンドウからフォーカスが外れる際に Vim は元々のカーソルを復元する。

xterm を "-bc" 引数で起動した場合、または他の方法でカーソルの点滅を発生させた
場合、が1つの例外となる。それらにより点滅フラグが逆転したことが問題の引き金と
なる。なぜなら Vim はその逆転を検出できず、端末ウィンドウのカーソルの点滅も逆
転する。


セッション
                                                        terminal-session
可能かつ必要であれば、セッションファイルを使用する際に端末ウィンドウが復元され
る。

"terminal" が 'sessionoptions' から削除された場合、端末ウィンドウは復元されな
い。

端末内のジョブが終了した場合、ウィンドウは復元されない。

端末を復元できる場合は、その端末を開くために使用されたコマンドが再び使われる。
これを変更するには term_setrestore() 関数を使用する。これは、コマンドを
"NONE" に設定して特定の端末を復元しない場合にも使用できる。


特別なキー
                                                        terminal-special-keys
端末エミュレータは xterm をシミュレートするため、端末ウィンドウでは Vim と
xterm の両方が認識するエスケープシーケンスのみを使用できる。端末で実行中のジョ
ブに他のエスケープシーケンスを渡したい場合は、転送を設定する必要がある。例:
        tmap <expr> <Esc>]b SendToTerm("\<Esc>]b")
        func SendToTerm(what)
          call term_sendkeys('', a:what)
          return ''
        endfunc


Unix
                                                        terminal-unix
UNIX ではすべての種類のコマンドを実行可能とするために pty を用いている。端末内
で Vim ですら実行できる! これは以下のようにデバッグに使用される。

実行中のジョブに情報を伝えるために以下の環境変数が使用される:
    TERM                端末の名前、'term' オプションまたはGUIでは $TERM から。
                        "xterm" で始まらなければ "xterm" にフォールバックする
    ROWS                端末の初期行数
    LINES               ROWS と同じ
    COLUMNS             端末の初期桁数
    COLORS              色数 't_Co' (GUIでは 256*256*256)
    VIM_SERVERNAME      v:servername
    VIM_TERMINAL        v:version


MS-Windows
                                                        terminal-ms-windows
MS-Windows ではすべての種類のコマンドを実行可能とするために winpty を用いてい
る。あたりまえのことだが、ここで実行するコマンドは端末の中で動くもので、独自の
ウィンドウを開くものであってはならない。

winpty 内の以下の2つのファイルが必要である:

    winpty.dll
    winpty-agent.exe

これらは以下のページからダウンロードできる:

    https://github.com/rprichard/winpty

これらのファイルを環境変数 PATH のいずれかに置くだけだ。必要ならばオプション
'winptydll' でファイルの場所を指定できる。もしも32ビット版と64ビット版を同じ
ディレクトリに置きたいのであれば、Vimのビルドに合わせてそれぞれを winpty32.dll
もしくは winpty64.dll という名前に変更すること。

                                                        ConPTY E982
MS-Windows 10の最新バージョン("October 2018 Update" 以降)では、winpty は必要な
くなった。それらのバージョンでは、:terminal はターミナルアプリケーションをホ
ストするためのWindowsの組み込みサポート "ConPTY" を使用する。ConPTY が使用され
ている場合、あいまいな幅の文字に関するレンダリングアーティファクトが発生する可
能性がある。そのような問題に遭遇した場合は、"winpty" をインストールすること。
ConPTY の問題が修正されるまでは、"winpty" が優先される。

環境変数は実行中のジョブに情報を渡すために使用される:
    VIM_SERVERNAME      v:servername

==============================================================================
2. 端末関数                                     terminal-function-details

                                                        term_dumpdiff()
term_dumpdiff({filename}{filename} [, {options}])
                2 つのファイルの差分を表示する新しいウィンドウを開く。これらの
                ファイルは term_dumpwrite() で作られたものでなければならな
                い。
                差分の検出に失敗したときはバッファ番号もしくは 0 を返す。
                terminal-diff も参照。
                NOTE: これは 2 倍幅文字ではまだ機能しない。

                バッファの先頭部分は 1 つ目のファイルの内容を含み、バッファの
                末尾部分は 2 つ目のファイルの内容を含む。中央部分は差分を表示
                する。
                それぞれの部分はイコールの行で分割される。

                引数 {options} は辞書でなければらなず、以下のメンバを含むこと
                ができる:
                   "term_name"       (1 つ目のファイル名の代わりに使用される)
                                     バッファ名
                   "term_rows"       ('termwinsize' の代わりに使用される) 端末
                                     の垂直サイズ、ただし最小サイズは尊重する
                   "term_cols"       ('termwinsize' の代わりに使用される) 端末
                                     の水平サイズ、ただし最小サイズは尊重する
                   "vertical"        ウィンドウを垂直に分割する
                   "curwin"          ウィンドウを分割せず現在のウィンドウを使
                                     用する、現在のバッファが放棄 (abandon)
                                     不可の場合は失敗する
                   "bufnr"           新しいバッファを作成せずに、既存のバッファ
                                     "bufnr" を使用する。このバッファは前もっ
                                     て term_dumpdiff() または term_dumpload()
                                     で作成され、ウィンドウに表示されていなけ
                                     ればならない。
                   "norestore"       端末ウィンドウをセッションファイルに加え
                                     ない

                中央部分のそれぞれの文字は違いを表示している。複数の違いがあっ
                た場合は以下のリスト内の最初のものだけが使用される:
                        X       異なる文字
                        w       異なる幅
                        f       異なる文字色
                        b       異なる背景色
                        a       異なる属性
                        +       1 つ目のファイル内に存在しない位置
                        -       2 つ目のファイル内に存在しない位置
                        >       2 つ目のファイルにはなく1 つ目のファイルにある
                                現在のカーソル位置
                        <       1 つ目のファイルにはなく2 つ目のファイルにある
                                現在のカーソル位置

                "s" キーを押すと、先頭部分と末尾部分が入れ替わる。これにより差
                分を簡単に確認することができる。

                method としても使用できる:
                        GetFilename()->term_dumpdiff(otherfile)

                戻り値の型: Number


term_dumpload({filename} [, {options}])                 term_dumpload()
                {filename} の内容を表示する新しいウィンドウを開く。このファイ
                ルは term_dumpwrite() で作られたものでなければならない。
                失敗したときはバッファ番号もしくは 0 を返す。
                terminal-diff も参照。

                {options} については term_dumpdiff() を参照。

                method としても使用できる:
                        GetFilename()->term_dumpload()

                戻り値の型: Number


term_dumpwrite({buf}{filename} [, {options}])         term_dumpwrite()
                ファイル {filename} に、{buf} の端末画面の内容をダンプする。こ
                れは term_dumpload() および term_dumpdiff() で使われる
                フォーマットを使用する。
                端末のジョブがすでに終了していた場合はエラーが発生する: E958
                {filename} が既に存在する場合はエラーが発生する:        E953
                terminal-diff も参照。

                {options} は以下のオプショナルな要素を含む辞書である:
                        "rows"          ダンプする行の最大値
                        "columns"       ダンプする列の最大値

                method としても使用できる、ベースはファイル名に使用される:
                        GetFilename()->term_dumpwrite(bufnr)

                戻り値の型: Number


term_getaltscreen({buf})                                term_getaltscreen()
                {buf} の端末が代替スクリーンを使用している場合 1 を返す。
                {buf} の扱いについては term_getsize() と同じ。

                method としても使用できる:
                        GetBufnr()->term_getaltscreen()

                戻り値の型: Number


term_getansicolors({buf})                               term_getansicolors()
                端末 {buf} で使用されている ANSI カラーパレットを取得する。
                長さ 16 のリストを返し、各要は色を 16 進数の "#rrggbb" フォー
                マットで表す文字列である。
                term_setansicolors() および g:terminal_ansi_colors も参照。
                どちらも使用されていない場合、既定値を返す。

                {buf} の扱いについては term_getsize() と同じ。バッファが存在
                しない、もしくは端末ウィンドウでない場合は、空リストが返され
                る。

                method としても使用できる:
                        GetBufnr()->term_getansicolors()

                戻り値の型: list<string> または list<any>

                {GUI が有効もしくは +termguicolors 機能付きでコンパイルされ
                たときのみ有効}

term_getattr({attr}{what})                            term_getattr()
                term_scrape() で返された項目 "attr" の値である {attr} につい
                て、{what} がオンになっているかを返す。{what} は次のうちどれか
                1 つである:
                        bold
                        italic
                        underline
                        strike
                        reverse

                method としても使用できる:
                        GetAttr()->term_getattr()

                戻り値の型: Number


term_getcursor({buf})                                   term_getcursor()
                端末 {buf} のカーソル位置を取得する。2 つの数値と辞書から構成
                されるリストを返す: [row, col, dict]。

                "row" および "col" は 1 を基準とし、最初のスクリーンセルは、
                行 1、列 1 である。これは端末自身のカーソル位置であり、Vim ウィ
                ンドウのものではない。

                "dict" は以下 3 つのメンバを持つ:
                   "visible"    カーソルが可視のときは 1、不可視のときは 0
                   "blink"      カーソルが点滅のときは 1、非点滅のときは 0
                   "shape"      ブロックカーソルは 1、下線は 2、垂直線は 3
                   "color"      カーソルの色。例: "green"

                {buf} は端末ウィンドウのバッファ番号でなければならない。バッ
                ファが存在しない、もしくは端末ウィンドウでない場合は、空リスト
                が返される。

                method としても使用できる:
                        GetBufnr()->term_getcursor()

                戻り値の型: list<any>


term_getjob({buf})                                      term_getjob()
                端末ウィンドウ {buf} に関連付いたジョブを取得する。
                {buf} の扱いについては term_getsize() と同じ。
                ジョブがない場合は v:null を返す。Vim9 script では、ジョブが
                ない場合 null_job を返す。

                method としても使用できる:
                        GetBufnr()->term_getjob()

                戻り値の型: job


term_getline({buf}{row})                              term_getline()
                端末ウィンドウ {buf} から行のテキストを取得する。
                {buf} の扱いについては term_getsize() と同じ。

                先頭行の {row} は 1 である。{row} が "." のときはカーソル行が
                使われる。{row} が無効のときは空文字列が返される。

                各文字の属性を取得するには term_scrape() を使用する。

                method としても使用できる:
                        GetBufnr()->term_getline(row)

                戻り値の型: String


term_getscrolled({buf})                                 term_getscrolled()
                端末 {buf} の先頭から上方にスクロールされた行の数を返す。これ
                は term_getline() および getline() で使われる行番号のオフ
                セットとなるので:
                        term_getline(buf, N)
                は以下と等しい:
                        getline(N + term_getscrolled(buf))
                (もしその行が存在していれば)。

                {buf} の扱いについては term_getsize() と同じ。

                method としても使用できる:
                        GetBufnr()->term_getscrolled()

                戻り値の型: Number


term_getsize({buf})                                     term_getsize()
                端末 {buf} のサイズを取得する。2 つの数値を含むリストを返す:
                [rows, cols]。これは端末のサイズであり、端末を含むウィンドウの
                サイズではない。

                {buf} は端末ウィンドウのバッファ番号でなければならない。現在の
                バッファには空文字列を使用する。バッファが存在しない、もしくは
                端末ウィンドウでない場合は、空リストが返される。

                method としても使用できる:
                        GetBufnr()->term_getsize()

                戻り値の型: list<number> または list<any>


term_getstatus({buf})                                   term_getstatus()
                端末 {buf} のステータスを取得する。これらの項目をコンマで区切っ
                た一覧を文字列で返す:
                        running         ジョブが実行中である
                        finished        ジョブが完了した
                        normal          端末ノーマルモードである
                "running" または "finished" のどちらかは常に存在する。

                {buf} は端末ウィンドウのバッファ番号でなければならない。バッ
                ファが存在しない、もしくは端末ウィンドウでない場合は、空文字列
                が返される。

                method としても使用できる:
                        GetBufnr()->term_getstatus()

                戻り値の型: String


term_gettitle({buf})                                    term_gettitle()
                端末 {buf} のタイトルを取得する。これは端末内でジョブが設定し
                たタイトルである。

                {buf} は端末ウィンドウのバッファ番号でなければならない。バッ
                ファが存在しない、もしくは端末ウィンドウでない場合は、空文字列
                が返される。

                method としても使用できる:
                        GetBufnr()->term_gettitle()

                戻り値の型: String


term_gettty({buf} [, {input}])                          term_gettty()
                端末ウィンドウ {buf} に関連付けられた制御端末の名前を取得する。
                {buf} の扱いについては term_getsize() と同じ。

                {input} が省略されたもしくは 0 のとき、書き込み (stdout) の名
                前を返す。{input} が 1 のとき、読み込み (stdin) の名前を返す。
                UNIX では両方で同じ名前が返る。

                method としても使用できる:
                        GetBufnr()->term_gettty()

                戻り値の型: String


term_list()                                             term_list()
                すべての端末ウィンドウのバッファのバッファ番号のリストを返す。

                戻り値の型: list<number> または list<any>


term_scrape({buf}{row})                               term_scrape()
                端末スクリーン {buf} の {row} にある内容を取得する。
                {buf} については term_getsize() を参照。

                先頭行の {row} は 1 である。{row} が "." のときはカーソル行が
                使用される。{row} が無効なときは空文字列が返される。

                各スクリーンのセルに対する辞書を含んだリストを返す:
                    "chars"     セルの文字
                    "fg"        文字色 (#rrggbb)
                    "bg"        背景色 (#rrggbb)
                    "attr"      セルの属性、個々のフラグを取得するには
                                term_getattr() を使用する
                    "width"     セルの幅: 1 もしくは 2
                1項目が2セル幅の時、結果のリストは端末の幅より短くなりえる。

                method としても使用できる:
                        GetBufnr()->term_scrape(row)

                戻り値の型: list<dict<any>> または list<any>


term_sendkeys({buf}{keys})                            term_sendkeys()
                端末 {buf} にキー入力 {keys} を送る。
                {buf} の扱いについては term_getsize() と同じ。

                {keys} はキーシーケンスとして解釈される。例えば、"\<c-x>" は
                文字 CTRL-X を意味する。

                method としても使用できる:
                        GetBufnr()->term_sendkeys(keys)

                戻り値の型: Number


term_setansicolors({buf}{colors})                     term_setansicolors()
                端末 {buf} で使用される ANSI カラーパレットを設定する。
                {colors} は、highlight-guifg で受け付けられるような、有効な
                カラー名もしくは 16 進数のカラーコードを 16 個含むリストでなけ
                ればならない。
                term_getansicolors() および g:terminal_ansi_colors も参照。

                カラーは通常以下のとおり:
                        0    black
                        1    dark red
                        2    dark green
                        3    brown
                        4    dark blue
                        5    dark magenta
                        6    dark cyan
                        7    light grey
                        8    dark grey
                        9    red
                        10   green
                        11   yellow
                        12   blue
                        13   magenta
                        14   cyan
                        15   white

                これらの色は、GUI 内および 'termguicolors' が設定されていると
                きの端末内で使用される。GUI カラーを使用しないとき (GUI モード
                もしくは 'termguicolors')、端末ウィンドウは、常に基となる端末
                の 16 ANSI カラーを使用する。

                method としても使用できる:
                        GetBufnr()->term_sendkeys(keys)

                戻り値の型: Number

                {GUI が有効もしくは +termguicolors 機能付きでコンパイルされ
                たときのみ有効}


term_setapi({buf}{expr})                              term_setapi()
                端末 {buf} 内で terminal-api 機能に使用する関数名のプリフィッ
                クスを設定する。例:
                    :call term_setapi(buf, "Myapi_")
                    :call term_setapi(buf, "")

                デフォルトは "Tapi_" である。{expr} が空の文字列の場合、{buf}
                の terminal-api 機能は使用できない。

                method としても使用できる、ベースは {buf} に使用される:
                        GetBufnr()->term_setapi({expr})

                戻り値の型: Number


term_setkill({buf}{how})                              term_setkill()
                Vim が終了するもしくは何らかの方法で端末ウィンドウを閉じようと
                しているとき、端末内のジョブを停止するかどうかを {how} で定義
                する。
                {how} が空 (既定値) のとき、ジョブは停止されない。終了しようと
                すると E947 となる。
                それ以外では、{how} はジョブに何のシグナルを送るかを記述する。
                値に関しては job_stop() を参照。

                シグナルを送ったあと、Vim はジョブが実際に停止したか確認するた
                めに 1 秒待つ。

                method としても使用できる:
                        GetBufnr()->term_setkill(how)

                戻り値の型: Number


term_setrestore({buf}{command})                       term_setrestore()
                この端末内のジョブを復元するためのセッションファイルを書き込む
                コマンドを設定する。セッションファイル内に書き込まれる行は以下
                の通り:
                        terminal ++curwin ++cols=%d ++rows=%d {command}
                コマンドを適切にエスケープするよう気を付けること。

                'shell' を実行するには空の {command} を使用する。
                このウィンドウを復元しないためには "NONE" を使用する。

                method としても使用できる:
                        GetBufnr()->term_setrestore(command)

                戻り値の型: Number


term_setsize({buf}{rows}{cols})             term_setsize() E955
                端末 {buf} のサイズを設定する。端末を含むウィンドウのサイズが
                可能であれば調整される。{rows} もしくは {cols} が、0 もしくは
                負である場合、大きさは変わらない。

                {buf} は端末ウィンドウのバッファ番号でなければならない。現在の
                バッファには空文字列を使用する。バッファが存在しない、もしくは
                端末ウィンドウでない場合は、エラーが発生する。

                method としても使用できる:
                        GetBufnr()->term_setsize(rows, cols)

                戻り値の型: Number


term_start({cmd} [, {options}])                 term_start()
                端末ウィンドウを開き、その中で {cmd} を実行する。

                {cmd} は job_start() と同じような文字列もしくはリストである。
                ジョブを開始せずに端末ウィンドウを開くには、文字列 "NONE" を使
                用することができ、端末の疑似端末は gdb のようなコマンドで使用
                することができる。

                端末ウィンドウのバッファ番号を返す。{cmd} が実行できない場合、
                ウィンドウが開いてエラーメッセージを表示する。
                ウィンドウを開くのに失敗すると 0 を返す。

                {options} は job_start() で使用されるものと似ている。
                job-options を参照。しかしながらすべてのオプションが使えるわ
                けではない。サポートされているものは以下のとおり:
                   すべての timeout オプション
                   "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"
                しなかしながら、少なくとも stdin、stdout もしくは stderr のう
                ち 1 つは端末に接続されていなければならない。I/O が端末に接続
                されているとき、その部分のコールバック機能は使用されない。

                追加のオプションは以下のとおり:
                   "term_name"       (コマンド名の代わりに使用される)バッファ
                                     名に使用する名前。
                   "term_rows"       ('termwinsize' の代わりに使用される) 端末
                                     の垂直サイズ。有効範囲は0から1000。
                   "term_cols"       ('termwinsize' の代わりに使用される) 端末
                                     の水平サイズ
                   "vertical"        ウィンドウを垂直に分割する。Note: 他のウィ
                                     ンドウの位置は、:belowright のようなコマ
                                     ンド修飾子によって決められる。
                   "curwin"          ウィンドウを分割せず現在のウィンドウを使
                                     用する、現在のバッファが放棄 (abandon)
                                     不可の場合は失敗する
                   "hidden"          ウィンドウを開かない
                   "norestore"       端末ウィンドウをセッションファイルに加え
                                     ない
                   "term_kill"       端末ウィンドウを閉じようとしているときに
                                     何をするか、term_setkill() を参照
                   "term_finish"     ジョブが終了したときに何をするか:
                                        "close": ウィンドウを閉じる
                                        "open": 必要ならばウィンドウを開く
                                     Note: "open" は割り込み的に発生する。
                                     term++close および term++openを参照。
                   "term_opencmd"    "term_finish" が "open" のときにウィンド
                                     ウを開くために使用されるコマンド: バッファ
                                     番号が入る "%d" を含む必要がある、例
                                     "10split|buffer %d": 指定されていない場合
                                     は "botright sbuf %d" が使用される
                   "term_highlight"  "Terminal" の代わりにハイライトグループと
                                     して使える
                   "eof_chars"       すべてのバッファ行が書き込まれた後に端末
                                     に送られるテキスト。設定されていないとき
                                     は MS-Windows では CTRL-D が使用される。
                                     Pythonでは CTRL-Z もしくは "exit()" を使
                                     用する。シェルでは "exit" を使用する。常
                                     に CR が追加される。
                                     "exit".  A CR is always added.
                   "ansi_colors"     GUI カラーモードで使われる ANSI パレット
                                     を定義する 16 個のカラー名もしくは 16 進
                                     数コード。g:terminal_ansi_colors を参
                                     照。
                   "tty_type"        (MS-Windowsのみ): 使用する pty を指定す
                                     る。値については 'termwintype' を参照。
                   "term_api"        terminal-api 機能の関数名プリフィック
                                     ス。term_setapi() を参照。

                method としても使用できる:
                        GetCommand()->term_start()

                戻り値の型: Number


term_wait({buf} [, {time}])                                     term_wait()
                {buf} で保留となっている更新が処理されるのを待つ。
                {buf} の扱いについては term_getsize() と同じ。
                {time} は更新が届くのを待つ、ミリ秒単位での長さ。設定されてい
                ない場合は 10 ミリ秒が使用される。

                method としても使用できる:
                        GetBufnr()->term_wait()

                戻り値の型: Number

==============================================================================
3. 端末通信                                      terminal-communication

端末内で実行中のジョブと通信するには、いくつかの方法がある:
term_sendkeys() でテキストやエスケープシーケンスをVimからジョブに送信する。
- JSON APIを使用して、エンコードされたコマンドをジョブからVimに送信する。
client-server 機構を使う。これは、XサーバーとMS-Windowsのマシンで動作する。


Vim からジョブへ: term_sendkeys()
                                                        terminal-to-job
これにより、端末内で実行中のジョブをリモート制御することができる。これは一方向
の機構である。ジョブは Vim に合図することで表示を更新することができる。例えば、
シェルが端末内で実行されている場合、次の操作を実行できる:
        call term_sendkeys(buf, "ls *.java\<CR>")

これは、キーを受け取ったときに正しいことをする適切な状態になるようなジョブを必
要とする。上記の例では、シェルはコマンドの入力を待つ必要がある。

この目的のために作成されたジョブでは、JSON APIエスケープシーケンスを別の方向で
使用できる。例:
        call term_sendkeys(buf, "\<Esc>]51;["response"]\x07")


ジョブから Vimへ: JSON API
                                                        terminal-api
ジョブは特殊なエスケープシーケンスを使用してJSONをVimに送ることができる。JSON
は、Vimが理解できるコマンドをエンコードする。そのようなメッセージの例:
        <Esc>]51;["drop", "README.md"]<07>

本体は常にリストになっており、終わりを見つけやすい: ]<07>
<Esc>]51;msg<07> シーケンスは "Emacs shell" のためにxtermによって予約されてい
る。私たちがここでやっていることに似ている。

現在サポートされているコマンド:

        call {funcname} {argument}

                ユーザー定義関数を {argument} で呼び出す。
                関数は2つの引数で呼び出される: 端末のバッファ番号とデコードさ
                れたJSON引数 {argument} である。
                デフォルトでは、関数名は端末API用に意図されていない関数を誤っ
                て呼び出すのを避けるため、"Tapi_" で始まる必要がある。これは、
                term_setapi() で変更できる。
                ユーザー関数は引数の正常性チェックをする必要がある。
                関数は term_sendkeys() を使って返信を送り返すことができる。
                JSONでの例:
                        ["call", "Tapi_Impression", ["play", 14]]
                次のように定義された関数を呼び出す:
                        function Tapi_Impression(bufnum, arglist)
                          if len(a:arglist) == 2
                            echomsg "impression " .. a:arglist[0]
                            echomsg "count " .. a:arglist[1]
                          endif
                        endfunc
                :echo からの出力は、再描画によって消去されるかもしれない。
                :echomsg を使い、:messages でそれを見ることができる。

        drop {filename} [options]

                Vimに :drop コマンドのようにファイルを開かせる。
                {filename} が既にウィンドウで開かれている場合、そのウィンドウ
                に切り替える。それ以外の場合は、{filename} を編集するための新
                しいウィンドウを開く。
                Note ジョブとVimの両方がカレントディレクトリを変更する可能性が
                あるので、フルパスを使用することをお勧めする。

                [options] は新しくウィンドウを開いた時にだけ使われる。与える場
                合、それは辞書でなければならない。++opt と同様に、これらのエ
                ントリは認識される:
                  "ff"          ファイルフォーマット: "dos" か "mac" か "unix"
                  "fileformat"  同上。
                  "enc"         'fileencoding' を上書きする。
                  "encoding"    同上。
                  "bin"         'binary' を設定する。
                  "binary"      同上。
                  "nobin"       'binary' をリセットする。
                  "nobinary"    同上。
                  "bad"         不正な文字のための振る舞いを指定する。
                                ++bad を参照。

                JSONでの例:
                        ["drop", "path/file.txt", {"ff": "dos"}]

Vimにこのエスケープシーケンスを送信させるトリック:
        exe "set t_ts=\<Esc>]51; t_fs=\x07"
        let &titlestring = '["call","Tapi_TryThis",["hello",123]]'
        redraw
        set t_ts& t_fs&

理論的根拠: コマンドや式を許可しないのはなぜか? セキュリティ上の問題が生じる
可能性があるため。
                                                terminal-autoshelldir
これを使用して、カレントディレクトリをシェルから Vim に渡すことができる。こ
れを .vimrc に置く:
        def g:Tapi_lcd(_, path: string)
            if isdirectory(path)
                execute 'silent lcd ' .. fnameescape(path)
            endif
        enddef

そして、bash の初期化ファイルには:
        if [[ -n "$VIM_TERMINAL" ]]; then
            PROMPT_COMMAND='_vim_sync_PWD'
            function _vim_sync_PWD() {
                printf '\033]51;["call", "Tapi_lcd", "%q"]\007' "$PWD"
            }
        fi

または、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"
            }
        fi

または、fish の場合は:
        if test -n "$VIM_TERMINAL"
            function _vim_sync_PWD --on-variable=PWD
                printf '\033]51;["call", "Tapi_lcd", "%s"]\007' "$PWD"
            end
        end


クライアントサーバー機能を使う
                                                terminal-client-server
これは、v:servername が空でない場合にのみ機能する。必要に応じて、端末を開く前
に次のように設定することができる:
        call remote_startserver('vim-server')

$VIM_SERVERNAME はサーバー名を渡すために端末内に設定される。

ジョブでは、次のようなことをおこなうことができる:
        vim --servername $VIM_SERVERNAME --remote +123 some_file.c
これによりファイル "some_file.c" が開き、123行目にカーソルが置かれる。

==============================================================================
4. リモートテスト                                       terminal-testing

VimのほとんどのテストはVimのなかでスクリプトを実行している。テスト対象のコード
と干渉してしまうような、幾つかのテストではこれは機能しない。これを避けるために
端末ウィンドウ内でさらにVimを実行している。そのテストではキーストロークを端末
に送信し、その結果として端末画面の状態が変わるのを検査する。

関数

term_sendkeys()       端末にキーストロークを送信する (tmap の影響を受けない)
term_wait()           端末画面が更新されるのを待つ
term_scrape()         端末画面の内容を検査する


==============================================================================
5. 画面ダンプの差分                                     terminal-diff

場合によっては、Vimが正しい文字を画面に表示するかどうかテストするのは面倒かも
しれない。例えば、構文のハイライト。これを簡単にするために、端末の画面ダンプを
取ってそれを予想される画面ダンプと比較することが可能である。

Vimはウィンドウのサイズ、テキスト、色、その他の属性を表示する。Vimの画面サイ
ズ、フォント、その他のプロパティは関係ない。したがって、この機構はシステム間で
移植可能である。従来のスクリーンショットでは、フォントサイズやフォントファミ
リーなど、すべての違いが反映される。


Vimの画面ダンプテストを書く
                                                        terminal-dumptest
例については、src/testdir/test_syntax.vim の Test_syntax_c() 関数を参照。主要
な部分は:
- テストするファイルを作成する。構文のハイライトをテストするのに便利である。空
  のバッファでVimを起動することもできる。
- 特定のサイズの端末でVimを実行する。デフォルトは75桁で20行である。これはダン
  プが常にこのサイズであることを確認する。RunVimInTerminal() 関数がこれを処理
  する。Vimコマンドの引数を渡す。
term_sendkeys() を使用して任意のコマンドをVimに送信する。例えば:
        call term_sendkeys(buf, ":echo &lines &columns\<CR>")
- VerifyScreenDump() を使用して、画面が期待どおりの状態になっていることを確認
  する。これは、参照する画面ダンプが src/testdir/dumps/ ディレクトリに存在する
  ことを前提としている。".dump" なしの名前を渡す。テスト関数の名前とシーケンス
  番号を使用してファイルがどのようなテストで使用されているかを知ることができ
  る。
- コマンド送信と状態の確認を繰り返す。
- 最後に StopVimInTerminal() を呼び出してVimを停止する。

初めてこれを行うときにはスクリーンダンプはまだありません。空のファイルを作成す
る。例:
        touch src/testdir/dumps/Test_function_name_01.dump

テストが失敗したら、参照ダンプと失敗したダンプを比較するコマンドを提供する。
例:
        call term_dumpdiff("failed/Test_func.dump", "dumps/Test_func.dump")

カレントディレクトリを src/testdir に設定して、Vimでこのコマンドを使用する。
テストに満足したら、参照の代わりに失敗したダンプを移動する:
        :!mv failed/Test_func.dump dumps/Test_func.dump


画面ダンプを作成する
                                                        terminal-screendump
画面ダンプを作成するには、端末でVim (または他のプログラム)を実行し、目的の状態
を表示させる。その後、term_dumpwrite() 関数を使用して画面ダンプファイルを作
成する。例:
        :call term_dumpwrite(77, "mysyntax.dump")

この "77" は端末のバッファ番号である。それを見るためには :ls! を使用する。

term_dumpload() で画面ダンプを見ることができる:
        :call term_dumpload("mysyntax.dump")

Vimがまったく同じ画面を表示していることを確認するには、まったく同じ方法でVimを
再度実行し、目的の状態を表示する。次に、別のファイル名を使用して画面ダンプを再
度作成する:
        :call term_dumpwrite(88, "test.dump")

ファイルがまったく同じものであることを主張するには assert_equalfile() を使う:

        call assert_equalfile("mysyntax.dump", "test.dump")

違いがある場合、v:errors はエラーメッセージを含む。


画面ダンプを比較する
                                                terminal-diffscreendump
assert_equalfile() は、何が違うのかを簡単に見分けることはできない。問題を見
つけるには、term_dumpdiff() を使用する:
        call term_dumpdiff("mysyntax.dump", "test.dump")

これで3つの部分からなるウィンドウが開く:
1.  1番目のダンプの内容
2.  1番目と2番目のダンプの差
3.  2番目のダンプの内容

通常、2番目の部分で何が違うかを見ることができる。1番目または2番目ダンプの位置
に関連付けるには 'ruler' を使用する。文字は違いの種類を示す:
        X       異なる文字
        >       1番目にはカーソルがあるが、2番目にはカーソルがない
        <       2番目にはカーソルがあるが、1番目にはカーソルがない
        w       文字の幅が異なる (単一 対 2倍幅)
        f       文字色が異なる
        b       背景色が異なる
        a       属性が異なる (ボールド、下線、反転など)
        ?       両方に文字がない
        +       1番目に文字がない
        -       2番目に文字がない

あるいは、"s" を押して、1番目と2番目のダンプを入れ替える。これを何度か実行し
て、テキストの文脈における相違を見つけ出すことができる。

==============================================================================
6. デバッグ                             terminal-debug terminal-debugger

Vim のウィンドウでソースコードを表示しながらプログラムを gdb でデバッグするの
に、端末デバッグプラグインが使用できる。これは Vim の中だけで完結するので、SSH
接続が1つあればリモートで機能する。

+terminal 機能がない場合、プラグインは可能であれば "prompt" バッファタイプを
使用する。実行中のプログラムは、新しく開かれた端末ウィンドウを使用する。詳細は
termdebug-prompt を参照。


はじめに
                                                        termdebug-starting
以下のコマンドでプラグインを読み込む:
        packadd termdebug
.vimrc ファイルからプラグインを読み込む時は、"!" 属性を追加する:
        packadd! termdebug
                                                        :Termdebug
デバッグを開始するには :Termdebug または :TermdebugCommand に続けてコマン
ド名を入力する。例:
        :Termdebug vim

これにより2つのウィンドウが開く:

gdb のウィンドウ
                "gdb vim" を実行した端末ウィンドウ。ここでは直接 gdb とやりと
                りできる。バッファ名は "!gdb"

プログラムのウィンドウ
                実行したプログラムの端末ウィンドウ。gdb 内で "run" をしてプロ
                グラムの I/O が発生するとこのウィンドウに反映される。その内容
                は gdb の制御下にない。バッファ名は "debugged program" である。

現在のウィンドウはソースコードを表示するのに使われる。gdb が一時停止した際に、
可能ならばその場所が表示される。現在の位置を示すためにハイライトグループ
debugPC を使って目印が使用される。

現在のウィンドウの内容が変更されると、現在の gdb の位置を表示するために別のウィ
ンドウが開く。:Winbar を使ってウィンドウツールバーを追加することができる。

実行中のプログラムを操作するにはその端末にフォーカスを合わせる。以降の操作は普
通の端末ウィンドウと同様である。

デバッガの終了は、通常は gdb のウィンドウで "quit" とタイプすると、開いている
2つのウィンドウが閉じられる。

一度にアクティブにできるデバッガは1つだけである。

                                                termdebug-timeout
gdb の起動方法によっては、termdebug の起動時間が異なる場合がある。
gdb の起動プロセスに時間が掛かりすぎる場合に termdebug が停止しないように、設
定可能なタイムアウトが含まれている。このタイムアウトは、10 ミリ秒の倍数で設定
できる:
    let g:termdebug_config['timeout'] = 500 # 500 * 10 ミリ秒 = 5 秒。

デフォルトのタイムアウトは 3000 ミリ秒である。
                                                        :TermdebugCommand
デバッグ中のコマンドに特定のコマンドを与える場合は、:TermdebugCommand コマン
ドの後にコマンド名と追加パラメータを使用できる。
        :TermdebugCommand vim --clean -c ':set nu'

:Termdebug と:TermdebugCommand はオプションの "!" をサポートしている。
gdbウィンドウで一時停止せずにコマンドをすぐに開始する (そしてカーソルはデバッ
グされたウィンドウに表示される) 例えば:
        :TermdebugCommand! vim --clean

すでに実行中の実行可能ファイルにgdbをアタッチするか、コアファイルを使用するに
は、追加の引数を渡す。例:
        :Termdebug vim core
        :Termdebug vim 98343

引数が指定されていない場合、gdbウィンドウが表示される。このウィンドウでは、例
えば、gdbの file コマンドを使って、どのコマンドを実行するか指定する必要があ
る。


セッション例
                                                        termdebug-example
Vim の "src" ディレクトリ内で作業を開始し、Vim をビルドする:
        % make
デバッグシンボルが存在することを確認する。通常は、$CFLAGS に "-g" が含まれるこ
とを意味する。

Vimを起動する:
        % ./vim

termdebug プラグインを読み込んで、Vimのデバッグを開始する:
        :packadd termdebug
        :Termdebug vim
これで、3つのウィンドウが表示される:
    source  - 開始直後はボタン付きウィンドウツールバーがある
    gdb     - ここに gdb コマンドを入力できる
    program - 実行されたプログラムはこのウィンドウを使用する

CTRL-W CTRL-W またはマウスを使用して、ウィンドウ間でフォーカスを移動できる。
gdbウィンドウにフォーカスを当てて、次のように入力する:
        break ex_help
        run
Vim は programウィンドウで実行を開始する。そこにフォーカスを置いて入力する:
        :help gui
Gdbはex_helpブレークポイントまで実行する。sourceウィンドウにex_cmds.cファイル
が表示される。ブレークポイントが設定されている目印欄に赤い "1 " のマーカーが表
示される。デバッガが停止した行がハイライトされる。今すぐプログラムを進めること
ができる。マウスを使おう: ウィンドウツールバーの "Next" ボタンをクリックする。
デバッガがソースコードの行を実行すると、ハイライトされる。

forループがハイライトされるまで、"Next" を数回クリックする。カーソルを
"eap->arg" の最後に置き、ツールバーの "Eval" をクリックする。これが表示される:
        "eap->arg": 0x555555e68855 "gui"
こうすることで、ローカル変数の値を調べることができる。また、gdbウィンドウに
フォーカスを当てて、"print" コマンドを使用することもできる。例:
        print *eap
マウスポインタの動きがうまくいっていれば、マウスがgdbで評価できるテキストの上
に置かれたときにVimはバルーンを表示する。

次に、sourceウィンドウに戻り、forループの後の最初の行にカーソルを置いて、次の
ように入力する:
        :Break
新しいブレークポイントを示す ">>" マーカーが表示される。ツールバーの "Cont" を
クリックして、コードをブレークポイントまで実行させる。

より高度なコマンドをgdbウィンドウに入力することができる。例えば、次のように入
力する:
        watch curbuf
ツールバーの "Cont" をクリックする (または、gdbウィンドウで "cont" と入力す
る)。do_ecmd() にある "curbuf" の値が変更されるまで、実行が継続される。この
ウォッチポイントを再度削除するには、gdbウィンドウで次のように入力する:
        delete 3

gdbウィンドウに次のように入力すると、スタックが表示される:
        where
スタックフレームを移動する。例えば:
        frame 3
sourceウィンドウには、より深いレベルに呼び出された時点のコードが表示される。


コードをステップ実行する
                                                        termdebug-stepping
gdb ウィンドウにフォーカスを移しコマンドを入力する。一般的なものは以下:
CTRL-C        プログラムを中断する
- next          現在の行を実行し、次の行(の手前)で停止する
- step          現在の行を実行し、次の文(の手前)で停止する。関数の内側に入る
- until         現在の行を通過する、または指定位置を通過する、または現在のス
                タックフレームに戻るまで実行する
- finish        現在の関数を抜けるまで実行する
- where         スタックを表示する
- frame N       N 番目のスタックフレームに移動する
- continue      実行を再開する

                                                :Run :Arguments
ソースコードを表示するウィンドウで、これらのコマンドをgdbの制御に使用できる:
 :Run [args]      [args] または以前の引数でプログラムを実行する
 :Arguments {args}  次の :Run のために引数を設定する
 :Break       カーソル位置にブレークポイントを設定する
 :Break {position}
                指定位置にブレークポイントを設定する
 :Tbreak      カーソル位置に一時的なブレークポイントを設定する
 :Tbreak {position}
                指定位置に一時的なブレークポイントを設定する
 :Clear       カーソル位置のブレークポイントを削除する
 :Step        gdb の "step" コマンドを実行する
 :Over        gdb の "next" コマンドを実行する (:Next は Vim のコマンド)
 :Until       gdb の "until" コマンドを実行する
 :Finish      gdb の "finish" コマンドを実行する
 :Continue    gdb の "continue" コマンドを実行する
 :Stop        プログラムを中断する

'mouse' が設定されている場合、プラグインはこれらのエントリを持つウィンドウツー
ルバーを追加する:
  Step          :Step
  Next          :Over
  Finish        :Finish
  Cont          :Continue
  Stop          :Stop
  Eval          :Evaluate
この方法で、マウスを使用して最も一般的なコマンドを実行できる。マウスのクリック
を有効にするには、'mouse' オプションを設定する必要がある。
このツールバーの設定については、termdebug_winbar を参照。
                                                                :Winbar
開いている他のウィンドウにウィンドウツールバーを追加することができる:
  :Winbar

gdbがソース行で停止し、現在ソースコードを表示しているウィンドウがない場合、ソー
スコード用の新しいウィンドウが作成される。これは、ソースコードウィンドウのバッ
ファが変更され、破棄できない場合でも発生する。

gdbは各ブレークポイントに番号を与える。Vim内では、赤い背景で、目印欄に表示され
る。次のgdbコマンドを使用できる。
- info break    ブレークポイントの一覧
- delete N      ブレークポイント N を削除
また、カーソルがブレークポイントの行にある場合は :Clear コマンドを使うことが
できる。または、右クリックのメニュー項目 "Clear breakpoint" を使用することもで
きる。


変数を検査する
                                        termdebug-variables :Evaluate
 :Evaluate          カーソルの下の式を評価する
 K                  上に同じ (無効にする場合は termdebug_map_K を参照)
 :Evaluate {expr}   {expr} を評価する
 :'<,'>Evaluate     ビジュアル選択したテキストを評価する

これは gdb ウィンドウで "print" コマンドを使ったのに相当する。
:Evaluate は :Ev に短縮できる。


スタックフレームの移動
                                termdebug-frames :Frame :Up :Down
 :Frame [frame]       フレームを選択する。[frame] は、フレーム番号、アドレ
                        ス、または関数名 (デフォルト: カレントフレーム)
 :Up [count]          [count] フレーム上へ (デフォルト: 1; カレントを呼び出
                        したフレーム)
 +                    同上 (無効にするには termdebug_map_plus を参照)
 :Down [count]        [count] フレーム下へ (デフォルト: 1; カレントによって
                        呼び出されるフレーム)
 -                    同上 (無効にするには termdebug_map_minus を参照)


その他のコマンド
                                                        termdebug-commands
 :Gdb      gdb ウィンドウに移動する
 :Program    デバッグ中のプログラムウィンドウに移動する
 :Source     ソースコードウィンドウにジャンプする、ウィンドウがなければ作成
             する
 :Asm      逆アセンブルウィンドウにジャンプする、ウィンドウがなければ作成す
             る
 :Var      ローカル変数と引数変数のあるウィンドウにジャンプし、なければ作成
             する。このウィンドウは、プログラムが停止されるたびに更新される

イベント
                                                        termdebug-events
4 つのautocmdが使える:
        au User TermdebugStartPre  echomsg 'debugging starting'
        au User TermdebugStartPost echomsg 'debugging started'
        au User TermdebugStopPre   echomsg 'debugging stopping'
        au User TermdebugStopPost  echomsg 'debugging stopped'

                                                TermdebugStartPre
TermdebugStartPre               デバッグ開始前。
                                すでにデバッガが開始しているもしくはデバッガコ
                                マンドが実行できない場合は発行されない。
                                                TermdebugStartPost
TermdebugStartPost              デバッグの初期化後。
                                :Termdebug あるいは :TermdebugCommand 経由
                                で ! 修飾子付きで実行された場合は gdb 内で提供
                                コマンドが動き出す前に発行される。
                                                TermdebugStopPre
TermdebugStopPre                デバッグの終了前で、gdb が終了する時、多くの場
                                合は gdb window で "quit" コマンドを発行した
                                後。
                                                TermdebugStopPost
TermdebugStopPost               デバッグの終了後、gdb 関連ウィンドウが閉じ、デ
                                バッグのバッファが消去されデバッグ前の状態が復
                                帰した時。


カスタマイズ
                                termdebug-customizing g:termdebug_config
以前は、構成にいくつかのグローバル変数が使用されていた。これらは非推奨であり、
g:termdebug_config 辞書の使用が推奨される。g:termdebug_config が存在する場合、
他のグローバル変数は使用されない。推奨される方法は、空の辞書から始めることであ
る:
        let g:termdebug_config = {}

次に、以下のように辞書にエントリを追加することができる。非推奨のグローバル変数
名については、念のため記載している。g:termdebug_config の使用に切り替える場合
は、古い変数名を見つけてその値を引き継ぎ、非推奨の変数を削除することができる。


プロンプトモード
                                                termdebug-prompt
+terminal 機能がサポートされていない場合や MS-Windows上の場合、gdbは
'buftype' が "prompt" に設定されたバッファで動作する。これは少し違った働きをす
る:
- コマンドを入力している間、gdbウィンドウは挿入モードになる。<Esc> でノーマル
  モードにして、バッファ間を移動したり、コピー/ペーストなどをおこなうことがで
  きる。a や i のような挿入モードを開始するコマンドでgdbコマンドの編集に戻
  る。
- デバッグ中のプログラムは別のウィンドウで実行される。MS-Windowsでは、これは新
  しいコンソールウィンドウである。Unixでは、+terminal 機能が利用可能な場合、
  端末ウィンドウが開いてデバッグされたプログラムを実行する。

                                                termdebug_use_prompt
プロンプトモードは、+terminal 機能が有効な場合でも使用できる:
        let g:termdebug_config['use_prompt'] = v:true
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebug_use_prompt = v:true


ただし、後者の形式は将来のリリースでは非推奨になる。


マッピング
termdebug プラグインは、いくつかのデフォルトマッピングを有効にする。
termdebug セッションが終了すると、これらのマッピングはすべて元の値にリセットさ
れる。

                                        termdebug_map_K termdebug-mappings
K へのバッファローカル (:map-local) マッピングがすでに存在している場合を除
き、K キーは通常 :Evaluate にマップされている。これが不要な場合は:
        let g:termdebug_config['map_K'] = v:false
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebug_map_K = v:false

ただし、後者の形式は将来のリリースでは非推奨になる。

                                                termdebug_map_minus
- へのバッファローカルマッピングがすでに存在している場合を除き、- は通常
:Down にマップされている。これが不要な場合は:
        let g:termdebug_config['map_minus'] = v:false

                                                termdebug_map_plus
+ へのバッファローカルマッピングがすでに存在している場合を除き、+ は通常 :Up
にマップされている。これが不要な場合は:
        let g:termdebug_config['map_plus'] = v:false

                                                termdebug_disasm_window
Asm ウィンドウをデフォルトで表示させたい場合、"disasm_window" フラグに 1 を設
定する。"disasm_window_height" エントリを使用してウィンドウの高さを設定できる:

        let g:termdebug_config['disasm_window'] = v:true
        let g:termdebug_config['disasm_window_height'] = 15
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebug_disasm_window = 15

ただし、後者の形式は将来のリリースでは非推奨になる。

1以上の任意の値を設定でき、その値が Asm ウィンドウの高さになる。
カレントウィンドウに十分な水平方向のスペースがある場合、垂直方向に分割され、
Asm ウィンドウがソースコードウィンドウと並べて表示される (高さのオプションは使
用されない)。

                                                termdebug_variables_window
Var ウィンドウをデフォルトで表示させたい場合、"variables_window" フラグに 1 を
設定する。"variables_window_height" エントリを使用してウィンドウの高さを設定で
きる:
        let g:termdebug_config['variables_window'] = v:true
        let g:termdebug_config['variables_window_height'] = 15
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebug_variables_window = 15

ただし、後者の形式は将来のリリースでは非推奨になる。

1 以上の任意の値を設定でき、その値が Var ウィンドウの高さになる。
カレントウィンドウに十分な水平方向のスペースがある場合、垂直方向に分割され、
Var ウィンドウがソースコードウィンドウと並べて表示される (高さのオプションは使
用されない)。


通信
                                                termdebug-communication
Vim が gdb と通信するために他に隠されたバッファが使用される。バッファ名は "gdb
communicate" である。デバッガが壊れてしまうので、このバッファを削除しないこと。

gdb は奇妙な動作をしているが、プラグインはその問題を回避するために最善を尽くし
ている。
例えば、gdbウィンドウで "continue" と入力した後に、CTRL-C を使用して実行中のプ
ログラムを中断することができる。しかし、MIコマンド "-exec-continue" を使用した
後、CTRL-C を押しても中断しない。したがって、通信チャネルを使用する代わりに、
:Continue コマンドに "continue" が使用されていることが分かる。


GDBコマンド
                                                        g:termdebugger
gdb コマンド以外のデバッガを使うには、:Termdebug を実行する前に
g:termdebug_config の "debugger" エントリか "g:termdebugger" 変数を変更する:
        let g:termdebug_config['command'] = "mygdb"
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebugger = "mygdb"

ただし、後者の形式は将来のリリースでは非推奨になりる。

コマンドに引数が必要な場合はリストを使用する:
        let g:termdebug_config['command'] = ['rr', 'replay', '--']
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebugger = ['rr', 'replay', '--']

gdb がデバッガで適切に動作するように、いくつかの引数が追加される。それらを変更
したい場合は、引数リストをフィルタリングする関数を追加する:
        let g:termdebug_config['command_filter'] = MyDebugFilter

引数を追加したくないが、"pty" を設定する必要がある場合は、関数を使用して必要な
引数を追加する:
        let g:termdebug_config['command_add_args'] = MyAddArguments
この関数はいままでの引数のリストと、ptyの名前である2番目の引数とともに呼ばれ
る。
                                                        gdb-version
gdb と完全互換のあるデバッガのみが使える。Vim は gdb の操作に GDB/MI インター
フェイスを使用する。"new-ui" コマンドには、gdbバージョン7.12以降が必要である。
このエラーが発生した場合:
        Undefined command: "new-ui". Try "help".~
あなたの gdb が古すぎる。


カラー
                                                hl-debugPC hl-debugBreakpoint
目印の色は以下のハイライトグループで調整できる:
- debugPC               現在の位置
- debugBreakpoint       ブレークポイント

'background' オプションが "light" の時のデフォルトは以下のとおり:
  hi debugPC term=reverse ctermbg=lightblue guibg=lightblue
  hi debugBreakpoint term=reverse ctermbg=red guibg=red

'background' オプションが "dark" の時は以下のとおり:
  hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
  hi debugBreakpoint term=reverse ctermbg=red guibg=red


ショートカット
                                                        termdebug_shortcuts
TermDebugSendCommand() 関数を使用して、任意のウィンドウで動作する gdb を制御す
る独自のショートカット(マッピング)を定義できる。例:
        map ,w :call TermDebugSendCommand('where')<CR>
引数は gdb コマンド。


ポップアップメニュー
                                                        termdebug_popup
デフォルトでTermdebugプラグインは 'mousemodel' を "popup_setpos" に設定し、こ
れらのエントリをポップアップメニューに追加する:
        Set breakpoint          :Break
        Clear breakpoint        :Clear
        Evaluate                :Evaluate
これを望まない場合は、以下で無効にする:
        let g:termdebug_config['popup'] = 0
g:termdebug_config がない場合は、以下を使用できる:
        let g:termdebug_popup = 0

ただし、後者の形式は将来のリリースでは非推奨になる。


デフォルトの目印の変更
                                                        termdebug_signs
Termdebug は、signcolumn のブレークポイント ID の 16 進数を使用してブレークポ
イントを表す。"0xFF" より大きい場合は、実際には記号用の画面セルが 2 つしかない
ため、"F+" と表示される。
代わりに 10 進数のブレークポイントの目印を使用することもできる。その場合、99
より大きい ID は "9+" と表示される。

ブレークポイントの目印をカスタマイズして、signcolumn に >> を表示するには:
        let g:termdebug_config['sign'] = '>>'
10 進数 (基数 10) のブレークポイントの目印を使用するには:
        let g:termdebug_config['sign_decimal'] = 1
変数 g:termdebug_config がまだ存在しない場合は、以下を使用できる:
        let g:termdebug_config = {'sign': '>>'}
同様に 10 進数の目印を有効にするには:
        let g:termdebug_config = {'sign_decimal': 1}


ウィンドウツールバー
                                                        termdebug_winbar
デフォルトでは、マウスが有効な場合、Termdebug プラグインはウィンドウツールバー
を作成する (:Winbar を参照)。これを望まない場合は、次のようにして無効にする:

        let g:termdebug_config['winbar'] = 0


Vimのウィンドウ幅
                                                        termdebug_wide
デバッグを開始した際に Vim のウィンドウ幅を変更し、垂直分割を利用するには次の
ように設定する:
        let g:termdebug_config['wide'] = 163
g:termdebug_config がない場合は、以下を使用できる:
  let g:termdebug_wide = 163

ただし、後者の形式は将来のリリースでは非推奨になる。

これは :Termdebug を実行した際に 'columns' を 163 に設定する。元の値はデバッ
ガが終了する際に復元される。

幅の値が設定されていて、'columns' がすでに幅の値より大きい場合、'columns' を変
更せずに垂直分割が使用される。

幅の値を1に設定することで 'columns' の変更なしに垂直分割が使える。これは端末が
Vimによってサイズ変更できない場合に便利である。


カーソル位置のポップアップウィンドウで評価する
                                                termdebug_evaluate_in_popup
デフォルトでは、:Evaluate は単に出力をエコーする。エンティティが大きい場合、
読みにくくなったり、切り捨てられたりする可能性がある。
あるいは、評価結果を現在のカーソル位置のポップアップウィンドウに出力することも
できる:
        let g:termdebug_config['evaluate_in_popup'] = v:true
これは "one-shot" 方式でも使用できる:
        func OnCursorHold()
          let g:termdebug_config['evaluate_in_popup'] = v:true
          :Evaluate
          let g:termdebug_config['evaluate_in_popup'] = v:false
        endfunc


コントリビュートする
                                                termdebug_contributing
termdebug の改善への貢献は大歓迎である。
ただし、開発プロセス中に作業を支援するために echo ステートメント (または同様
のもの) のようなメカニズムが必要になることはよくあることだ。
このため、以下が設定できる:
    let g:termdebug_config['debug'] = true

これにより、ソースコード内で使用できる DEBUG 変数が true に設定される。使
用例を以下に示す:
    if exists('g:termdebug_loaded')
      if DEBUG
        Echoerr('Termdebug already loaded.')
      endif
      finish
    endif


 vim:tw=78:ts=8:noet:ft=help:norl: