未来から来た異星の魔法、「Cursorless」
(xeiaso.net)- RSI の再発で再びコーディングの入力方法を変えなければならなくなった状況で、VS Code 拡張機能 Cursorless が音声ベースのコード編集の中核ツールになった
- Cursorless はコードトークンに色と文字ベースの hat を付け、ユーザーが画面上の位置を声で指定し、削除・移動・挿入のような操作を行えるようにする
- 単純なカーソル移動より強力なのは、
green urge past green batのような経路指定と、言語の AST 認識を組み合わせて、関数・ラムダ・定義本体のような構造単位を扱える点にある - Talon コマンドを直接書けば、
async <destination>のような挿入や Go のメソッド宣言のような長い入力も、より短い 音声コマンド で自動化できる - 音声コーディングは発話すべき単語そのものをなくすことはできないが、コードを頭の中で理解するやり方により近い命令体系を作れる
RSI 再発と Cursorless を使うことになった文脈
- 新しい職場を始めるタイミングで RSI が再発し、以前のように技術文章の執筆に頼るのではなく、再びプログラミングする方法が必要になった
- Emacs ユーザーだが、今回はある特定の拡張機能ひとつのために Visual Studio Code を使っている
- その拡張機能が Cursorless であり、音声制御ソフトウェアと組み合わせることで AST レベルのコード編集 を可能にする
- 以前は Cursorless を主に画面移動にだけ使っていたが、今回は可能な作業全般により深く適用しようとしている
- Slack や Discord のメッセージにもこうした入力方式があればよいのに、という願いがある
hat、target、destination で位置を表現する方法
- Cursorless の基本単位は target と destination
- target は文書内の個別のアンカーを指す
- destination は特定の target を基準にした相対位置を意味する
- 文書のトークンには色と文字で構成された hat が付く
- hat の位置が名前を決める
- hat の色が曖昧さを解消する
- 例の JavaScript コードで
functionという単語のuの上に緑色の hat があるなら、その単語をgreen urgeと呼べる - この target を対象に、その単語を削除したり別の位置へ移動したりする命令を出せる
- この方式だけでも、音声で Vim の motion に近い操作が可能になる
AST 認識が生み出す構造的編集
- Cursorless の力は、単純な位置指定にとどまらず、経路(path) と言語の AST 認識を組み合わせて使える点にある
green urge past green batのような表現で、画面上のfunction fetchBlogの範囲を選択できる- 言語の AST 構造を理解するため、関数全体を削除したり別の位置へ移したりする作業も可能になる
visualize lambdasコマンドは、関数内のラムダを別個の構造単位として可視化する- AST 単位も target になるため、定義の本体を選択したあと、その範囲でリファクタリングを続けられる
- 例では、関数を非同期関数へ変えるリファクタリングが簡単になる
Talon コマンドで拡張する音声コーディング
- Cursorless と Talon を一緒に使うと、自分で音声コマンドを書ける
async <user.cursorless_destination>の例は、指定した destination の前に"async"を挿入するコマンドである
[state] async <user.cursorless_destination>:
user.cursorless_insert(cursorless_destination, "async")
- Talon コマンドは大きく二つの部分に分かれる
- pattern: ユーザーが話す単語
- capture: 発話内容から抽出する対象
- この例で pattern は
async、capture はasyncを挿入する宛先である <user.cursorless_destination>capture は、ある target の前後を指定できるようにする特殊な capture である- より複雑なコマンドも可能で、Go のメソッド宣言を作る Talon ルールが例として使われている
(method|meth) <user.letter> [<user.go_pointer>] [<user.go_visibility>] <user.text> [over] [<user.go_visibility>] named <user.text> [over]:
user.go_method(go_pointer or "", letter, go_visibility_1 or "public", text_1, go_visibility_2 or "public", text_2)
Go メソッド宣言とポインタ表現の実験
- Go ではメソッドは次のような形になる
func (reciever *Type) MethodName() {
// function body here or something
}
- Go には伝統的な意味でのメソッドがあるというより、特定の struct に名前空間化された receiver を受け取る関数がある、という説明が添えられている
- 自動化なしでこのコードを音声で入力しようとすると、長い命令を話さなければならない
state funk args word reciever space star hammer type over go right space hammer method name args go right brack enter
- Talon ルールを使えば、もっと短く言える
meth r raised type named method name over
- それでも発話すべき単語は多いが、入力はより効率的で、頭の中での概念化の仕方に近くなる
raisedは Go のポインタ概念を別の形で表現してみる実験である- Go のポインタ構文は C スタイルで、
*はポインタ値を通常の値へ下げる(lower)ために使い、&は通常の値をポインタ値へ上げる(raise)ために使う、という解釈を採っている - Go 向け Talon バインディングを新たに設計する中で、ポインタ値を raising/lowering の概念で統合して理解しやすくできるか実験している
- Go のポインタ構文は C スタイルで、
- GitHub Copilot Voice beta に参加し、Talon ベースの音声コーディングと比較してみたいと考えている
1件のコメント
Hacker Newsのコメント
投稿者です。ここまで反応が良いとは思っていなかった
興味があれば、実験中の Talon設定リポジトリ をここに置いてあります: https://github.com/Xe/invocations
いつかは、キーボードよりこういうやり方で作業するほうが、必須ではなくてもずっと痛みの少ない日が来そうだし、実用的な選択肢があると分かったのは良かった
こういう設定を見るたびに、自分のニューロダイバーシティは他の人たちとかなり違うのだと感じる。画面を理解して移動するために頭の中で維持しなければならない文脈や抽象化が膨大で、言語やIDE/CLIに何十年も慣れた状態でようやく可能になるように見える
「時間が経てばVimコマンドのように第二の本能になる」という部分も、本当にそうやって身につける必要がありそう。30年コンピュータを触ってきたけれど、このレベルの コーディング熟練度 は今でも混乱しつつ感嘆する
いまいちだったのか、それともVS Code側の解決策のほうがずっと良さそうに見えたのか知りたい
Cursorless自体にはあまり興味がない。VSCodeを使わないし、Vim/Evilモードのテキストオブジェクトも同じくらい強力で、しかも視覚的にはもっと騒がしくないからだ。この概念全体にはとても期待している
これは tree-sitter AST を使って、バッファの「部分」に対して操作を行うやり方のように見える
だとすると、Vim/Evilのテキストオブジェクトに非常に近いが、そこに音声の要素が加わった形だ
ここに「録音して後で実行」のような機能が付けば可能性は大きそう。キーボードでXの作業をしている間、次にやるべきYが画面に見えていて単純な作業なら、Yのコマンドを先に話しておき、Xが終わったあとでボタンを押して音声コマンドを実行できる。タイピングと発話を交互に行うよりずっと良い
タイピングと発話は異なる認知領域を使うし、文法を理解したあとのソフトウェア作成はそれほど言語的ではない。タイピングしながら同時に話せるならフロー状態に入りやすそうで、ある種の強化版 ラバーダックデバッグ のようにも見える。メモにも使えそうだ
Emacsパッケージが出てきそう
ただ、この領域に追いつくには時間がかかりそう。表示エンジンがCursorless式の表記を処理できず、tree-sitter統合もまだ成熟していない。自分で試した
それでもネイティブEmacs向けのものがあればいいのにと思う
Cursorlessそのものではないが、音声プログラミング に関する素晴らしい発表とデモがここにある: https://youtu.be/GM_siEPD4Ws?si=99ZhC1P4irOyu1pH
見ていて楽しいし、発表者はこの分野の現在の共通課題もよく扱っている
まだどう動くのかを完全に理解しようとしているところだ
キーボードの代わりに音声を使う avy に似ていて、そこにAST認識コマンドが付いたように聞こえる: https://karthinks.com/software/avy-can-do-anything/
その次にオーバーレイを常時表示にしようとしたけれど、どこかで行き詰まった
Cursorless作者の Strange Loop発表: https://www.youtube.com/watch?v=NcUJnmBqHTY
なぜ「urge」と「bat」を使うのか気になる
関連する文字で始まる適当な単語なら何でも使っていいわけではないのか?
詳しくはここ: https://whalequench.club/blog/2019/09/03/learning-to-speak-c...
以前、1日6〜8時間ずつ音声コーディングをしてみると、こういう 細かな最適化 の一つひとつがありがたく感じられる
最近の 視線追跡技術 なら、2秒以上見つめた位置にカーソルを置くだけでも十分ではないか?
運転や美術作品を見るときに視線が留まるという研究を思い出す
コーディング中にはそういう止まり方をすることが非常に多い
少なくとも3〜5個のボタンを検出できる、極めて反応が速く正確な視線追跡装置が必要になる: クリック、押す、離す、右移動、左移動
この文体は『Gödel, Escher, Bach』の亀とアキレスの対話パートにかなり似ていると感じる
52歳で、1995年から技術職で毎日タイピングしてきた。2000年ごろに反復運動障害を患い、キーボードの前で手首を載せる柔らかいパッドや、肘を置くスライド式の器具のような人間工学的補助具も試したが、まったく効果はなかった
その代わり、タイピングのやり方を変えた。手と手首をリラックスさせた状態にし、指を伸ばしてキーを押すのではなく腕を動かすようにしたところ、効果があった
今でも毎日たくさんタイピングしているが、20年間ずっと痛みはない。人それぞれではあるが、腕や手の使い方を変えることは大いに役立つ可能性がある
動きをより大きな筋肉群に任せられるなら、たいていはそうしたほうがいい。腕の代わりに肩や背中、手の代わりに腕、指の代わりに手を使う、といった具合だ
人によるとは思うが、トラックボールが大いに役立った。しばらくの間は左にマウス、右にトラックボールを置いて交互に使っていたが、今ではその必要はない
休憩を取り、姿勢に気を配ることも重要だ。特に手首の姿勢が大事で、手首や腕をどこにも預けず、指だけがキーボードに触れるようにしている
ずっと後になってからケトルベルで筋力トレーニングを始めたが、筋力と血行がかなり良くなるのを感じた
10年ほど前、背中の痛み、首の痛み、反復運動障害の問題があった。背筋を伸ばして座る方法を身につけ、机の高さを調整し、エビのように丸まった姿勢でタイピングしないよう机の上の物を配置し直した。そして、実際にはそれほど多くタイピングする必要はないのだということにも気づいた
それ以来、痛みはまったくない
Cursorlessの全体的な概要と実際の使用例を見たいなら、今年のStrange Loopの発表がよかった: https://youtube.com/watch?v=NcUJnmBqHTY
とても気に入っていて、開発が続いているのもうれしいが、実際に深く使いこなすには腕や手を痛めていたり、重い反復運動障害があったりする必要がある気もする
精神的な初期導入コストが高そうだ
ただ、最大の制約は、これを事実上ひとりで在宅勤務しているときにしか使えないことのように思える。外やオフィスで使っている姿は想像しにくい
手が使えなくなったら使うと思う