MacBook Leopardのクリップボードを最もシンプルかつ自由に拡張してみる
クリップボードっていうのは、(おそらく)一日一回はお世話になるはずのコピー&ペーストをする時のコピーデータの一時的な保管場所のこと。にも関わらず、普段使っている分にはクリップボードは目に見えることもなく、コピー&ペーストの仲介人としてひっそりと、でも確実に処理をこなす縁の下の力持ち的な存在なのだ。
もしもクリップボードがない世界*1を考えてみると、それは相当使い難いOS環境になってしまうだろう。(はてな日記の下書きとしてスティッキーズに書いたとしても、さて、どうやってアップロードしようかと悩んでしまう...。)
このとっても便利なクリップボードという仕組みは、OSX標準では常に一つのクリップボードだけが提供されてきた。そうすると、みんな考えることは同じで、複数のクリップボードを使い分け出来たら便利なんじゃないだろうかと。試しにgoogle:OSX クリップボード等で検索してみると、様々なクリップボードの機能を拡張するアプリケーションがヒットする。だけども、自分が求める要件を満たしてくれるアプリケーションはなかなか見つからない...。
検索した多くのアプリケーションは、コピーの履歴を呼び出す方式になっていた。この方式だとコピーする度に対応するショートカットが変化してしまう...。変化するクリップボードの中身を常に気にする必要があり、それが煩わしい。
OS9時代からあるCopyPasteなどは理想的なのだが、シェアウェアで今となってはちょっと割高感がある。自分が求める機能はシンプルな下記用件のみ。
- 指定したクリップボードにショートカット一発でコピーして、ショートカット一発でペーストできること。
- 使い分けるクリップボードの数としては5つくらいで十分。
- クリップボードの中身は確認できなくてもOK。
- 保存先のクリップボードは自分が指定するので、自分の記憶で覚えておくことにする。
- 忘れた時はペーストすれば見られるし、間違ってペーストしたらcommand-Zで取り消しする。
そんなクリップボード拡張アプリケーションがどこかにないかな、フリーウェアでないかなと探していたが、なかなか見つからない。考えているうちに自分でも作れるような気がしてきた。いつものAppleScriptとQuicksilverの組み合わせで。早速、やってみた。
作業環境
- MacBook OSX 10.5.5
- AppleScript
- Quicksilver(3815)
クリップボードの拡張(clipシリーズ)
- クリップボードの保存用(clip1.scpt)、コピー処理(clip1_copy.scpt)、ペースト処理(clip1_paste.scpt)と3つの役割に分けてみた。
- 下記コード(clip1.scpt、clip1_copy.scpt、clip1_paste.scpt)をclipフォルダに入れて、ユーザーScriptフォルダに移動すればOK。
- 3つで一組のファイル名の数字の部分を変更してコピーすることで、使い分けるクリップボードの数を好きなだけ増やせる。
~/Library/Scripts/clip/clip1.scpt ~/Library/Scripts/clip/clip1_copy.scpt ~/Library/Scripts/clip/clip1_paste.scpt ~/Library/Scripts/clip/clip2.scpt ~/Library/Scripts/clip/clip2_copy.scpt ~/Library/Scripts/clip/clip2_paste.scpt ...
- フォルダ名とファイル名は重要。ルール外に変更すると動作しない。
- Quicksilverからのショートカット操作で利用することが前提なので、スクリプトメニューからは実行できない。
- (* ブロック *) 内のコードを有効にすれば、スクリプトメニューからも利用可能になる。
- その場合、副作用としてショートカット操作した時に対象アプリケーションのウィンドウが前面に出てくる。(アプリケーション切替でアクティブにした状況と同じ)
clip1_copy.scpt
- 選択部分をクリップボード経由でclip1.scptに保存する。
- ポイントは(the clipboard as record)という書き方。これで様々なデータを扱えるようになった!
on clipName() tell application "Finder" set myName to name of (path to me) as text --自分自身のファイル名 --「_」で区切ったリストに変換 set text item delimiters of AppleScript to "_" set nameList to text items of myName set text item delimiters of AppleScript to "" "clip:" & (item 1 of nameList) & ".scpt" end tell end clipName delay 0.5 --Quickslverで実行するにはひと呼吸必要だった set current_clip to (the clipboard as record) set CB to load script file (((path to scripts folder) as text) & clipName()) tell application "System Events" (* --操作対象のアプリを最前面に設定する(スクリプトメニューから実行する場合必要) set appName to (name of every process whose frontmost is true) as text tell process appName set frontmost to true end tell *) keystroke "c" using command down delay 0.5 end tell --set pb of CB to (the clipboard as «class rtfd») --リッチテキスト添付ファイルのみ --set pb of CB to (the clipboard as «class RTF ») --リッチテキスト --set pb of CB to the clipboard--テキストグループ set pb of CB to (the clipboard as record) --すべて store script CB in file (((path to scripts folder) as text) & clipName()) replacing yes delay 1 set the clipboard to current_clip
clip1_paste.scpt
- clip1.scptに保存されている内容をクリップボード経由で貼り付ける。
--property CB : load script file (((path to scripts folder) as text) & "clipboard.scpt")--実行時に更新されないのでNG on clipName() tell application "Finder" set myName to name of (path to me) as text --自分自身のファイル名 --「_」で区切ったリストに変換 set text item delimiters of AppleScript to "_" set nameList to text items of myName set text item delimiters of AppleScript to "" "clip:" & (item 1 of nameList) & ".scpt" end tell end clipName delay 0.5 --Quickslverで実行するにはひと呼吸必要だった set current_clip to (the clipboard as record) set CB to load script file (((path to scripts folder) as text) & clipName()) set the clipboard to pb of CB tell application "System Events" (* --操作対象のアプリを最前面に設定する(スクリプトメニューから実行する場合必要) set appName to (name of every process whose frontmost is true) as text tell process appName set frontmost to true end tell *) keystroke "v" using command down end tell delay 1 set the clipboard to current_clip
ショートカットの割り当て
Quicksilverには以下のように登録してみた。
- 例えば、クリップ1を利用するには...
- control-shift-1でコピー(clip1_paste.scpt)
- control-option-1でペースト(clip1_copy.scpt)
操作感
- Quicksilverからのショートカット操作は快適で、気持ち良くコピー&ペーストの操作ができた。
- プレーンテキストに限らず、リッチテキスト、画像、
ファイルなどもコピーできる。(通常のcommand-Cのコピーと同じだと思う。...ではなかった。)
自由な拡張(wrapシリーズ)
AppleScriptでクリップボードをこんなに簡単に扱えることが分かれば、あとは想像力と創意工夫次第で、自分好みに自由に拡張することができそう!
括弧で囲む
- 選択範囲の文字列を「括弧」で囲む。
delay 0.5 --Quickslverで実行するにはひと呼吸必要だった (* --操作対象のアプリを最前面に設定する(スクリプトメニューから実行する場合必要) set current_app to short name of (info for (path to frontmost application)) activate application current_app --tell application "System Events"ブロック内ではエラーになる *) tell application "System Events" keystroke "c" using command down delay 0.5 set the clipboard to "「" & (the clipboard as string) & "」" keystroke "v" using command down end tell
- バリエーションで""、''、[]、{}、()、<>なども作ってみた。
- 特殊な括弧を登録するのもありかも。
両端を1文字ずつ削除
- 選択範囲の両端を1文字ずつ削除する。(括弧を取り除きたい時などに)
delay 0.5 --Quickslverで実行するにはひと呼吸必要だった (* --操作対象のアプリを最前面に設定する(スクリプトメニューから実行する場合必要) set current_app to short name of (info for (path to frontmost application)) activate application current_app --tell application "System Events"ブロック内ではエラーになる *) tell application "System Events" keystroke "c" using command down delay 0.5 set the clipboard to text 2 thru -2 of (the clipboard as string) keystroke "v" using command down end tell
スタイルの復活(文字の大きさや太さなど)
- 括弧付きに変換や両端削除をした時、スタイル情報は失われてしまう...。
- スタイルを復活させたいそんな時は、以下のショートカットの連続技で幸せ。
- command-Z、shift-option-command-V
タグで囲む
- さらに、現在のクリップボードの文字列をタグとして認識して、選択範囲の文字列を囲むようにしてみた。
- 現在のクリップボードの文字列は<div>、</div>、divのどれでもOK。(divは一例。abcなら
のようなタグを生成する。) - 「文字列」を選択して実行すると「<div>文字列</div>」に変換される。
- 現在のクリップボードの文字列は<div>、</div>、divのどれでもOK。(divは一例。abcなら
delay 0.5 --Quickslverで実行するにはひと呼吸必要だった set aWord to (the clipboard as string) if aWord starts with "<" then set aWord to text 2 thru -1 of aWord if aWord starts with "/" then set aWord to text 2 thru -1 of aWord if aWord ends with ">" then set aWord to text 1 thru -2 of aWord set startTag to "<" & aWord & ">" set endTag to "</" & aWord & ">" (* --操作対象のアプリを最前面に設定する(スクリプトメニューから実行する場合必要) set current_app to short name of (info for (path to frontmost application)) activate application current_app --tell application "System Events"ブロック内ではエラーになる *) set current_clip to the clipboard tell application "System Events" keystroke "c" using command down delay 0.5 set the clipboard to startTag & (the clipboard as string) & endTag keystroke "v" using command down end tell delay 1 set the clipboard to current_clip
ショートカットの割り当て
ショートカットは複合キー押しまくりで、もう訳解らん感じだが、以下のようにしてみた。
使い始めるまでのQuicksilverの設定が面倒かもしれないが、ショートカットは自分好みに設定できるし、AppleScriptなので欲しい機能は工夫次第で自分好みに自由に追加できる。自分スペシャルな手に馴染む操作環境を手に入れられるかも。
解決できない問題・実現したい課題
- ショートカットの連続技で操作したい。
- CopyPasteのようにcommand-Cのあと、commandを押し続けたまま1を押すとクリップ1に保存できるようになると便利。
- (他のショートカットとの重複を避けるため)複合キー押しまくりの現状では、ちょっと操作し難い。
- リッチテキストのまま括弧やタグで囲うようにしたい。
- wrapシリーズの操作をすると、プレーンテキストとして変換されてしまう。
- AppleScriptでリッチテキストのまま操作する方法ってあるのだろうか?
- 文字列の選択範囲の両端を1文字広げる操作をしたい。
- ファイル(またはフォルダ)を複数選択してコピーすると、先頭の1ファイル(または1フォルダ)しかコピー出来ない。
- クリップボードの情報をプロパティに保存して復元する時に、何らかの情報が欠落しているのかもしれない...。
- 原因調査中。
- 問題は解決していないが、ファイル(またはフォルダ)を複数選択してコピーした場合、そのパスをコピーする仕様に変更した。
- Finderでファイルやフォルダのパスをコピーする
- クリップボードを指定したコピーでは、ファイルやフォルダ自体のコピーは出来ない仕様。(必要な時は、通常のcommand-CでコピーすればOK)
- 複数選択した場合は、ちゃんと複数のパスをペーストすることができる。
*1:iPhone・iPod Touchに未だにコピー&ペーストの機能がない。ゲーム機ならOKだが、手のひらパソコンとして考えると大問題だと思う。