MacBookでテキスト選択範囲の両端を拡大・縮小するスクリプト

テキストの選択範囲を始点と終点の両方を広げたり、狭めたりしたいことって自分の場合よくある。例えば以下のようなケース。ダブルクォーテーションまで含めた選択範囲に変更したいことってよくあるのだ。("文字列"、「文字列」、(文字列)...なども)*1

しかし、選択範囲の両端を広げるためには、キー操作一発という訳にはいかない...。結構、面倒な操作になりがち。

基本に忠実バージョン

で、以前からAppleScriptで何とかならないかと考えていて、最初にやってみたのが以下のスクリプト

--expand_selection.scpt
delay 0.5
tell application (name of (info for (path to frontmost application)))
    tell application "System Events"
        keystroke "c" using command down
        delay 0.1
        set selection_len to length of string of (the clipboard as record)
        key code 123 --←
        key code 123 --←
        repeat with i from 1 to selection_len + 2
            key code 124 using shift down
        end repeat
    end tell
end tell

ついでに、選択範囲を縮小するスクリプト

--shorten_selection.scpt
delay 0.5
tell application (name of (info for (path to frontmost application)))
    tell application "System Events"
        keystroke "c" using command down
        delay 0.1
        set selection_len to length of string of (the clipboard as record)
        key code 123 --←
        key code 124 --→
        repeat with i from 1 to selection_len - 2
            key code 124 using shift down
        end repeat
    end tell
end tell

一応、希望通りの動きをするスクリプト。"Script Editor"程度に選択範囲が短い時はこれでOK。ところが、長い文章になると問題発生。始点から1文字ずつ範囲を選択する動作なので、終点に至るまで結構な時間がかかるのだ。その動きが実際に目で見えるのは楽しいけど、あまり実用的ではない...。長い文章になるほど、それに比例して時間がかかるというのが許せないところ。

選択範囲を広げる別の方法を考えなくてはならない。選択範囲を文字列の先頭から選択し直しているために、文字数分のrepeatが必要になってしまう。どうにか現在の選択範囲を維持したまま、左右に1文字ずつ拡大する方法はないものか...。悩みながら眠っていたら、夢の中で閃いた。

文字列を選択する時の挙動

  • shift-←・→によって、選択範囲の始点または終点のどちらか一方を移動して、拡大・縮小することができる。
  • 拡大の方向と逆方向の矢印で縮小することができる。
  • マウスで文字列を選択した直後、最初の操作で拡大する位置が決定する。
    • shift-←なら始点が移動して拡大する。
    • shift-→なら終点が移動して拡大する。
  • 選択中の文字列を削除して、command-Zでその操作を取り消した場合、削除前の文字列を選択した状態に戻る。
    • 上記状態は、マウスで文字列を選択した直後と同じ状態で、最初の操作で拡大位置が決定する。

以上は、スクリプトエディタ、テキストエディット、スティッキーズ、CotEditorで実際に試してみた挙動。

取り消し操作を利用したバージョン

上記の挙動を利用すると、以下のスクリプトでも始点と終点を1文字ずつ拡大することが出来た。

--expand_selection.scpt
delay 0.5
tell application (short name of (info for (path to frontmost application)))
    tell application "System Events"
        key code 51 --delete
        keystroke "z" using command down
        key code 123 using shift down --shift-←
        
        key code 51 --delete
        keystroke "z" using command down
        key code 124 using shift down --shift-→
    end tell
end tell

ついでに、選択範囲を縮小するスクリプト

  • 一旦拡大した後、縮小する方向のキー操作を2回行っている。
  • よって、選択範囲の前後に文字がない場合、変な動作になる。
--shorten_selection.scpt
delay 0.5
tell application (short name of (info for (path to frontmost application)))
    tell application "System Events"
        key code 51 --delete
        keystroke "z" using command down
        key code 123 using shift down --shift-←
        key code 124 using shift down --shift-→
        key code 124 using shift down --shift-→
        
        key code 51 --delete
        keystroke "z" using command down
        key code 124 using shift down --shift-→
        key code 123 using shift down --shift-←
        key code 123 using shift down --shift-←
    end tell
end tell


しかし、この方法はすべての状況で万能ではなく、SafariFirefoxのテキスト入力ボックス、mi、TextMate、AptanaStudio等では通用しなかった...。
あらゆるテキスト編集の環境に対応させるためには、今のところ「基本に忠実バージョン」のスクリプトを利用するしかなさそう...。お決まりのQuicksilverから、それをショートカットに登録してみた。(選択範囲が長文の時は躊躇するが、自分が利用するケースではほとんどが数単語なので、思ったほどストレスは感じないかも。)

  • command-option-Eで、選択範囲の両端を1文字ずつ拡大。(Expand)
  • command-option-Sで、選択範囲の両端を1文字ずつ縮小。(Shorten)


AppleScriptGUIスクリプティングを利用すると、テキストエディタを選ばず、同様の操作が実現できるのが便利なところ。このまま暫く使ってみることにする。

*1:利用するテキストエディタによっては、既にそんな希望を叶えてくれるかも。