Helix Editor のカスタマイズ

:::note warn
随時更新用
:::

# はじめに

Rust や Python などを Vim や NeoVim で書けるようにセットアップしようと思ったが、思ったより理想に近づけるには道のりが長い…。。色々言語対応するとなると余計に…。
という事で、サクッと行けるやつない？？って事で、ちょくちょく見かける Rust 製エディタの Helix を触ってみる事にした。

:::note info
特に言語周りに関しては、今後も使ってみて追記する。
:::

# 環境

* Windows 11 Pro 23H2
* Helix 24.3

# インストール

## Windows

```powershell
winget install Helix.Helix
```

# 環境設定

ユーザーコンフィグは、Windows では `%APPDATA%\helix\cofnig.toml`、Linux と macOS では `~/.config/helix/config.toml` にあるものが認識される。
Helix では、ここまでパスを指定してファイルを開かなくても、コマンドで開けるようになっている。

```
:config-open
```

https://docs.helix-editor.com/configuration.html

例によって dotfiles 管理する。

https://github.com/takavfx/dotfiles/blob/main/helix/config.toml

## テーマカラー

テーマカラー自体のその場での設定は `:theme <theme-name>` でできるが、Helix エディタを開いたときにその任意のテーマカラーを開く

```toml:config.toml
theme = "everforest_dark"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/e4d723b5-15fc-4e2a-9514-36d53e9dbb72.png)

### テーマいろいろ

|everforest_dark|base16_transparent|
|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/bf1f5f46-1504-3b29-bb70-209c13d24f7c.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/9fc28759-78ee-7af7-a5e3-5cadc25c22a2.png)|
|**onedark**|**dracula**|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/0dbcdf22-2016-6f92-eddf-f1fba06b6d1b.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/bd09ca82-dc79-6ac5-34a5-dcf4496f4398.png)|

## ライン番号を相対 (`relative`) にする

lazy.nvim のデフォルトの様に、相対でのライン番号表記に切り替える。
`<number> x` で `<number>` 文選択したい場合などの「指標を絶対値から計算しながら入力」といったことよりも直感的になって良い。

```toml:config.toml
[editor]
line-number = "relative"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/cf910627-680d-1885-0203-f291a767c86a.png)


## モードに応じたカーソルタイプの変更

インサートモードではなるべく入力位置と前後の文字関係をハッキリ見たいというのがある。
そうした場合には `bar` タイプのカーソルが欲しくなる。
また、範囲選択時には `underline` タイプのカーソルが欲しくなる。
この場合は、`[editor.cursor-shape]` として設定する。

```toml:config.toml
[editor.cursor-shape]
insert = "bar"
normal = "block" # デフォルトで block なので実際には指定する必要はない
select = "underline" 
```

| タイプ | イメージ |
|:-:|:-:|
|`block`|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/9ee7fd32-0b88-0879-b5f1-1f23afeaea8d.png)|
|`bar`|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/fa05eff5-424b-43ba-2a32-55ec9be06c51.png)|
|`underline`|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/26cfa75a-4981-2b2d-c088-6a661bba262c.png)|

# プロジェクトレベルの環境設定

作業ディレクトリ以下に `.helix` フォルダを作成し、ここに `config.toml` や `languages.toml` を配置することで、全体設定をこの階層下の設定でうわ書くことができる。

特に言語設定がプロジェクトごとに存在する場合は、こちらを共有しながら作業するといいだろう。

![output6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/1cd28101-a70e-c01e-2003-962c10c37994.gif)


# 言語対応

## 設定の基本

Helix には、デフォルトで LSP (Language Server Protocol) が実装されている。
ただ、言語対応を設定するには各自でやる必要がある。

細かい設定は、Windows であれば `%APPDATA%\helix\language.toml` を作成し、そこに記述していく。
Linux/macOS は `~/.cofnig/helix/language.toml` に設置する。

ここら辺は Helix のレポジトリにサンプルがあるので、それを参考にするのが良い。

https://github.com/helix-editor/helix/blob/master/languages.toml

これも dotfile 管理する。

https://github.com/takavfx/dotfiles/blob/main/helix/languages.toml

## サポートされている言語

https://docs.helix-editor.com/lang-support.html

## Rust

まずはバイナリ版 [rust-analyzer](https://rust-analyzer.github.io) をインストールする。
色々方法があるが、rustup でもインストールできて楽なので、これを使う。
もうこれだけで Rust 用の LSP は機能する様になる。爆速！便利！

```powershell
rustup component add rust-analyzer
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/1e71b5fd-6aad-2941-ca94-8de6d136b36e.png)

### 詳細設定

細かい設定は `languages.toml` に書く。
まぁ、僕は Rust に関してはデフォルトに準拠で満足しているので、特に設定するものはない。

```toml:languages.toml
[[language]]
name = "rust"
```

### その他

`:run-shell-command cargo run` を実行すると、Rust のデバッグ実行ができるが、出力がある場合は次の様に表示される。
この表示は `<Esc>` で消える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/bcd6d779-3c0a-c05e-fc52-f3a6e11b922b.png)

## Python

Python は、リンタとフォーマット両方で [Ruff](https://docs.astral.sh/ruff/) を導入する。
Ruff も Rust 製という事もあるが、かなり爆速で気に入っている。

以下はかみ砕いた状態で記述するが、要は以下のフローで設定を行う。

1. LSP サーバーのインストール
2. コンフィグでのフォーマッターの設定


### LSP サーバー周りのインストールと設定

Python では LSP として、デフォルトでは `pylsp` を必要とする。

環境を確認したい場合 `hx --health python` で確認することが出来る。
pylsp が動作出来ない環境 (= PATH パス上に見つからない状況) だと次の様にエラーが発生する。

```
Configured language servers:
  ✘ pylsp: 'pylsp' not found in $PATH
Configured debug adapter: None
Configured formatter: None
Highlight queries: ✓
Textobject queries: ✓
Indent queries: ✓
```

#### vritualenv 環境の作成

Pythno の場合、まずやる事と言えば仮想環境を作る事。
デフォルトの `python -m venv .venv` か PDM などのツール (`pdm init`) を使って環境を作る。

```powershell
python -m venv .venv
.venv\Script\activate
```

さらに必須モジュールを追加する。

```powershell
pip install python-lsp-server
```

`hx --health python` で確認すると以下の結果が得られる。

```
Configured language servers:
  ✓ pylsp: D:\tools\scripts\python\.venv\Scripts\pylsp.exe
Configured debug adapter: None
Configured formatter: None
Highlight queries: ✓
Textobject queries: ✓
Indent queries: ✓
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/85f79385-e137-4b73-9785-d37a67c4b2d9.png)

この時点で、自動補完やヘルプの表示などのサポートは得られる状態になる。
この自動補完等には [Jedi](https://github.com/davidhalter/jedi) を使っているとのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/a620ef91-dc1e-287e-ccd8-ef3e7de7d36f.png)

#### LSP と 関連モジュールのインストール

Ruff のための `python-lsp-ruff` をインストールする。
もちろん Ruff もインストールする。

https://github.com/python-lsp/python-lsp-ruff

```powershell
pip install ruff python-lsp-ruff
```

この時点で、`:format` コマンドでフォーマットが効くようになる。

![output4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/ec326091-1b34-db96-3ac1-188cc5ba5c87.gif)

:::note info
`python-lsp-ruff` に関しては、どうやらインストール時に既に認識するように設定されている様子。
また、`python-lsp-ruff` を使用有効にした場合リンタとフォーマッタ両方が Ruff から供給されることになるとのこと。
何かしら挙動の設定をしたくなったら、Ruff の設定を調べるとよさそう。

また、別に `autopep8` などを採用する場合は、デフォルトではオフになっている様子なので、各自で `languages.toml` の設定をする必要がある。
`python-lsp-server` + `python-lsp-ruff` を選択するメリットはここら辺の簡略化にもありそうだ。
:::

### 詳細設定

言語設定に関しては例によって `languages.toml` に記述していく。

#### 保存時のフォーマット

デフォルトでは、保存時にフォーマットをかけない設定になっているので、これを変更する。

```toml:languages.toml
[[language]]
name = "python"
auto-format = true
```

![output5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/b7ca5ff5-649c-d219-b383-127db3266ee5.gif)

## Svelte

### LSP サーバーのインストール

Svelte の LSP には Svelte 公式の [language-tools](https://github.com/sveltejs/language-tools) にある [Svelte Language Server](https://github.com/sveltejs/language-tools/tree/master/packages/language-server) を使用する。

```powershell
npm i -g svelte-language-server
```

`hx --health svelte` を実行すると以下の様になる。

```
Configured language servers:
  ✓ svelteserver: C:\Users\aurat\AppData\Local\Volta\bin\svelteserver.exe
Configured debug adapter: None
Configured formatter: None
Highlight queries: ✓
Textobject queries: ✘
Indent queries: ✓
```

この時点で、リンタや自動補完、フォーマッタなどが利用可能になっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/fe93471b-713d-4597-3b75-49d870e55ac8.png)


![output7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/29cc018b-3672-7d3c-7b35-26e442766f3a.gif)

#### `.js` や `.ts` との統合に対応する

`.js` や `.ts` にも同様に対応する場合は、次の様に `tsconfig.json`/`jsconfig.json` を編集する。

```powershell
npm i -g typescript-svelte-plugin
```

```json:tsconfig.json
{
    "compilerOptions": {
        "plugins": [{
            "name": "typescript-svelte-plugin"
        }]
    }
}
```


# その他

## ターミナルの活用

現状は、Vim や NeoVim の様に `:term` で起動できるような一体型のターミナルを作成することはできない。（結構ここに不満を持ってる人も多そう

現状はどうしようもないので、とりあえず Windows Terminal の分割機能で気を紛らわしている。

`<Ctr+Alt+->` で水平分割ができるので、まずはそれで分割する。

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/53007242-c439-c096-4d87-2cd077ffcd25.gif)

さらに下のエリアにフォーカスしている時に `<Shift+Alt+↓>` や `<Shift+Alt+↑>` で高さを下げたり上げられる。

![output3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/744e5110-3154-5b89-36d0-17ee67fb5654.gif)

ちなみに、分割のフォーカス変更は `<Alt+↑>`/`<Alt+↓>`。

# 最後に

あんまりカスタマイズできないからこそ迷うことがないというのもあるし、なにより動作がサクサクで速いというのがとてもいい。
[プラグイン機構が今後実装されたりするよう](https://github.com/helix-editor/helix/discussions/3806)なので、そこら辺の動向を注視したい。