Alfred Workflow

Alfred Workflowで引数の入力を促す

引数の入力を促したい

YosemiteでSpotlightの強化などがありつつも、やはりAlfred Workflowの便利さには変え難く、相変わらずAlfredばかり使っています。

で、Alfred Workflowにおいて、Script Filterを利用して、入力テキストの内容によって処理を変えたりすることがあります。

この場合、キーワードに続くテキストの一部がオプションになるわけですが、WorkflowとしてはArgument Optionalであっても、オプションによってはArgument Requiredにしたいことがあります。

例えば、catfist/Alfred-MyHexoの場合、hxコマンドのオプションがb/nの場合はタイトル入力が必須となるため、通知センターで警告を出すようにしていました。

しかし、どうせ入力必須なら、すぐにAlfredを開いて入力を再開したいところです。

というわけで、少し改良

従来の引数がない場合の処理は以下の通りです。

1
2
3
4
5
if [ -z $arg ];then # 入力テキストがない場合
echo -n "ERROR: Input title" # エラーを標準出力にエコーして通知センターに渡す
else # それ以外の場合
Create # Create関数を実行して記事ファイルを作成
fi

これを、以下のように改良しました。詳細は前回の記事をご参照ください。

1
2
3
4
5
6
if [ -z $arg ];then
echo -n "ERROR: Input title"
osascript -e "tell application \"Alfred 2\" to search \"hx$cmd \"" # Alfredを起動してテキスト入力を促す
else
Create
fi

これで、$cmd変数がb/nかつタイトル未入力の場合、通知を出しつつAlfredウインドウが起動して、タイトル入力をすぐ受け付けられるようになります。

Alfred WorkflowからAlfred Workflowを起動することで連続的に入力を受け付ける

Alfred WorkflowからAlfredを起動したい


ver. 1.2 - 無料( 仕事効率化 )
Running with Crayons Ltd

Alfred Workflowで、「何かを入力/選択」した後、さらに「リストから何かを選択」したい時があります。

実際にこのような処理をしているWorkflowとしては、ajgon/alfred2-html-entity-lookupなどがあります。

このWorkflowの場合、まず記号を入力し、次にエンティティの種類を選択すると、エンティティがクリップボードにコピーされます。

で、どうやっているかというと、「入口」のアクションと「出口」のアクションが、それぞれにキーワード付きで設定されており、「入口」のアクションからAppleScriptで、「出口」のキーワードを入力した状態でAlfredを起動しているのです。

具体的に

「入口」がRun Script(/usr/bin/osascript)またはAppleScriptアクションの場合、以下のようにします。

1
tell application "Alfred 2" to search "entity {query}"

このようなスクリプトにより、entity(キーワード)と{query}(引数)を入力した状態でAlfredを起動しています。

Run Script(/bin/bash)で置き換えると、以下のようになります。

1
osascript -e "tell application \"Alfred 2\" to search \"entity {query}\""

スクリプト文(-eに続く部分)全体をシングルクォートで囲ってもいいですが、変数を含める場合は、上記例のように、文中のダブルクォートをバックスラッシュエスケープする必要があります。

この方式の利点はなんといっても「出口」でScript Filterが使えることで、「インクリメンタルサーチからのインクリメンタルサーチ」とかが簡単にできます。

(2015-01-03追記)External Triggerを利用する

完璧に忘れてたので追記。

External Triggerとは、AppleScriptで指定のWorkflowアイテムを起動する機能です。

この機能を利用するためには、ふたつの前提が必要になります。

  1. Workflow自体にBundle IDが指定されている
  2. Workflow内のアイテムにExternal Triggerが連結している

構成例はこんな感じです。

スクリーンショット

Bundle IDは、「com.alfredapp.<作成者>.<WorkflowID>」というフォーマットが推奨されているようです。

External TriggerからWorkflow内のScript Filter/Keywordを起動すると、こんな感じで、キーワードなしで入力に移ることができます。

スクリーンショット

こちらのほうがフィールドが広く使えていい感じですね。

nvALTのノートをGeeknoteでEvernoteに保存するAlfred Workflow

からの続編。もともとはこれがやりたかった。

スクリーンショット

AppleScriptは以下。

(2014-11-29修正)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
property nvNoteFolder : "~/Dropbox/Notes/" -- include trailing slash
property nvNoteExtension : ".txt" -- include leading dot
-----------------------------
on alfred_script(q)
-- ファイルパスを取得
set nvNoteFolder to do shell script "echo " & nvNoteFolder ----フォルダパスをチルダ展開
set f to false
if application "nvALT" is running then -- nvALTが起動中かどうか
else -- 起動中でない場合
launch application "nvALT" -- 起動
repeat -- 検索フィールドが存在するかチェック
tell application "System Events" to exists text field 1 of group 1 of toolbar 1 of window 1 of application process "nvALT"
if result is true then exit repeat
delay 0.5
end repeat
end if
tell application "System Events" to tell process "nvALT"
set p to value of text field 1 of group 1 of toolbar 1 of window 1 -- 検索フィールドの内容を取得
set p to replaceText(p, "/", ":") of me -- /を:に置換
try -- 指定フォルダ、指定拡張子に基づきファイル取得試行
set f to POSIX file (nvNoteFolder & p & nvNoteExtension) as alias
end try
if f is false then -- 失敗した場合
try -- 指定拡張子の代わりに.txtを付けてみる
set f to POSIX file (nvNoteFolder & p & ".txt") as alias
end try
end if
if f is false then -- また失敗した場合、ダイアログを出す
set _res to display dialog nvNoteFolder & p & nvNoteExtension & "を開けません" buttons {"OK"}
return
end if
end tell
-- Geeknoteでポスト
if f is not false then
set pFile to POSIX path of f
set pFile to quoted form of pFile
tell application "iTerm"
tell the first terminal
-- iTermで新規セッションを開く
launch session "Default Session"
tell the last session
-- GeeknoteでEvernoteに保存
write text "gn " & pFile & " && rm " & pFile & " && logout"
end tell
end tell
end tell
end if
-- nvALTをアクティベート
tell application "nvALT"
activate
end tell
end alfred_script
-- 任意のデータから特定の文字列を置換
on replaceText(origData, origText, repText)
set curDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {origText}
set origData to text items of origData
set AppleScript's text item delimiters to {repText}
set origData to origData as text
set AppleScript's text item delimiters to curDelim
return origData
end replaceText

Geeknoteに投げる部分をdo shell scriptでやると、Input stream is emptyとか言われて詰みます。

やむなく、iTerm2をAppleScriptで操作する形にしました。

シェルスクリプトを全部AppleScript内に書くと気が狂うので、.bashrcに以下のシェル関数を記述しておきます。

1
2
3
4
5
6
gn () {
file=${1##*/} #フルパスをファイル名に変換
name=${file%.*} #ファイル名から拡張子を除く
cont=`cat "$1"` #ファイル内容を取得
geeknote create --title "$name" --content "$cont" #GeeknoteでEvernoteに保存
}

余計なセッションが開くのが気に食わないですが、自動で閉じるのでまあ許そう。

これで、キーワード一発でnvALTのノートを(HTML変換して!)Evernoteに保存することができます。

nvALTのノートを任意のアプリで開きたい

上記の続編的な。

nvALTはテキストの集積場所であり、一種のハブと言えます。メモを正式な文書に書き起こしたり、Evernoteに投げたりとかで、ノートを他のアプリで開きたいときがままあります。

そこで、「Note > Edit With」で他のアプリから開いたりするわけですが、アプリを一覧から選ぶのが面倒くさい。

そこで、AppleScriptで解決したかったのですが……

nvALTはAppleScriptに対応していない

FoldingTextの場合、AppleScriptに対応しているのであっさり解決したのですが、nvALTはAppleScriptで「開いているファイル」を取得したりすることができません。

どうしたものかと思っていたところ、Markedに関連して配布されているAppleScriptで、「nvALTのノートをMarkedで開く」ということが実現されていました。

tell application "System Events"で検索フィールドのテキストを取得し、ユーザで定義した保存フォルダと拡張子を付加するという、なかなか涙ぐましい有り様です。

これを参考に、任意のアプリケーションで開くAlfred Workflowを組んでみました。

やってみた

スクリーンショット

Script Filter

こちらはFoldingTextのものと同じ。アプリケーションをインクリメンタルサーチします。

(2014-11-23修正)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
q="{query}"
cd /Applications
# 省略表記
case "$q" in
st) q="Sublime Text" ;;
ft) q="FoldingText" ;;
as) q="AppleScript Editor" ;;
esac
while read App; do Apps+=("$App"); done < <(ls /Applications)
while read App; do Apps+=("$App"); done < <(ls /Applications/Utilities)
cat << EOB
<?xml version="1.0"?>
<items>
EOB
IFS=$'\n'
for App in `echo "${Apps[*]}" | sed 's/.app$//' | grep -i "$q"`
do
cat << EOB
<item uid="$App" arg="${App}" valid="YES" >
<title>Open current note in ${App}.app</title>
</item>
EOB
done
echo "</items>"

AppleScript

(2014-11-20修正)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
property nvNoteFolder : "~/Dropbox/Notes/" -- include trailing slash
property nvNoteExtension : ".txt" -- include leading dot
-----------------------------
on alfred_script(q)
set nvNoteFolder to do shell script "echo " & nvNoteFolder ----フォルダパスをチルダ展開
set f to false
if application "nvALT" is running then -- nvALTが起動中かどうか
else -- 起動中でない場合
launch application "nvALT" -- 起動
repeat -- 検索フィールドが存在するかチェック
tell application "System Events" to exists text field 1 of group 1 of toolbar 1 of window 1 of application process "nvALT"
if result is true then exit repeat
delay 0.5
end repeat
end if
tell application "System Events" to tell process "nvALT"
set p to value of text field 1 of group 1 of toolbar 1 of window 1 -- 検索フィールドの内容を取得
set p to replaceText(p, "/", ":") of me -- /を:に置換
try -- 指定フォルダ、指定拡張子に基づきファイル取得試行
set f to POSIX file (nvNoteFolder & p & nvNoteExtension) as alias
end try
if f is false then -- 失敗した場合
try -- 指定拡張子の代わりに.txtを付けてみる
set f to POSIX file (nvNoteFolder & p & ".txt") as alias
end try
end if
if f is false then -- また失敗した場合、ダイアログを出す
set _res to display dialog nvNoteFolder & p & nvNoteExtension & "を開けません" buttons {"OK"}
return
end if
end tell
if f is not false then
tell application q
activate
open f
end tell
end if
end alfred_script
-- 任意のデータから特定の文字列を置換
on replaceText(origData, origText, repText)
set curDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {origText}
set origData to text items of origData
set AppleScript's text item delimiters to {repText}
set origData to origData as text
set AppleScript's text item delimiters to curDelim
return origData
end replaceText

文字列置換ハンドラは以下を参考にしました。

なお、追加のハンドラをalfred_scriptハンドラ内に記述しないよう注意する必要があります。

nvALTはファイル名に関するエスケープ機能を持っておらず、タイトルにスラッシュを含むノートを、そのまま保存してしまいます。これは、Mac OS Xにより、コロンに置換されるため、対応する必要があります。

これで、任意のアプリでノートを開くことができます。

Alfred Workflowのインクリメンタルサーチで「一覧から絞り込む」か「検索結果を表示する」か

Alfred Workflowではインクリメンタルサーチができる

上記記事で書いたように、Script Filterループ処理でXMLドキュメントを生成することによって、Alfred Workflowで入力テキストによるインクリメンタルサーチを実現することができます。

この際、検索結果について、ふたつの表示方法が考えられます。

  1. 入力テキストがない場合、候補を表示しない
  2. 入力テキストがない場合、全ての候補を表示する

候補の母集団が多い場合は1が、少ない場合は2が適切だと考えられます。

では、どのように表示方法を指定するのかというと、Script FilterのArgumentオプションです。

スクリーンショット

1の場合は「Argument Optional」、2の場合は「Argument Required」を指定します。「Argument Required」の場合、テキストを入力しないと候補が表示されません。

例1:入力テキストがない場合、候補を表示しない

あるテキストファイル(hoge.txt)から、先頭一致検索して行をコピーするWorkflowがあるとしましょう。

構成はこんな感じですね。

スクリーンショット

「Argument Required」を指定します。

bashでScript Filterを書くとすると、こんな感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file=~/Documents/hoge.txt
cat << EOB
<?xml version="1.0"?>
<items>
EOB
# 入力テキストで検索
for line in `grep "^{query}" $file`
do
# XML特殊文字エスケープ
line=`echo "${line}" | sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g' -e "s/'/\'/g" -e 's/"/\"/g'`
cat << EOB
<item uid="${line}" arg="${line}" valid="YES" >
<title>Copy: ${line}</title>
</item>
EOB
done
echo "</items>"

出てきません。

スクリーンショット

例2:入力テキストがない場合、全ての候補を表示する

構成は1と同様です。

「Argument Optional」を指定します。

Script Filterはこんな感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file=~/Documents/hoge.txt
cat << EOB
<?xml version="1.0"?>
<items>
EOB
# 入力テキストなしの場合、全ての行が検出されるように、検索条件に.*を入れる
for line in `grep "^{query}.*" $file`
do
# XML特殊文字エスケープ
line=`echo "${line}" | sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g' -e "s/'/\'/g" -e 's/"/\"/g'`
cat << EOB
<item uid="${line}" arg="${line}" valid="YES" >
<title>Copy: ${line}</title>
</item>
EOB
done
echo "</items>"

いっぱい出てきます。

スクリーンショット

「Argument Optional」にしたい!でも候補全部出したくない!

例えば、入力テキストがない場合に何か別の処理(hoge.txtを開くとか)をしたい場合、「Argument Optional」指定が必須です。

ifしましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
file=~/Documents/hoge.txt
# 入力テキストがある場合のみ実行
if [ -n "{query}" ];then
cat << EOB
<?xml version="1.0"?>
<items>
EOB
# 入力テキストで中間一致検索
for line in `grep -i "{query}" $file`
do
# XML特殊文字エスケープ
line=`echo "${line}" | sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g' -e "s/'/\'/g" -e 's/"/\"/g'`
cat << EOB
<item uid="${line}" arg="${line}" valid="YES" >
<title>Copy: ${line}</title>
</item>
EOB
done
echo "</items>"
else
#何か他の処理を書く
cat << EOB
<?xml version="1.0"?>
<items>
<item uid="open" arg="open" valid="YES" >
<title>Open Document</title>
</item>
</items>
EOB
fi

これで、arg要素をRun Scriptに渡すなりして、分岐処理を行えばよいです。

適当な空ファイルを作ってSublime Textとかで開く

適当にシンタックスハイライトしながらコード修正とかしたい時のために。

シェル関数

.bashrcに以下のように書きます。

1
2
3
4
5
cb () {
tmp=/tmp/`date '+%s'`.$1 # 現在日時+指定拡張子で一時ファイルを作成
pbpaste > ${tmp} # クリップボードをファイルに書き込み
subl $tmp # Sublime Textでファイルを開く
}

cb shとかcb scptとかします。

コードをペーストしたい場合がほとんどなのでpbpasteからリダイレクトしていますが、普通にtouchでもいいです。

当初はファイル名に$$(プロセスID)を利用していましたが、いくつも作るかもしれないのでdateコマンドで生成することにしました。

さらにmacite/sublimebashbuildsystemとかidleberg/AppleScript-Sublime-Textとか入れておくと、デバッグもできてよさげであります。

Alfred Workflow(2014-11-23追記)

ターミナル以外でも使いたくなったのと、アプリを選びたかったので。

ベースはこれです。

例えばcb scpt AppleScript Editorと入力すると、.scptファイルをAppleScriptエディタで開きます。

構成

スクリーンショット

Script Filter

(2014-12-31修正:開くアプリケーションのアイコンを表示)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
read Ext q <<< "{query}"
case "$q" in
st) q="Sublime Text" ;;
ft) q="FoldingText" ;;
as) q="AppleScript Editor" ;;
esac
while read App; do Apps+=("$App"); done < <(ls /Applications)
while read App; do Apps+=("$App"); done < <(ls /Applications/Utilities)
# 拡張子のみ入力されている状態があるので、アプリ名が入力されている場合のみ実行
if [ -n "$q" ];then
cat << EOB
<?xml version="1.0"?>
<items>
EOB
IFS=$'\n'
for App in `echo "${Apps[*]}" | sed 's/.app$//' | grep -i "$q"`
do
# アイコン表示のためアプリのフルパスを取得
if [ -d "/Applications/$App.app" ];then
icon="/Applications/$App.app"
else
icon="/Applications/Utilities/$App.app"
fi
cat << EOB
<item uid="$App" arg="${Ext} ${App}" valid="YES" >
<title>Create & Open '${Ext}' file in ${App}.app</title>
</item>
EOB
done
echo "</items>"
# アプリ名が未入力の場合、入力を促す
else
cat << EOB
<?xml version="1.0"?>
<items>
<item uid="error" arg="txt Alfred 2.app" valid="YES" >
<title>Create "$Ext" file & Open in ..</title>
<subtitle>Enter App Name</subtitle>
</item>
</items>
EOB
fi

/bin/bash Script

(2014-12-21修正)

1
2
3
4
5
6
7
8
9
read Ext App <<< "{query}" # 拡張子とアプリ名を取得
tmp=/tmp/`date '+%s'`.$Ext # 作成するファイルのパスを指定
if [ "$Ext" = scpt ];then # 拡張子がscptの場合
touch /tmp/blanc.scpt # 別途空ファイルを作成
osacompile -o $tmp /tmp/blanc.scpt # AppleScriptとして指定パスにコンパイル
else # それ以外の場合
pbpaste > ${tmp} # 指定パスにクリップボードの内容を出力
fi
open -a "${App}" ${tmp} # 指定アプリで作成したファイルを開く

(2014-12-21追記)AppleScript(scpt)ファイルの特別扱いについて

実行可能なscptファイルはバイナリファイルです。普通のスクリプトファイルと同様にpbpasteをリダイレクトするとテキストファイル扱いになってしまい、保存ができなくなります。

かといって、pbpasteをリダイレクトして書き込んでからコンパイルしようとすると、構文エラーでコンパイル失敗が多発します。これを避けるには、空の状態でアプリに引き渡してから普通にペーストするのが一番スマートです。

AppleScriptは、スクリプト言語でありながらファイルとしてはバイナリという特殊な言語であるため、このような対処が必要になります。

なお、シバンが#!/usr/bin/osascriptの実行可能ファイルにしてOpenする場合、テキストファイルのまま扱えます。ただし、スクリプトエディタやSublime TextのAppleScriptビルドシステムでの実行テストはできません。

Alfred Workflowで複数のアイテムの実行ファイルをひとつにしてしまえ

の続き。

実行ファイルを一つにしてしまえ

前回は、Alfred WorkflowのGUIエディタから編集するのくそだるいので実行ファイルにしてしまえという話でした。

もはや複数の実行ファイルにパスとか書き込むのもめどいので、実行ファイルをひとつにしてしまいましょう。

このようなWorkflowがあるとしましょう。

スクリーンショット

Script Filter、Run Scriptの内容はそれぞれ以下の通りです。

Filter.sh
1
./hx.sh input "{query}"
Script.sh
1
./hx.sh run "{query}"

で、hx.shではcase文を利用して分岐処理を行います。

1
2
3
4
5
6
7
8
9
case $1 in
input )
case "$2" in
# 以下略
;;
run )
case "$2" in
# 以下略
;;

Alfred Workflowのアイテムごとに異なる引数1($1)が最初の分岐に利用され、その後の入力テキストである引数2以降($2,$3…)が実際の処理に利用されます。

実際どう?

実行速度については、数KBのファイルなら分割した場合と大差ない感じです。

今回は、ファイルが長大すぎてかえって編集がめどくなった感がなきにしもあらず。個々のスクリプトがどのくらい複雑かにもよりますが、ゴチャゴチャした分岐処理とかしないならできるだけまとめたほうが楽そうです。

Alfred Workflowの開発で楽するために全部スクリプトファイルにする

Alfred Workflowの開発はめどい

めどい。使うのは便利だけど作るのはめどいのです。

なにがめどいかというと、普通に作るとコードをGUIウィンドウに書き込まねばならないため、好きなエディタで編集するにはいちいちコピペしなければならない点です。

スクリーンショット

info.plistを直接編集すればいいだろうという話もありますが、あんな複雑な書式の、しかも全てのコードがひとつのファイルになったようなものを直接編集するのは恐ろしすぎます。全文置換なんかとてもとても。

というわけで、実行権限を付与したスクリプトファイルを作って、Actionの実体はそれを実行するだけにします。

このようなWorkflowがあるとしましょう。

スクリーンショット

Script Filter、Run Scriptの内容はそれぞれ以下の通りです。

Filter.sh
1
./hx.sh "{query}"
Script.sh
1
./hxrun.sh "{query}"

hx.shおよびhxrun.shの最初のあたりはこうです。

1
2
3
4
5
6
7
8
9
read cmd arg <<< "$1"
case "$cmd" in
"" )
cmd=t
t="Input command"
st="If no commands, open Hexo project folder in Terminal"
;;
# 以下略
1
2
3
4
5
6
7
8
9
10
dir=`sed -n 2p Config | sed "s%~%$HOME%"`
editor=`sed -n 5p Config`
terminal=`sed -n 8p Config`
url=`sed -n 11p Config`
PATH=$PATH:/usr/local/bin
q="$1"
read cmd arg <<< "$q"
cd $dir
# 以下略

普通なら{query}になるところを、シェルスクリプトの引数を意味する$1に置換しています。

これで、好きなエディタで簡単にWorkflowを編集することができますし、個々のスクリプトをターミナルで実行することもできるので、デバッグも簡単になります。

欠点は、公開した場合にユーザが内容を把握しにくいことでしょうか。まあ勘弁な、ということで。

AppleScriptでBluetoothテザリングを接続してみる

執筆やら開発やらの際、概ね全部出先でMacBook Airなので、iPhoneのテザリングに頼ることがよくあります。

iPhoneのテザリングでは、Bluetoothによる接続を利用します。

  • USBだとiPhoneの(電源アダプタからの)充電ができない
  • (iPhoneのインターネット共有常時オンで)Wi-Fiだと、Wi-Fiスポットを優先利用できない

ためです。

しかし、Bluetoothだと自動接続ができません。いちいちメニューバーの項目をクリックするのは面倒です。そこで、AppleScriptで自動化してみました。

1
2
3
4
5
6
7
tell application "System Events"
tell process "SystemUIServer"
click menu bar item 2 of menu bar 1
click menu item "MyiPhone" of menu 1 of menu bar item 2 of menu bar 1
click menu item "ネットワークへ接続" of menu "mmiPhone" of menu item "mmiPhone" of menu 1 of menu bar item 2 of menu bar 1
end tell
end tell

Alfred Workflowで実行する場合、on alfred_script(q)end alfred_scriptの間に上記スクリプトを挟みます。

pickではなくclickなのは、クリックしてメニューバーを展開しないと子アイテムを取得できないためです。なので、最後の1回は別にpickでもいいです。

menu bar item 2がBluetoothメニューになっていますが、これはスクリプトメニューが表示されているためで、そうでない場合はmenu bar item 1になります。

実のところ、一番実行したいのはスクリプトメニューだったりするわけですが……。まあ、それならAlfred WorkflowでAppleScriptを直接起動すればいい話となりますな。

なんだかんだと、こうしてプログラム的な解決策が用意されているところがMacの良さではあるのかな。

(2014-11-24追記:名前指定で実行する方法あった)

あるじゃん…

ハンドラを下の方に書いておいて、以下のスクリプトでいけました。

1
2
3
4
5
on alfred_script(q)
click_menu_extra("bluetooth/(デバイス名)/ネットワークへ接続")
end alfred_script
--以下略

FoldingTextで編集中のファイルを削除する

FoldingTextで編集中のファイルをゴミ箱に入れたいことけっこうあるんだけどなーFinderで開いて捨てるのめんどいなーと思っていたのですが。

1.メニューバーから

Move to…

スクリーンショット

Trash

スクリーンショット

Move

スクリーンショット

やったぜ。

これで削除できました。あとはウインドウを閉じればOK。

スクショにも写っているように、「システム環境設定>キーボード」でショートカットキーを割り振っておくともっと楽です。

2.Alfred Workflow(AppleScript)

とはいえ、まだ微妙にかったるいのでAppleScriptでやります。

スクリーンショット

AppleScriptの内容は以下の通り。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
on alfred_script(q)
tell application "FoldingText"
set lstDocs to documents -- 開いているドキュメント一覧を取得
set {strName, dFile} to {name, file} of item 1 of lstDocs --最前面ドキュメントの名前・ファイルを取得
close window 1 -- 最前面ウインドウを閉じる
end tell
---- Delete file
tell application "Finder"
delete dFile -- ファイルを削除
end tell
do shell script "echo deleted: " & strName -- 名前を含む通知テキストをエコー
end alfred_script

(追記)こっちでもいけます。FoldingTextから取得できるファイルパスをシェル(POSIX)式のファイルパスに変換してrm。こっちのが速い。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
on alfred_script(q)
tell application "FoldingText"
set lstDocs to documents -- 開いているドキュメント一覧を取得
set {strName, dFile} to {name, file} of item 1 of lstDocs --最前面ドキュメントの名前・ファイルを取得
close window 1 -- 最前面ウインドウを閉じる
end tell
---- Delete file
set dFile to POSIX path of dFile -- ファイルパスをシェル方式に変換
do shell script "rm " & quoted form of dFile --ファイルを削除。パスにスペースを含む場合に備えてクォート付きにする
do shell script "echo deleted: " & strName -- 通知テキストをエコー
end alfred_script