VimでWeb開発してるとブラウザとTerminalを行ったり来たりすることが多い。
ブラウザのタブ切り替えをブラウザでやるのではなく、Terminalでできればノンストレスな開発ができるのではないか。そうだろう。
fzfで実現した
追記:fzf本家の方、Junegunnさんからプルリクを頂き、よりパワフルでスマートなものになった。ほんと感謝、I love fzf。
こんな感じでfzfで今現在開いているChromeのTab一覧を出力して、選択したらアクティブにするスクリプト。
インストール
$ brew tap Rasukarusan/tap $ brew install Rasukarusan/tap/fzf-chrome-active-tab
使い方
$ chrome-tab-activate
ソース
シンプルにAppleScriptとShellScriptの夢のコラボレーション。
成果物がShellScript1つだけってのはミニマムで良いよね。
#!/bin/sh function getTabs() { osascript << EOF set _output to "" tell application "Google Chrome" set _window_index to 1 repeat with w in windows set _tab_index to 1 repeat with t in tabs of w set _title to get title of t set _url to get URL of t set _output to (_output & _window_index & "\t" & _tab_index & "\t" & _title & "\t" & _url & "\n") set _tab_index to _tab_index + 1 end repeat set _window_index to _window_index + 1 if _window_index > count windows then exit repeat end repeat end tell return _output EOF } function setActiveTab() { local _window_index=$1 local _tab_index=$2 osascript -- - "$_window_index" "$_tab_index" << EOF on run argv set _window_index to item 1 of argv set _tab_index to item 2 of argv tell application "Google Chrome" activate set index of window (_window_index as number) to (_window_index as number) set active tab index of window (_window_index as number) to (_tab_index as number) end tell end run EOF } function main() { local tabs=$(getTabs) local title=$(echo "${tabs}" | awk -F '\t' '{print $3}' | fzf) local window_index tab_index read window_index tab_index <<< "$(echo "${tabs}" | grep -F "${title}" | head -n 1 | awk -F '\t' '{print $1, $2}')" setActiveTab $window_index $tab_index } main
学び
今回は結構色々学びがあった。
- ヒアドキュメントでAppleScript書けばShellScript内に埋め込める
osascript << EOF tell application "Google Chrome" ... EOF
みたいな形でShellScript内にAppleScriptを埋め込めるのはいい。今までAppleScriptは別のシェルファイルとして作ってたから、 1つのファイルにまとまるのは非常に良い。
- readコマンドの変数のぶち込み方
read window_index tab_index <<< "$(echo "${tabs}" | grep -F "${title}" | head -n 1 | awk -F '\t' '{print $1, $2}')"
これも「ああなるほどなぁ...」と思うreadの使い方だった。fzfのexamplesに載っていた。
今まで複数の変数を定義する場合、
local window_index=$(echo "${tabs}" | awk -F '\t' '{print $1}') local tab_index=$(echo "${tabs}" | awk -F '\t' '{print $2}')
こんな感じで1個ずつ定義していたが、何回も同じものをecho
していて冗長だなと感じていた。
read a1 a2 <<< awk '{print $1, $2}'
ならphpのlist()みたいな形で一気に複数の変数を定義できる。これは賢い。
- AppleScriptへのコマンドによる引数の渡し方
ヒアドキュメントでAppleScript書く場合、引数はどうやって渡すのかと悩んだが、下記でいけるらしい。
osascript -- - "$_window_index" "$_tab_index" << EOF on run argv set _window_index to item 1 of argv set _tab_index to item 2 of argv ... EOF
終わり
そもそもChromeのTabをfzfで選択したい、ってのは1年ぐらい前に思いついたが今まで手を出していなかった。
当時はAppleScriptを使うっていう脳もなかったし何から調べたら良いのかわからなかったけど、そう思うと以前よりやれること増えた。