coc.nvim の CocAction ってなんだ？

簡単に言えば、エラーとかワーニングが表示されたときに、チョチョっと直してくれるいわゆる **クイックフィックス** のような機能を呼び出すために使うそうです。

正確に言えば、Language Server Protocol の Code Action Request に該当する機能を呼び出すものだと思われます（理解はできていないので、正確にとは言い辛いのですが...）。

```vim
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')
```

* [neoclide/coc.nvim](https://github.com/neoclide/coc.nvim)

## 定義

coc.nvim のドキュメントを検索しても見つかりませんでした。いろいろ探し回った結果 Visual Studio Code と Language Server Protocol の仕様書の中に類似の用語が見つかりました。

Visual Studio Code の機能うち Code Navigation に分類される Code Action の記述が、具体的にどういった機能を提供してくれているか、書かれています。

> [Visual Studio Code > Code Navigation > **Code Action**](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)
> ワーニングとエラーは、問題を修正するのに役立つコードアクション（クイックフィックスとも呼ばれる）を提供します。これらのワーニングとエラーは、エディタの左側の欄外に電球のようなマークとして表示されます。電球をクリックすると、コードアクションのオプションが表示されるか、アクションが実行されます。
> Warnings and Errors can provide Code Actions (also known as Quick Fixes) to help fix issues. These will be displayed in the editor in the left margin as a lightbulb. Clicking on the lightbulb will either display the Code Action options or perform the action.
> 

LSP の仕様書のうち Language Features に分類される Code Action Request の記述が、内部でどういった動作をしているか、雰囲気を伝えてくれています。

> [Language Server Protocol Specification > Language Features > **Code Action** Request](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction)
> コードアクションリクエストは、与えられたテキスト文書と範囲に対するコマンドを計算するために、クライアントからサーバに送信されます。コードアクションリクエストによって送信されるコマンドは通常、問題を修正したり、コードを美しくしたり/リファクタリングしたりするためのコード修正です。
> The code action request is sent from the client to the server to compute commands for a given text document and range. These commands are typically code fixes to either fix problems or to beautify/refactor code.



## 背景

公式ドキュメントの Example vim configuration にある以下の設定をいれると...

```vim
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')
```

* [neoclide/coc.nvim](https://github.com/neoclide/coc.nvim)

`:Format` を押下したタイミングで Formatter が走ってくれます。各言語ごとに Formatter の設定は必要になります。例えば JavaScript は、以下の通りです。

* [coc.nvim で Vue.js を使う。](https://qiita.com/domodomodomo/items/36c488c1efc2fb8d1714)

`'format'` 以外にも使えるアクションがいくつかありそうです。一覧は以下のリンクをご参照ください。

```
"format"					*coc-action-format*


	Format current buffer using the language server.
	Return `v:false` when format failed.
```

* [https://github.com/neoclide/coc.nvim/blob/.../doc/coc.txt#L1396-L1667](https://github.com/neoclide/coc.nvim/blob/d1bbbf6b61a3886390eaf32d85902822ccd072d4/doc/coc.txt#L1396-L1667)


## 補足

`:Format` を打つと `:call CocAction('format')` が実行されます。

```vim
command! -nargs=0 Format :call CocAction('format')
```

* `command` はコマンドラインモードで呼び出すコマンドを定義するそうです。
* `!` は、それ以前に同じコマンド名 `Format` があった場合、それを上書きするそうです。
* `-nargs=0` は、引数がないことを表すそうです。

上書きっていいのかなと思ったのですが vimscript は、この `!` をよく見かけます。そう言う文化なのでしょうか。Python では、属性名にプライベート `__` ではなくプロテクテッド `_` が使われるように。

このあたりの動作は以下の本で勉強させていただきました。vim の help だけでは自分には難解すぎて読んでもわからず、本当に助かりました。

* [BOOTH > Vimが好きになる本 > P.120 コマンドの定義](https://booth.pm/ja/items/1513974)

## 検索

`CocAction` が検索するも何かよくわからず調べていました。

Step 1. `:help CocAction` で検索する。


```
:{range}CocAction  [{only}]			*:CocAction*

		Get codeActions of current document in actions list,
		with optional {range}.

		{only} can be 'quickfix' or 'source' as CodeActionKind.
```



Step 2. `:help codeActions` で検索する。

```
"codeActions" [{visualmode}] [{only}]		*coc-action-codeActions*

	Get codeActions of current range.

	{visualmode} can be result of |visualmode()| for visual selected
	range, When it's empty string or not exists use current line.

	{only} can be used to limit codeActionKind, possible values:
	'refactor', 'quickfix' and 'source'.
```

Step 3. s を除いた `:help codeAction` で検索する。

```
"codeAction" [{mode}] [{only}]			*coc-action-codeAction*

	Prompt for a code action and do it.

	{mode} should be result of visualmode(), when used in visualmode,
	could be empty string or v:null for none visualmode.

	{only} can be title of a codeAction or list of CodeActionKind.
```

Step 4.

ここで詰まってしまい、しばらくネットをさまよっていました。以下の記事から、どうも coc.nvim に限定された用語ではなさそうなことがわかり...

* [vim-lsp の導入コストを下げるプラグイン vim-lsp-settings を書いた。 - Qiita](https://qiita.com/mattn/items/e62b9f16bc487a271a7f)

単純に code action で検索したら LSP や VS Code の記事に辿り着きました。以上になります。ありがとうございました。