1
- *channel.txt* For Vim バージョン 9.0. Last change: 2022 Feb 27
1
+ *channel.txt* For Vim バージョン 9.0. Last change: 2022 Jun 23
2
2
3
3
4
4
VIMリファレンスマニュアル by Bram Moolenaar
@@ -25,7 +25,9 @@ Netbeans インターフェイスもチャネルを使っています。|netbean
25
25
12. ジョブオプション | job-options |
26
26
13. ジョブを制御する | job-control |
27
27
14. プロンプトバッファを使う | prompt-buffer |
28
+ 15. Language Server Protocol | language-server-protocol |
28
29
30
+ *E1277*
29
31
{Vim が | +channel | 機能付きでコンパイルされたときのみ有効}
30
32
`has (' channel' )` でこれを確認できる
31
33
{Vim が | +job | 機能付きでコンパイルされたときのみ有効}
@@ -51,6 +53,7 @@ RAW 何も知られていない、Vim はメッセージの終わりを知らせ
51
53
NL すべてのメッセージは NL (改行) 文字で終わります。
52
54
JSON JSON エンコーディング | json_encode() |
53
55
JS JavaScript スタイルの JSON 風のエンコーディング | js_encode() |
56
+ LSP Language Server Protocol のエンコーディング | language-server-protocol |
54
57
55
58
共通の組み合わせ:
56
59
- NL モードでパイプを介して接続されたジョブを使用します。例えば、スタイルチェッ
@@ -118,18 +121,22 @@ send を呼ぶたびに毎回コールバックを指定する代わりに、チ
118
121
119
122
| ch_status() | を使用して、チャネルを開くことができたかどうかを確認します。
120
123
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 ドメインソケットパス
125
131
126
132
{options} はオプションのエントリを持つ辞書です: *channel-open-options*
127
133
128
- "mode" でモード (通信フォーマット) を指定します: *channel-mode*
134
+ "mode" は次のいずれかです: *channel-mode*
129
135
"json" - JSONを使う (詳しくは下記を参照。もっとも使いやすい方法。既定)
130
136
"js" - JS (JavaScript) エンコーディングを使用し、JSON よりも効率的。
131
137
"nl" - NL 文字で終わるメッセージを使う
132
138
"raw" - raw メッセージを使う
139
+ "lsp" - language server protocol エンコーディングを使う
133
140
*channel-callback* *E921*
134
141
"callback" メッセージ受信時に他のハンドラーで扱われない時に呼ばれます
135
142
(例えば、ID が0の JSON メッセージ)。これはチャネルのハンドル
@@ -139,8 +146,8 @@ IPv6 アドレスを使う時、角カッコでくくった中に納めてくだ
139
146
endfunc
140
147
let channel = ch_open("localhost:8765", {"callback": "Handle"})
141
148
<
142
- "mode" が "json", "js" の時には、"msg" 引数は受信したメッセー
143
- ジの本文で 、Vim の型に変換されています。
149
+ "mode" が "json", "js", "lsp" の時には、"msg" 引数は受信した
150
+ メッセージの本文で 、Vim の型に変換されています。
144
151
"mode" が "nl" の時には、"msg" 引数は NL を除く 1 つのメッセー
145
152
ジです。
146
153
"mode" が "raw" の時には、"msg" 引数はメッセージ全体を格納し
@@ -165,7 +172,19 @@ IPv6 アドレスを使う時、角カッコでくくった中に納めてくだ
165
172
close_cb が呼び出されることがあります。プラグインは何とかこれ
166
173
を処理する必要があり、これ以上データが来ていないことを知ってお
167
174
くと便利です。
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*
169
188
"drop" メッセージをいつドロップするかを指定します:
170
189
"auto" メッセージを処理するコールバックがない場合。
171
190
"close_cb" もこのために考慮されます。
@@ -407,6 +426,7 @@ mode が "nl" の場合、同様の方法でメッセージを送信できます
407
426
プロセス {訳注:サーバーのこと} はレスポンスを返し、チャネルのハンドラーに渡さ
408
427
れます。
409
428
429
+ *channel-onetime-callback*
410
430
メッセージを送信し、レスポンスを特定の関数で非同期的に取り扱うには以下のように
411
431
します: >
412
432
call ch_sendraw(channel, {string}, {'callback': 'MyHandler'})
@@ -444,10 +464,11 @@ v:none、RAW または NL チャネルでは空の文字列です。|ch_canread(
444
464
コールバックメッセージがない場合、メッセージは破棄されます。これを回避するに
445
465
は、チャネルにコールバックを追加します。
446
466
447
- 使用可能な RAW チャネルからすべての出力を読み込むには : >
467
+ 使用可能な RAW チャネルからすべての通常出力を読み込むには : >
448
468
let output = ch_readraw(channel)
449
- エラー出力を読むには : >
469
+ 使用可能な RAW チャネルからすべてのエラー出力を読み込むには : >
450
470
let output = ch_readraw(channel, {"part": "err"})
471
+ Note チャネルが NL モードの場合、ch_readraw() は各呼び出しで1行しか返しません。
451
472
452
473
ch_read() と ch_readraw() はチャネルタイムアウトを使用します。その時間内に何も
453
474
読み込めない場合、空の文字列が返されます。別のタイムアウトをミリ秒で指定するに
@@ -505,13 +526,16 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
505
526
ンコードされる。この関数は生のチャネルでは使用できない。
506
527
| channel-use | を参照。
507
528
{handle} はチャネルもしくはチャネルを持つジョブであっても良い。
529
+ "lsp" モードでチャネル使用時は、{expr} は | Dict | でなければな
530
+ らない。
508
531
*E917*
509
532
{options} は辞書でなければならない。また "callback" のエントリ
510
533
を持ってはならない。また個別のリクエストに対して "timeout" を
511
534
持つ事ができる。
512
535
513
536
ch_evalexpr() は応答を待ち、式をデコードした物が返される。エ
514
- ラーもしくはタイムアウトの場合は空文字列が返る。
537
+ ラーもしくはタイムアウトの場合は空の | String | 、あるいは "lsp"
538
+ モードでチャネル使用時は空の | Dict | が返る。
515
539
516
540
Note 応答を待っている間、Vimは他のメッセージを処理する。これが
517
541
トラブルを引き起こさないことを確認する必要がある。
@@ -563,10 +587,15 @@ ch_info({handle}) *ch_info()*
563
587
ch_open() で開いた場合:
564
588
"hostname" アドレスのホスト名
565
589
"port" アドレスのポート
590
+ "path" Unix ドメインソケットのパス
566
591
"sock_status" "open" または "closed"
567
592
"sock_mode" "NL", "RAW", "JSON" または "JS"
568
593
"sock_io" "socket"
569
594
"sock_timeout" タイムアウト(ミリ秒)
595
+
596
+ Note "path" は Unix ドメインソケットの場合にのみ存在し、通常は
597
+ "hostname" と "port" が代わりに存在する。
598
+
570
599
job_start() で開いた場合:
571
600
"out_status" "open", "buffered" または "closed"
572
601
"out_mode" "NL", "RAW", "JSON" または "JS"
@@ -577,7 +606,7 @@ ch_info({handle}) *ch_info()*
577
606
"err_io" "out", "null", "pipe", "file" または "buffer"
578
607
"err_timeout" タイムアウト(ミリ秒)
579
608
"in_status" "open" または "closed"
580
- "in_mode" "NL", "RAW", "JSON" または "JS "
609
+ "in_mode" "NL", "RAW", "JSON", "JS" または "LSP "
581
610
"in_io" "null", "pipe", "file" または "buffer"
582
611
"in_timeout" タイムアウト(ミリ秒)
583
612
@@ -601,16 +630,20 @@ ch_logfile({fname} [, {mode}]) *ch_logfile()*
601
630
{fname} へチャネルの挙動ログ出力を開始する。
602
631
{fname} が空の場合、ロギングは停止する。
603
632
604
- {mode} が省略されるか "a" の場合、ファイルへの追加になる。
605
- {mode} が "w" の場合、空のファイルへで開始される。
633
+ {mode} が省略されるか "a" を含むか "o" の場合、ファイルへの追
634
+ 加になる。
635
+ {mode} が "w" を含み "a" を含まない場合、空のファイルで開始さ
636
+ れる。
637
+ {mode} が "o" を含む場合、全ての端末出力が記録される。
638
+ その他の場合は、興味深い端末出力のみがログに記録される。
606
639
607
640
ログメッセージを書き込むには | ch_log() | を使用する。UNIX で
608
641
"tail -f" にてリアルタイムで何が行われているかが見える様に、
609
642
ファイルはメッセージ毎にフラッシュされる。
610
643
611
644
最初期にログを有効にし、初期化中に端末から何を受信したのかを参
612
- 照するには、| --cmd | を使う: >
613
- vim --cmd "call ch_logfile(' logfile', 'w')"
645
+ 照するには、| --log | ("ao" モードを使用) を使う: >
646
+ vim --log logfile
614
647
<
615
648
この関数は | sandbox | 内では無効である。
616
649
Note: チャネルとの通信はファイルに格納される。これには、あなた
@@ -626,11 +659,8 @@ ch_open({address} [, {options}]) *ch_open()*
626
659
チャネルを返す。失敗をチェックするには | ch_status() | を使用す
627
660
る。
628
661
629
- {address} は文字列で "localhost:8765" のように "ホスト名:ポー
630
- ト" の形式である。
631
-
632
- IPv6 アドレスを使う時、角カッコでくくった中に納めること。
633
- たとえば、"[2001:db8::1]:8765"。
662
+ {address} は文字列で、受け付け可能な形式は | channel-address |
663
+ を参照のこと。
634
664
635
665
{options} が与えられる場合は辞書でなければならない。
636
666
| channel-open-options | を参照。
@@ -675,6 +705,17 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
675
705
| channel-use | を参照。
676
706
{handle} はチャネルもしくはチャネルを持つジョブであっても良い。
677
707
チャネルは開いていなければならない。
708
+ "lsp" モードでチャネル使用時は、{expr} は | Dict | でなければな
709
+ らない。
710
+
711
+ チャネルのモードが "lsp" の場合、辞書を返す。それ以外は空の文
712
+ 字列を返す。{options} に "callback" の項目が存在する場合、リク
713
+ エストメッセージのIDを含む辞書を返す。IDはLSPサーバーへキャン
714
+ セルのリクエスト(必要な場合)を送るのに使うことができる。エラー
715
+ のときは空の辞書を返す。
716
+
717
+ {expr} に対して応答メッセージを受けないのであれば、{options}
718
+ に "callback" 項目を指定しないこと。
678
719
679
720
| method | としても使用できる: >
680
721
GetChannel()->ch_sendexpr(expr)
@@ -1365,5 +1406,155 @@ Shift-CTRL-W を使用します)。ウィンドウを離れるとき挿入モー
1365
1406
# シェルコマンドの受け付けを開始する。
1366
1407
startinsert
1367
1408
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" フィールドはオプションです: >
1368
1542
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
+ <
1369
1560
vim:tw=78:ts=8:noet:ft=help:norl:
0 commit comments