Vscodeのマルチカーソルをスクリーンリーダーで使う

便利だが説明がわかりにくいマルチカーソルを頑張って使ってみるのまき

いろんなサイトに開設は載ってるんですけど、結構図解されていたりしてわかりにくいんですよね。ということで、スクリーンリーダーで使うには手っ取り早くどうすればええねんというのを書きます。

そもそもマルチカーソルとは

エディター上に複数のカーソルを置ける機能です。複数置いて切り替えながら使うというよりは、複数置いてそいつらにいっきに命令を出すイメージです。

カーソルが複数ある状態では、いつもやってる操作が以下のような効果をもたらします。

  • カーソル移動を行うと、今あるカーソルたちは、全部同じように移動します。ctrl+左右矢印のように、一気に何文字か移動するコマンドを使ったときは、書くカーソルの位置でそのコマンドをそれぞれ使ったような動きをします。つまり、カーソルが 3 つあって、書くカーソルの下の単語の文字数が違っているときに ctrl+右矢印を押したら、同じ文字数移動するわけではなく、それぞれの単語の最後にしっかり移動してくれます。
  • 文字入力すると、それぞれのカーソルがある位置に、入力した文字が同時に挿入されます。通常の文書編集と同じように、範囲選択状態であれば、選択している部分が、入力した文字列にまるごと置き換わります。
  • 範囲選択を行うと、それぞれのカーソルが選択しているテキストが全部合計されて選択範囲になります。

どんなことができるか

私もまだそこまで黒魔術的な使い方はしていないんですが、以下のようなことができます。応用すれば、もっといろんなことができます。

  • 特定の単語の前後にいっきに文字を付け加える
  • 正規表現を書かずに複雑な一括置換
  • JSON のキーや特定位置の引数などをまとめてコピー
  • 特定の単語や文字を一括で消す

スクリーンリーダーで使うときのポイント

カーソルを増やすとき

スクリーンリーダーでマルチカーソルを置くには、以下のコマンドのうちのどれかを使うといいと思います。

shift+alt+i: 選択している全ての行の末尾にカーソルを置きます。3 行選択している状態で使えば、その 3 行だけに置かれるし、全て選択している状態で使えば、全ての行にカーソルが置かれます。全てのカーソルを一括で動かすので、カーソルを置いた後にホームを押せば、書くカーソルはその行の先頭の文字に移動します(インデントレベルが違ってもそれぞれちゃんと動きます)。もう 1 回ホームを押せば、書くカーソルは行頭に移動します。

ctrl+shift+l: 選択している単語が出現する全ての位置にカーソルを置きます。たとえば、 cat という 3 文字を選択してから ctrl+shift+l を押すと、cat と書いてある場所が全て検索されて、それぞれの t の位置にカーソルが置かれます。この時、全ての cat は選択状態になっているので、直後に文字入力すると一括置換になって便利です。

ctrl+alt+上下矢印: それぞれ、上下方向にカーソルを増やします。今自分が 10 行目にいるとすると、ctrl+alt+上矢印を 1 回押せば 9 行目にカーソルが増えて、もう 1 回押せば 8 行目に増えます。ctrl+alt+下矢印だったら、1 回押すと 11 行目に増えて、2 回押すと 12 行目に増えます。なお、このコマンドは NVDA のテーブルナビゲーションのコマンドとバッティングしていますから、使う前に NVDA+f2 で NVDA 側を倍パスする必要があります。連続で使うときは、ctrl+alt を押しっぱなしにしておけば問題なく連続で使えます。

カーソルを動かすとき

左右矢印キーやホーム/エンドキー、ctrl+左右矢印キーで移動します。スクリーンリーダーを使っているときにちょっとネックになるのは、メインのカーソルというか、自分が元々いた位置の情報しか読んでくれないというところです。実質、カーソル 1 この時と読み上げがなにも変わりませんから、「他のカーソル達はこういうふうに動いてるだろうな」ということをイメージする必要があります。

基本的には左右移動だけだろうから問題ないのですが、上下に移動すると、カーソルが減る場合があります。たぶんなんですが、実際のドキュメントからはみ出したカーソルは消えるんじゃないかと思います。たとえば、一番上から 3 行にカーソルを置いているときに、上矢印を 1 回押したら、一番上にあったカーソルはこれ以上上に行けませんから、このタイミングで 1 個消えている気がします。

編集するとき

普通に編集すれば問題ないですが、これもちょっとイメージしていないと、へんな編集をしてしまうかもしれません。ちょっと練習して慣れるといいと思います。

いつもの状態に戻るとき

エスケープを押せば、増やしたカーソルを全て消して、いつもの状態に戻れます。

具体例

タブをスペースにしたい

正規表現で\t をスペース 4 つとかにしてもいいですが、ダイアログを操作するよりこっちのほうが絶対早いって方法です。

まず、どこでもいいのでタブ文字を 1 個選択します。そしたら、ctrl+shift+l で、タブがある場所全部にカーソルを置きます。最後に、スペースを 4 回押します。なんとこれだけです!!!!!!!!

コーテーションの種類を変えたい、特定の場所だけ

こんなコードがあると想像してください。


oreore_json = """
{
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value",
	"key": "value"
}
"""
print("JSONを表示しますね。\n%s" % oreore_json)

理由はよく分かりませんけど、JSON のダブルクオートをシングルクオートニしろって言われたとします。でも、JSON 以外はダブルクオートのままじゃないと、色々ぶっ壊れます。全部手で直すのは、なんというか、お仕置きです。だるいです。やりたくないですね。ミスも増えます。でも、そんなときはこうすれば解決です。

まずは、oreore_json の中身だけを選択します。shift+上下矢印でもいいし、このあいだ紹介した始点/終点での選択でもいいですね。選択したら、shift+alt+i で、選択した行の末尾にカーソルを増やします。これで、JSON の中身の各行にカーソルが増やせました。

ホームを押して先頭の文字に移動します。ここにはダブルクオートがあるので、シングルクオートニします。右に移動していって、ダブルクオートを見つけたらシングルクオートニします。1 行分変更したら終わりです、しかも、何百行合っても、未来永劫このやり方で通用します!!!!!!!!

ちなみに、私は JSON じゃなくて、HISS を作っていたときに、 unordered_map<wchar_t, wchar_t> の initializer list を全部ダブルクオートで記述してしまって怒られたのを一括で直すために使いました。

csv から特定の列を抜いてくる

こんなのがあるとします。


item,price,description
apple,120,sweet fuji apple
orange,110,from Shizuoka farm
banana,140,imported from Philippines
pineapple,160,very very big
peach,130,harder than you might think

これは、以下のようにするとできるはずなんですが、こちらの環境では、ctrl+右矢印を押した瞬間に全部のカーソルがクリアされてしまいました。ちょっとよく分からないので問い合わせています。

csv を全て選択してから shift+alt+i を押して、全部の行にカーソルを置きます。ホームを押して、行の先頭に移動します。ctrl+右矢印で、カンマの直前まで選択状態にします。ctrl+c でコピーします。これで、理論的にはできるはずなんですけど!

終わり

また思いついたら何か書きます。ctrl+右でカーソルが消えちゃう原因も書き足したい。