narrow
これは僕が最近かなりパワーを注いで開発していた、narrow という Atom package の宣伝記事です。
めちゃくちゃ良いです。ぜひ使ってください.( lazy-motion 作った時もそう思ってたけど結局使わななくなったが、今回は違うはず! )
基本的なドキュメントは wiki にアップデートしていく予定。
ですので、この記事の情報は古くなっていきます。
- 絞込み UI 自体は目新しくもない。Vim なら ctrlP や unite.vim( denite ), Emacs なら anything, helm があるし、CLI ツールでもそういうの( percol, peco, fzf ...) がある。
- 因みに僕は Emacs の頃に anything を、Vim の頃に unite.vim を使っていた。
- そもそも僕が最初に作ったのも、Vim の時に使っていた unite 的なものを Atom でも作れないかと実験的に作ったのだった。
- 2016年5月頃になんとなく作って、リリースした後、ずっと放置していた。僕自身は出来に満足しておらず、全く使っていなかった。
- 当時は vim-mode-plus でやることが沢山あり、narrow にかけている時間はなかった。
- 今年(2017年)になって、vim-mode-plus も年末一段落したのと、飽きてきたので、narrow の実験を本格的に再開することにした。
- 2ヶ月間ぶっ通しで narrow ばかりやっていた。お陰で自分自身はかなり気に入る出来になった。
概要
用語と役割達
-
narrow-provider
: アイテムを提供する。アイテムを決定するとそのアイテム(ファイル/ポジション)が開く。 -
narrow-ui
: 殆どの文脈で、narrow-editor
とイコール。- ユーザーの絞込みクエリに応じて、アイテムリストを更新する。
-
narrow-editor
やcontrol-bar
やシンタックスハイライト( Grammar で提供 ) を管理する
-
narrow-editor
: アイテムが表示されるテキストエディタ。クエリは最初の行に入力する。
active-editor と narrow-editor の関係
コントロールバー( Control bar )
それぞれショートカットが用意されていて、マウスオーバーするとツールチップ上にショートカットが表示されるが、覚えるまではマウスが便利です.
特徴
- helm や unite のような絞り込み UI を提供
- コードナビゲーションに重点を置いている
- 単一ファイルと紐づく provider は アクティブなテキストエディタが変わるとアイテムリストも自動更新される
- このお陰で、
symbols
は常に現在アクティブなエディタのシンボルが表示されるので minimap 的、table of content for current code 的に使える.
- このお陰で、
- アクティブエディタのカーソル位置と、
narrow-editor
の "選択中アイテム" を自動同期- まず
narrow:next-item
,narrow:previous-item
でnarrow-editor
にフォーカスがなくても、次、前のアイテムに移動できる様にしている - この時
narrow
以外のコマンドでカーソル移動しても、"次のアイテム"、"前のアイテム" が現在のカーソル位置を考慮して "次"、"前" を選んでくれる - 複数のファイルをまたいで検索、編集している時に「あれ、今何やってたっけ?」とか「いまアイテムリスト中のどこにいるんだっけか?」とならないように
- まず
- 直編集・反映機能( Direct edit )
-
narrow-editor
で編集して、保存すると、実際のファイルを更新 - 編集用に別の専用バッファを開かないで済むようにしている。直接編集、保存、反映の最短フローになる様に.
-
- キーボードナビゲーション
-
narrow-editor
にフォーカスしていない状態で、tab
,shift-tab
で次、前のアイテムに移動したり、narrow-editor
を閉じたり出来る
-
- 作者(僕)が拡張性にモチベーションがない
- 最近「それほんとに必要?」という考えになってきた。少数の組み込み provider がいい感じにちゃんと動けば、それで僕はとりあえず満足。
組み込みの provider
僕が普段使いしているのは scan
, search
, symbols
, git-diff-all
です。
概要と画像は以下にまとまっている
-
scan
: 現在のエディタをスキャン( 最初narrow:lines
がこの役割を担っていたが、こっちの方が良いのでlines
は削除した ) -
search
:ag
の検索結果を提供(ag
は自分で入れる必要ある ) -
atom-scan
:search
と一緒だが、Atom のatom.workspace.scan
を使って同じことをやっている。ちょっと遅いけど、ag
入れずに使える。 -
fold
: Fold の開始行をアイテムとして提供 -
git-diff
: 現在アクティブなエディタの git-diff が情報元。コアパッケージのgit-diff
の情報を利用 -
git-diff-all
: git-diff をプロジェクト全体で。( こっちはあとから作った。結果、単なるgit-diff
は僕は使わなくなった。) -
bookmarks
: コアパッケージのbookmarks
が情報元. なんちゃって provider であんまり便利じゃない。( 僕はbookmarks
機能使ってない ) -
symbols
: ctags で取れる関数定義箇所をアイテムとして提供. コアパッケージのsymbols-view:toggle-file-symbols
の narrow 版。 -
project-symbols
: プロジェクト全体のtags
ファイルからアイテムを提供 -
linter
: linter パッケージの情報を利用
ユースケース
Use case and flow of keystrokes にも幾つか例がある
minimap 的、 table of content for code 的な使い方( 常に開いておく )
関数の引数を一括で変更
同一ファイル内の関数の使用箇所、定義箇所を quick preview
やっぱり使わなくなった関数の削除
保存するとアイテムリストが変更されるので最初に検索しておいて、検索結果の narrow-editor
を見ながら
編集、保存、ctrl-cmd-n
( or tab
)で次のアイテムに移動を繰り返し、narrow-editor
のアイテムリストが空になれば DONE!
仕様( 作った後からかんがえた )
- Provider はアイテムを提供する
- 各アイテムは必ずファイルと、ポジションに紐付いていなければならない
- つまり "どのファイルのどのポジションを開く" という形式でオープンで出来る必要がある。
- "絞込UIでコマンド絞り込んで実行" みたいなのは対象外。やらない。
- 2種類の Provider ( boundToSingleFile vs Not boundToSingleFile )がある。
- 単一ファイルに紐付けられる( boundToSingleFile ) provider
- e.g.
scan
,fold
,symbols
. - プロジェクトや、ファイル名のヘッダ行は表示しない( 不要だから ).
- 基本的にこのプロバイダはバッファの内容が変更されるとアイテムリストが更新される( 保存の必要なし ).
-
symbols
は例外。保存しないと更新されない
-
- e.g.
- 複数ファイルに紐付けられる( Not boundToSingleFile ) provider
- e.g.
search
,atom-scan
,git-diff-all
. - プロジェクトヘッダやファイルヘッダを表示する
- 基本的にアイテムリストの更新はファイルの保存時に行われる. 保存の必要あり.
- e.g.
- 各 provider はそれ専用の( dedicated )
narro-ui
インスタンスを持つ。つまり Ui インスタンスは共有しない。 -
narrow-ui
は 常に 現在アクティブ( focus されている )なテキストエディタに紐付けられる( bound to editor).- そして、アクティブなエディタのカーソル移動を検知して、"選択中アイテム"をアップデートする( 自動同期 ).
-
narrow-editor
は 普通の エディタでなければならない- 通常のエディタで利用できている移動・編集コマンドやパッケージの機能を例外なく使える為にとても重要
- e.g. vim-mode-plus のコマンドが
narrow-editor
でも使えるように. - これまでに narrow-editor の Uiの改善や query-area と item-area の分離を試みて数回トライして毎回失敗したので学んだ.
- 本当は、query-editor と アイテムレンダリング用エディタを分けたかった。だがチャレンジして何度も負けて諦めた。
- Atom では エディタは pane-item で HTMLElement ならなんでもマウントできるので、Custom Element を作り、そこに Query input 用のミニエディタと、アイテムレンダリング用の mini じゃないエディタを埋め込んで、pane-item として pane に追加することもできて、実際やってみたら内部的には実装がスッキリするし、良い面もたくさんあった。しかし、これをやると、もう
narrow-editor
は 普通のエディタ としては扱われない。具体的にはatom.workspace.observeTextEditors
とかで observe できなくなるので、これを監視している vim-mode-plus や他の多くのパッケージがnarrow-editor
上で有効にならない。
スタートアップの流れ
-
narrow:scan
を実行 -
Scan
が実体化( instantiation ) され、専用の Ui も実体化される -
narrow-editor
が開く