こんにちは!今年の夏の初め、友人とfishを使うのが大好きなこと、そして設定しなくてもいいのが好きだという話をしていました。すると友人は、helixテキストエディタについても同じように感じていると言い、試してみることにしました。

もう3ヶ月使っていますが、ここにいくつかのメモを残します。

helixを選ぶ理由:言語サーバー

Helixを試してみようと思ったきっかけは、「定義へ移動」などの操作ができる言語サーバーのセットアップを試していたところ、VimやNeovimで快適に使える設定を作るのが大変だと感じたことです。

Vim/Neovimを20年使ってきて、「最初から自分でカスタム設定を構築する」「誰かの既存の設定システムを使う」の両方を試しましたが、Vimは好きでも、設定に一切手を加えなくてもそのまま使えることに魅力を感じました。

Helixには言語サーバーサポートが最初から組み込まれており、どんな言語でも「シンボルの名前を変更」などが簡単にできるのが快適です。

検索機能が優れている

Helixのお気に入りの機能のひとつが検索です。リポジトリ内のすべてのファイルから文字列を検索すると、一致するファイル群をスクロールしながら、各一致箇所の完全な文脈を確認できます。

helix-search.png

比較のため、これまで使っていたvimのripgrepプラグインの表示例です:

vim-ripgrep.png

その行の周辺の文脈が表示されません。

クイックリファレンスが便利

Helixで気に入っている点のひとつに、gを押すと移動先の候補をポップアップで表示してくれる機能があります。「定義へ移動」や「参照へ移動」をあまり使わないので、ショートカットを忘れがちだった私にはとても助かります。

goto.png

VimからHelixへの置き換え例

  • Helixにはma'aのようなマーク機能がないので、Ctrl+OCtrl+Iを使って前後のカーソル位置に移動しています。
  • Helixにもマクロ機能はあるようですが、以前マクロを使っていた場面ではすべてマルチカーソルを使うようにしています。毎回マクロを書くよりマルチカーソルの方が気に入っています。ドキュメント内の複数箇所を一括変更したい場合は、まず%で全体を選択し、次にsで正規表現を使って変更したい部分を選択し、まとめて編集します。
  • HelixにはNeovimスタイルのタブはありませんが、代わりに便利なバッファスイッチャー(<space>b)で目的のバッファに切り替えられます。Neovimスタイルのタブを実装するプルリクエストもあります。また、bufferline="multiple"という設定を使うと、gpgnで前後の「タブ」に移動したり、:bcで「タブ」を閉じたりできます。

Helixの気になる点

これまでHelixで気になった点をすべて挙げます。

  • :reflowの動作が、vimのgqによるテキスト整形ほど良くありません。特にリストでうまく機能しません。(GitHub issue
  • Markdownのリスト作成時、リスト項目の末尾でEnterを押しても次の項目が自動で作成されません。箇条書きリストには部分的な回避策がありますが、番号付きリストには対応するものがわかりません。
  • 永続的なアンドゥがまだ実装されていません。Vimではundofileを使って、終了後も変更を元に戻せますが、Helixにはまだこの機能がありません。(GitHub PR
  • ディスク上のファイルが変更されても自動で再読み込みされません。手動で:reload-all:ra<tab>)を実行する必要があります。大きな問題ではありません。
  • 時々パニックを起こします。週に1回程度で、このissueが原因かもしれません。

クラッシュ時の表示例:

thread 'main' panicked at helix-core/src/transaction.rs:499:9:
Positions [(2959, AfterSticky), (2959, AfterSticky)] are out of range for changeset len 2945!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Markdownリストとreflowの問題は、私がMarkdownリストを頻繁に編集するためによく発生しますが、それでもHelixを使い続けているので、そこまで大きなストレスにはなっていないようです。

思ったより簡単に移行できた

20年分のVimの筋肉記憶を再学習するのは大変ではないかと心配していました。

実際には予想以上に簡単でした。休暇中にちょっとしたサイドプロジェクトでHelixを使い始め、1〜2週間で違和感がなくなりました。VimとHelixを行き来するのは難しいかもしれませんが、最近はVimを使う必要がないので問題になるかはわかりません。

初めてHelixを試したときは、Vimに近いキーバインドを強制しようとしましたがうまくいきませんでした。「Helixの流儀」をそのまま覚える方がはるかに簡単でした。

今でも戸惑う点はあります。たとえば、wの「単語」の定義がVimとHelixで異なり、Helixでは単語の後のスペースも含みます。

ターミナルベースのテキストエディタを使う

長年は主にVim/NeovimのGUI版を使っていたので、ターミナル上でエディタを使うのは少し慣れが必要でした。

最終的に次のように決めました:

  1. プロジェクトごとに専用のターミナルウィンドウを使い、そのウィンドウ内のタブは基本的に同じ作業ディレクトリにする
  2. Helixのタブをターミナルウィンドウの最初のタブにする

この方法はかなり快適で、以前のワークフローより好みかもしれません。

私の設定

Neovimの数百行に及ぶ設定に比べて、自分の設定が非常にシンプルなのが嬉しいです。主に4つのキーボードショートカットだけです。

theme = "solarized_light"
[editor]
# Sync clipboard with system clipboard
default-yank-register = "+"

[keys.normal]
# I didn't like that Ctrl+C was the default "toggle comments" shortcut
"#" = "toggle_comments"

# I didn't feel like learning a different way
# to go to the beginning/end of a line so
# I remapped ^ and $
"^" = "goto_first_nonwhitespace"
"$" = "goto_line_end"

[keys.select]
"^" = "goto_first_nonwhitespace"
"$" = "goto_line_end"

[keys.normal.space]
# I write a lot of text so I need to constantly reflow,
# and missed vim's `gq` shortcut
l = ":reflow"

言語ごとの設定は別のlanguages.tomlで行っており、自動フォーマットの無効化などを指定しています。以下はPythonの設定例です:

[[language]]
name = "python"
formatter = { command = "black", args = ["--stdin-filename", "%{buffer_name}", "-"] }
language-servers = ["pyright"]
auto-format = false

今後の経過を見守る

まだ3ヶ月しか使っていないので、いつかVimに戻る可能性もあります。以前Nixへの移行に関する記事を書いたものの、8ヶ月ほどでHomebrewに戻った経験があります(ただし、1台の小さなサーバーでは今もNixOSを使っていて満足しています)。