Skip to content

Commit 0df7614

Browse files
authored
Merge pull request #1112 from tsuyoshicho/update/20220619/channel
Update channel.{txt,jax}
2 parents 5317acc + 823f12e commit 0df7614

File tree

2 files changed

+428
-43
lines changed

2 files changed

+428
-43
lines changed

doc/channel.jax

Lines changed: 213 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*channel.txt* For Vim バージョン 9.0. Last change: 2022 Feb 27
1+
*channel.txt* For Vim バージョン 9.0. Last change: 2022 Jun 23
22

33

44
VIMリファレンスマニュアル by Bram Moolenaar
@@ -25,7 +25,9 @@ Netbeans インターフェイスもチャネルを使っています。|netbean
2525
12. ジョブオプション |job-options|
2626
13. ジョブを制御する |job-control|
2727
14. プロンプトバッファを使う |prompt-buffer|
28+
15. Language Server Protocol |language-server-protocol|
2829

30+
*E1277*
2931
{Vim が |+channel| 機能付きでコンパイルされたときのみ有効}
3032
`has('channel')` でこれを確認できる
3133
{Vim が |+job| 機能付きでコンパイルされたときのみ有効}
@@ -51,6 +53,7 @@ RAW 何も知られていない、Vim はメッセージの終わりを知らせ
5153
NL すべてのメッセージは NL (改行) 文字で終わります。
5254
JSON JSON エンコーディング |json_encode()|
5355
JS JavaScript スタイルの JSON 風のエンコーディング |js_encode()|
56+
LSP Language Server Protocol のエンコーディング |language-server-protocol|
5457

5558
共通の組み合わせ:
5659
- NL モードでパイプを介して接続されたジョブを使用します。例えば、スタイルチェッ
@@ -118,18 +121,22 @@ send を呼ぶたびに毎回コールバックを指定する代わりに、チ
118121
119122
|ch_status()| を使用して、チャネルを開くことができたかどうかを確認します。
120123

121-
{address} は "ホスト名:ポート番号" の形式です。例:"localhost:8765"
122-
123-
IPv6 アドレスを使う時、角カッコでくくった中に納めてください。
124-
たとえば、"[2001:db8::1]:8765"。
124+
*channel-address*
125+
{address} はドメイン名か IP アドレスで、それにポート番号を続ける、あるいは
126+
"unix:" プリフィックスを付けて Unix ドメインソケットパス にできます。例 >
127+
www.example.com:80 " ドメイン + ポート
128+
127.0.0.1:1234 " IPv4 + ポート
129+
[2001:db8::1]:8765 " IPv6 + ポート
130+
unix:/tmp/my-socket " Unix ドメインソケットパス
125131
126132
{options} はオプションのエントリを持つ辞書です: *channel-open-options*
127133

128-
"mode" でモード (通信フォーマット) を指定します: *channel-mode*
134+
"mode" は次のいずれかです: *channel-mode*
129135
"json" - JSONを使う (詳しくは下記を参照。もっとも使いやすい方法。既定)
130136
"js" - JS (JavaScript) エンコーディングを使用し、JSON よりも効率的。
131137
"nl" - NL 文字で終わるメッセージを使う
132138
"raw" - raw メッセージを使う
139+
"lsp" - language server protocol エンコーディングを使う
133140
*channel-callback* *E921*
134141
"callback" メッセージ受信時に他のハンドラーで扱われない時に呼ばれます
135142
(例えば、ID が0の JSON メッセージ)。これはチャネルのハンドル
@@ -139,8 +146,8 @@ IPv6 アドレスを使う時、角カッコでくくった中に納めてくだ
139146
endfunc
140147
let channel = ch_open("localhost:8765", {"callback": "Handle"})
141148
<
142-
"mode" が "json", "js" の時には、"msg" 引数は受信したメッセー
143-
ジの本文で、Vim の型に変換されています。
149+
"mode" が "json", "js", "lsp" の時には、"msg" 引数は受信した
150+
メッセージの本文で、Vim の型に変換されています。
144151
"mode" が "nl" の時には、"msg" 引数は NL を除く 1 つのメッセー
145152
ジです。
146153
"mode" が "raw" の時には、"msg" 引数はメッセージ全体を格納し
@@ -165,7 +172,19 @@ IPv6 アドレスを使う時、角カッコでくくった中に納めてくだ
165172
close_cb が呼び出されることがあります。プラグインは何とかこれ
166173
を処理する必要があり、これ以上データが来ていないことを知ってお
167174
くと便利です。
168-
*channel-drop*
175+
読み込むメッセージがあるか不明な場合は、try/catch ブロックを使
176+
います: >
177+
try
178+
let msg = ch_readraw(a:channel)
179+
catch
180+
let msg = 'no message'
181+
endtry
182+
try
183+
let err = ch_readraw(a:channel, #{part: 'err'})
184+
catch
185+
let err = 'no error'
186+
endtry
187+
< *channel-drop*
169188
"drop" メッセージをいつドロップするかを指定します:
170189
"auto" メッセージを処理するコールバックがない場合。
171190
"close_cb" もこのために考慮されます。
@@ -407,6 +426,7 @@ mode が "nl" の場合、同様の方法でメッセージを送信できます
407426
プロセス {訳注:サーバーのこと} はレスポンスを返し、チャネルのハンドラーに渡さ
408427
れます。
409428

429+
*channel-onetime-callback*
410430
メッセージを送信し、レスポンスを特定の関数で非同期的に取り扱うには以下のように
411431
します: >
412432
call ch_sendraw(channel, {string}, {'callback': 'MyHandler'})
@@ -444,10 +464,11 @@ v:none、RAW または NL チャネルでは空の文字列です。|ch_canread(
444464
コールバックメッセージがない場合、メッセージは破棄されます。これを回避するに
445465
は、チャネルにコールバックを追加します。
446466

447-
使用可能な RAW チャネルからすべての出力を読み込むには: >
467+
使用可能な RAW チャネルからすべての通常出力を読み込むには: >
448468
let output = ch_readraw(channel)
449-
エラー出力を読むには: >
469+
使用可能な RAW チャネルからすべてのエラー出力を読み込むには: >
450470
let output = ch_readraw(channel, {"part": "err"})
471+
Note チャネルが NL モードの場合、ch_readraw() は各呼び出しで1行しか返しません。
451472

452473
ch_read() と ch_readraw() はチャネルタイムアウトを使用します。その時間内に何も
453474
読み込めない場合、空の文字列が返されます。別のタイムアウトをミリ秒で指定するに
@@ -505,13 +526,16 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
505526
ンコードされる。この関数は生のチャネルでは使用できない。
506527
|channel-use| を参照。
507528
{handle} はチャネルもしくはチャネルを持つジョブであっても良い。
529+
"lsp" モードでチャネル使用時は、{expr}|Dict| でなければな
530+
らない。
508531
*E917*
509532
{options} は辞書でなければならない。また "callback" のエントリ
510533
を持ってはならない。また個別のリクエストに対して "timeout" を
511534
持つ事ができる。
512535

513536
ch_evalexpr() は応答を待ち、式をデコードした物が返される。エ
514-
ラーもしくはタイムアウトの場合は空文字列が返る。
537+
ラーもしくはタイムアウトの場合は空の |String|、あるいは "lsp"
538+
モードでチャネル使用時は空の |Dict| が返る。
515539

516540
Note 応答を待っている間、Vimは他のメッセージを処理する。これが
517541
トラブルを引き起こさないことを確認する必要がある。
@@ -563,10 +587,15 @@ ch_info({handle}) *ch_info()*
563587
ch_open() で開いた場合:
564588
"hostname" アドレスのホスト名
565589
"port" アドレスのポート
590+
"path" Unix ドメインソケットのパス
566591
"sock_status" "open" または "closed"
567592
"sock_mode" "NL", "RAW", "JSON" または "JS"
568593
"sock_io" "socket"
569594
"sock_timeout" タイムアウト(ミリ秒)
595+
596+
Note "path" は Unix ドメインソケットの場合にのみ存在し、通常は
597+
"hostname" と "port" が代わりに存在する。
598+
570599
job_start() で開いた場合:
571600
"out_status" "open", "buffered" または "closed"
572601
"out_mode" "NL", "RAW", "JSON" または "JS"
@@ -577,7 +606,7 @@ ch_info({handle}) *ch_info()*
577606
"err_io" "out", "null", "pipe", "file" または "buffer"
578607
"err_timeout" タイムアウト(ミリ秒)
579608
"in_status" "open" または "closed"
580-
"in_mode" "NL", "RAW", "JSON" または "JS"
609+
"in_mode" "NL", "RAW", "JSON", "JS" または "LSP"
581610
"in_io" "null", "pipe", "file" または "buffer"
582611
"in_timeout" タイムアウト(ミリ秒)
583612

@@ -601,16 +630,20 @@ ch_logfile({fname} [, {mode}]) *ch_logfile()*
601630
{fname} へチャネルの挙動ログ出力を開始する。
602631
{fname} が空の場合、ロギングは停止する。
603632

604-
{mode} が省略されるか "a" の場合、ファイルへの追加になる。
605-
{mode} が "w" の場合、空のファイルへで開始される。
633+
{mode} が省略されるか "a" を含むか "o" の場合、ファイルへの追
634+
加になる。
635+
{mode} が "w" を含み "a" を含まない場合、空のファイルで開始さ
636+
れる。
637+
{mode} が "o" を含む場合、全ての端末出力が記録される。
638+
その他の場合は、興味深い端末出力のみがログに記録される。
606639

607640
ログメッセージを書き込むには |ch_log()| を使用する。UNIX で
608641
"tail -f" にてリアルタイムで何が行われているかが見える様に、
609642
ファイルはメッセージ毎にフラッシュされる。
610643

611644
最初期にログを有効にし、初期化中に端末から何を受信したのかを参
612-
照するには、|--cmd| を使う: >
613-
vim --cmd "call ch_logfile('logfile', 'w')"
645+
照するには、|--log| ("ao" モードを使用) を使う: >
646+
vim --log logfile
614647
<
615648
この関数は |sandbox| 内では無効である。
616649
Note: チャネルとの通信はファイルに格納される。これには、あなた
@@ -626,11 +659,8 @@ ch_open({address} [, {options}]) *ch_open()*
626659
チャネルを返す。失敗をチェックするには |ch_status()| を使用す
627660
る。
628661

629-
{address} は文字列で "localhost:8765" のように "ホスト名:ポー
630-
ト" の形式である。
631-
632-
IPv6 アドレスを使う時、角カッコでくくった中に納めること。
633-
たとえば、"[2001:db8::1]:8765"。
662+
{address} は文字列で、受け付け可能な形式は |channel-address|
663+
を参照のこと。
634664

635665
{options} が与えられる場合は辞書でなければならない。
636666
|channel-open-options| を参照。
@@ -675,6 +705,17 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
675705
|channel-use| を参照。
676706
{handle} はチャネルもしくはチャネルを持つジョブであっても良い。
677707
チャネルは開いていなければならない。
708+
"lsp" モードでチャネル使用時は、{expr}|Dict| でなければな
709+
らない。
710+
711+
チャネルのモードが "lsp" の場合、辞書を返す。それ以外は空の文
712+
字列を返す。{options} に "callback" の項目が存在する場合、リク
713+
エストメッセージのIDを含む辞書を返す。IDはLSPサーバーへキャン
714+
セルのリクエスト(必要な場合)を送るのに使うことができる。エラー
715+
のときは空の辞書を返す。
716+
717+
{expr} に対して応答メッセージを受けないのであれば、{options}
718+
に "callback" 項目を指定しないこと。
678719

679720
|method| としても使用できる: >
680721
GetChannel()->ch_sendexpr(expr)
@@ -1365,5 +1406,155 @@ Shift-CTRL-W を使用します)。ウィンドウを離れるとき挿入モー
13651406
# シェルコマンドの受け付けを開始する。
13661407
startinsert
13671408
1409+
==============================================================================
1410+
15. Language Server Protocol *language-server-protocol*
1411+
1412+
language server protocol の仕様は以下にあります:
1413+
1414+
https://microsoft.github.io/language-server-protocol/specification
1415+
1416+
各 LSP プロトコルメッセージは単純な HTTP ヘッダ で始まり JSON-RPC フォーマット
1417+
にエンコードされたペイロードが続きます。次で説明されています:
1418+
1419+
https://www.jsonrpc.org/specification
1420+
1421+
Vim |Dict| 内の LSP のリクエスト/通知メッセージをエンコードして LSP JSON-RPC
1422+
メッセージ に入れて送信をするのと LSP JSON-RPC 応答/通知メッセージの受信とデ
1423+
コードをして Vim |Dict| 内に収めるには、|channel-mode| を "lsp" に設定して LSP
1424+
サーバーに接続します。
1425+
1426+
|channel-mode| を "lsp" に設定したチャネルからメッセージを受信したたなら、Vim
1427+
は HTTP ヘッダを処理し、JSON-RPC ペイロードをデコードして Vim |Dict| 型に格納
1428+
し、|channel-callback| 関数もしくは指定された |channel-onetime-callback| 関数
1429+
を呼びます。|ch_evalexpr()||ch_sendexpr()| 関数を用いてチャネルからメッセー
1430+
ジを送信した時には、Vim は HTTP ヘッダを付与し Vim の式を JSON にエンコードし
1431+
ます。Vim が組み込み型を JSON へエンコードあるいはデコードする方法の詳細につい
1432+
ては、|json_encode()||json_decode()| を参照してください。
1433+
1434+
'lsp' モードを使用してチャネルを開くには、|ch_open()| の引数 {options}
1435+
'mode' 項目を 'lsp' にします。例: >
1436+
1437+
let ch = ch_open(..., #{mode: 'lsp'})
1438+
1439+
'lsp' モードを使用したチャネルをジョブで開くには、|job_start()| の引数
1440+
{options} の 'in_mode' と 'out_mode' 項目を 'lsp' にします。例: >
1441+
1442+
let cmd = ['clangd', '--background-index', '--clang-tidy']
1443+
let opts = {}
1444+
let opts.in_mode = 'lsp'
1445+
let opts.out_mode = 'lsp'
1446+
let opts.err_mode = 'nl'
1447+
let opts.out_cb = function('LspOutCallback')
1448+
let opts.err_cb = function('LspErrCallback')
1449+
let opts.exit_cb = function('LspExitCallback')
1450+
let job = job_start(cmd, opts)
1451+
1452+
Note ジョブが LSP メッセージを標準出力に、非LSPメッセージを標準エラーに出す場
1453+
合、チャネルのコールバック関数は両方のメッセージフォーマットを適切に扱うか、上
1454+
記にあるように "out_cb" と "err_cb" で個別のコールバック関数を使って扱わなくて
1455+
はなりません。
1456+
1457+
サーバーにむけて JSON-RPC リクエストの同期送信をするには、|ch_evalexpr()| 関数
1458+
を使います。この関数は応答を待ちサーバーからのレスポンスメッセージをデコードし
1459+
て返します。|channel-timeout| を使うかあるいは引数 {options}'timeout'
1460+
フィールドに値を設定することで応答の待ち時間の制御ができます。レスポンスがタイ
1461+
ムアウトした場合、空の |Dict| が返ります。例: >
1462+
1463+
let req = {}
1464+
let req.method = 'textDocument/definition'
1465+
let req.params = {}
1466+
let req.params.textDocument = #{uri: 'a.c'}
1467+
let req.params.position = #{line: 10, character: 3}
1468+
let defs = ch_evalexpr(ch, req, #{timeout: 100})
1469+
if defs->empty()
1470+
... <handle failure>
1471+
endif
1472+
1473+
Note リクエストメッセージには 'id' フィールドを指定してはいけません。指定した
1474+
場合、Vimは内部的に生成する識別子の値を上書きします。Vimは現在、'id' フィール
1475+
ドの種別として数値のみをサポートしています。RPC のリクエストの成功と失敗の両方
1476+
でコールバック関数が呼び出されます。
1477+
1478+
JSON-RPC リクエストをサーバーに送信して応答を非同期に処理するには、
1479+
|ch_sendexpr()| 関数を使ってコールバック関数を与えます。リクエストメッセージに
1480+
"id" フィールドが設定されている場合は、Vimは内部的に生成する識別子の値を上書き
1481+
します。この関数はメッセージに使用した識別子を含む Dict を返します。キャンセル
1482+
リクエストを LSP サーバーに送信する(必要な場合)にも使用できます。例: >
1483+
1484+
let req = {}
1485+
let req.method = 'textDocument/hover'
1486+
let req.id = 200
1487+
let req.params = {}
1488+
let req.params.textDocument = #{uri: 'a.c'}
1489+
let req.params.position = #{line: 10, character: 3}
1490+
let resp = ch_sendexpr(ch, req, #{callback: 'HoverFunc'})
1491+
1492+
|ch_sendexpr()| 関数を使用してサーバーに送信した非同期 LSP リクエストの未処理
1493+
のものをキャンセルするには、リクエスト時に返されたIDとともに |ch_sendexpr()|
1494+
関数でキャンセル用メッセージをサーバーに送信します。例: >
1495+
1496+
" 補完リクエストを送信
1497+
let req = {}
1498+
let req.method = 'textDocument/completion'
1499+
let req.params = {}
1500+
let req.params.textDocument = #{uri: 'a.c'}
1501+
let req.params.position = #{line: 10, character: 3}
1502+
let reqstatus = ch_sendexpr(ch, req, #{callback: 'LspComplete'})
1503+
" キャンセル通知を送信
1504+
let notif = {}
1505+
let notif.method = '$/cancelRequest'
1506+
let notif.id = reqstatus.id
1507+
call ch_sendexpr(ch, notif)
1508+
1509+
JSON-RPC 通知メッセージをサーバーに送信するには、|ch_sendexpr()| 関数を使いま
1510+
す。サーバーは通知のレスポンスメッセージを送信しません。"callback" 項目は指定
1511+
をしてはいけません。例: >
1512+
1513+
call ch_sendexpr(ch, #{method: 'initialized'})
1514+
1515+
サーバーからの JSON-RPC リクエストメッセージへの返答には |ch_sendexpr()| 関数
1516+
を使用します。レスポンスメッセージの中の 'id' フィールドの値はサーバーへのリク
1517+
エストメッセージの応答メッセージからコピーします。例: >
1518+
1519+
let resp = {}
1520+
let resp.id = req.id
1521+
let resp.result = 1
1522+
call ch_sendexpr(ch, resp)
1523+
1524+
サーバーからの JSON-RPC 通知メッセージは |channel-callback| 関数を通じて伝達さ
1525+
れます。
1526+
1527+
ユースケースに依存しますが、ch_evalexpr(), ch_sendexpr(), ch_sendraw() 関数を
1528+
同じチャネルで使うことができます。
1529+
1530+
LSP リクエストメッセージは以下のフォーマット(Vim Dict で表現)を持ちます。
1531+
"params" フィールドはオプションです: >
1532+
1533+
{
1534+
"jsonrpc": "2.0",
1535+
"id": <number>,
1536+
"method": <string>,
1537+
"params": <list|dict>
1538+
}
1539+
1540+
LSP レスポンスメッセージは以下のフォーマット(Vim Dict で表現)を持ちます。
1541+
"result" と "error" フィールドはオプションです: >
13681542
1543+
{
1544+
"jsonrpc": "2.0",
1545+
"id": <number>,
1546+
"result": <vim type>
1547+
"error": <dict>
1548+
}
1549+
1550+
LSP 通知メッセージは以下のフォーマット(Vim Dict で表現)を持ちます。"params"
1551+
フィールドはオプションです: >
1552+
1553+
{
1554+
"jsonrpc": "2.0",
1555+
"method": <string>,
1556+
"params": <list|dict>
1557+
}
1558+
1559+
<
13691560
vim:tw=78:ts=8:noet:ft=help:norl:

0 commit comments

Comments
 (0)