Firefoxツリー型タブをTabSnailで

ツリー型タブをKeySnailでコントロール

Firefoxアドオン「ツリー型タブ」

tree_style_tab.jpg

おもうところあって Firefox アドオンの ツリー型タブ (Tree Style Tab) を使ってみたら、すごく便利だと思った。

このツリー型タブは、Firefoxのタブたちをツリー構造で分類してくれる。例えば、リンクを Ctrl+クリック して開いたタブは、もとのタブに属する「子供のタブ」になる。子供は何人だって設けられるし、孫だって曾孫だっていける。そうしてタブを仮想的なツリーに形成していく。

タブの表示位置は、Firefoxデフォルトの上部のままにもできる。だがそれでは親子関係もあったもんじゃない。

本領を発揮させるにはサイドバーを表示させることだ。よくあるファイラーのフォルダツリーのように、子供や孫はインデントで表現される。

マウスでドラッグして順番を変えたり、親を子に(子を親に)したり、それに、親子関係をかたまりにしてごっそりと移動もできる。

ツリーを気にして整理するようになる

調べものをする時にはFirefoxのタブをじゃんじゃか開いていくのだけれども、ツリーで管理できると見通しがよくとてもわかりやすい。もうこれがないと自分がなにを調べていたのかさえ覚束ない感じになってしまう。それはそれで別の問題があるのかもしれないけれど。

使ってみて気付いたのだが、以前は開いたタブが有用か否かにかかわらず開きっぱなしで次、また次と新しいタブをポンポン開いていくもので、あっという間にタブが50個とかになって Firefox がモッサリし始めたものだ。

しかたがないので幾つも消すのだけれど、そのうちまたモッサリしだす。それでもう面倒だから全部消したりして、でももう一度みたいのがあるからタブ復帰させたり履歴漁ったりとか、どうにも効率が悪かった。

ツリー型タブを表示しておくとツリーを気にするから整理するようになり、いらないものも閉じながらブラウズするようになるので、そのような事が減るようなのだ。

私は、調べている事柄ごとにツリーを設けてタブグループ的に使うというのをやっている。

検索サイトなどを軸に、そこから関心のありそうなリンクを子タブとしていくつか先に開いておく。そうしてから子タブへ移って、いらない子タブをクローズしながら順に読んでいく、みたいにすると他の調べ物との間で識別しやすく、捗る。

キーボードでツリー型タブをコントロール

FirefoxアドオンのKeySnailには TabSnail (tabsnail.ks.js) という、ツリー型タブをコントロールするプラグインが公開されている。これを使えばキーボードでコントロールできるので、さらに捗るだろうからちょっとインストールしてみた。

でもどういうわけか「ext “tst-*” not found 」などとエラーが出る。

グググッといってみた。すると、

No ‘ext’s detected · Issue #3 · gifnksm/TabSnail · GitHub

書かれてある通りにしてみよう。tabsnail.ks.js の200行以上下の “const Samplebinding =” ではじまる行から後ろを全部コメントアウトしてみたら動くようになった。

TabSnailのキーバインド

Twitterなどのウェブサイトでは便利なショートカットキーがマップされているので、keysnailプラグインの Site local keymap (site-local-keymap.ks.js) を使って調整している。けれどもKeySnailに設定してあるキーと重なってしまっていると、Site local keymap か KeySnail そのものをモードオフしなければならないのでうまくない。キーを切り替えたりしている隙に何を調べていたのか忘れてしまうのだ。

そこで、Twitter、Reddit、GitHub、Googleなどでつかわれないキーをプレフィクスキー的に割り当ててしまおうかと考えた。調べてみると、’T’ と ‘C-t’ は大丈夫そうだ。Firefoxでは ‘C-t’ が新規タブオープンに割り当てられているが、これはkeysnailの setGlobalKey で ‘C-t C-c’ にあてなおしてしまったらいい。

以下設定ファイル keysnail.js から抜粋。

// Global keybindings

key.setGlobalKey([['C-t', 'C-c'], ['C-t', 'c']], function (ev) {
    BrowserOpenTab();
}, '新しいタブを開く', false);

key.setGlobalKey([['C-t', 'C-/'], ['C-t', '/']], function () {
    ext.exec("list-closed-tabs");
}, '最近閉じたタブ一覧');

key.setGlobalKey([['C-c', 'C-n'], ['C-c', 'n'], ['C-<right>'], ['C-M-l']], function (ev) {
    getBrowser().mTabContainer.advanceSelectedTab(1, true);
}, 'タブ選択 下', false);

key.setGlobalKey([['C-c', 'C-p'], ['C-c', 'p'], ['C-<left>'], ['C-M-h']], function (ev) {
    getBrowser().mTabContainer.advanceSelectedTab(-1, true);
}, 'タブ選択 上', false);

// KeyBindings for TabSnail

key.setGlobalKey(['C-t', 'C-n'], function (ev, arg) {
    ext.exec("tst-select-next-sibling-tab", arg, ev);
}, '兄弟タブ選択 下 (次)');

key.setViewKey([['L'], ['n'], ["g", "t"], ["."]], function (ev, arg) {
    ext.exec("tst-select-next-sibling-tab", arg, ev);
}, '兄弟タブ選択 下 (次)');

key.setGlobalKey(['C-t', 'C-p'], function (ev, arg) {
    ext.exec("tst-select-previous-sibling-tab", arg, ev);
}, '兄弟タブ選択 上 (前)');

key.setViewKey([['H'], ['p'], ["g", "T"], [","]], function (ev, arg) {
    ext.exec("tst-select-previous-sibling-tab", arg, ev);
}, '兄弟タブ選択 上 (前)');

key.setGlobalKey(['C-t', 'C-a'], function (ev, arg) {
    ext.exec("tst-select-first-sibling-tab", arg, ev);
}, '兄弟タブ選択 最初', true);

key.setGlobalKey(['C-t', 'C-e'], function (ev, arg) {
    ext.exec("tst-select-last-sibling-tab", arg, ev);
}, '兄弟タブ選択 最後', true);

key.setGlobalKey(['C-t', 'C-u'], function (ev, arg) {
    ext.exec("tst-select-parent-tab", arg, ev);
}, '親タブを選択');

key.setGlobalKey(['C-t', 'C-j'], function (ev, arg) {
    ext.exec("tst-select-first-child-tab", arg, ev);
}, '最初の子タブを選択');

key.setGlobalKey(['C-t', 'C-h'], function (ev, arg) {
    ext.exec("tst-select-last-child-tab", arg, ev);
}, '最後の子タブを選択');

key.setGlobalKey([['C-N'], ['S-C-<down>']], function (ev, arg) {
    ext.exec('tst-move-selected-tab-right', arg, ev);
}, '選択中のタブを下へ移動');

key.setGlobalKey([['C-P'], ['S-C-<up>']], function (ev, arg) {
    ext.exec('tst-move-selected-tab-left', arg, ev);
}, '現在のタブを上へ移動');

key.setGlobalKey(['C-t', 'C-l'], function (ev, arg) {
    ext.exec("tst-read-selected-tab-later", arg, ev);
}, '現在のタブを後回しにする');

key.setGlobalKey([['C-B'], ['S-C-<left>']], function (ev, arg) {
    ext.exec("tst-promote-tab", arg, ev);
}, '現在のタブを上の階層に移動');

key.setGlobalKey([['C-F'], ['S-C-<right>']], function (ev, arg) {
    ext.exec("tst-demote-tab", arg, ev);
}, '現在のタブを下の階層に移動');

key.setGlobalKey(['C-t', 'C-o'], function (ev, arg) {
    ext.exec("tst-toggle-collapse-expand-tree", arg, ev);
}, 'タブフォールド (トグル)', true);

key.setGlobalKey(['C-T'], function (ev, arg) {
    ext.exec("tst-toggle-autohide-tabbar", arg, ev);
}, 'タブバーの表示 (トグル)', true);

key.setViewKey(['T', 'T'], function (ev, arg) {
    ext.exec("tst-toggle-autohide-tabbar", arg, ev);
}, 'タブバーの表示 (トグル)', true);

上記の設定で以下のようなキー操作が可能になる。

キー 動作 TabSnail
C-t C-c タブの新規作成
C-t C-/ 最近閉じたタブ一覧
C-c C-n タブ選択 次
C-c C-p タブ選択 前
C-t C-n タブ選択 (兄弟タブ) 次 tst-select-next-sibling-tab
C-t C-p タブ選択 (兄弟タブ) 前 tst-select-previous-sibling-tab
C-t C-a タブ選択 (兄弟タブ) 最初 tst-select-first-sibling-tab
C-t C-e タブ選択 (兄弟タブ) 最後 tst-select-last-sibling-tab
C-t C-u タブ選択 (親タブ) tst-select-parent-tab
C-t C-j タブ選択 (子タブ) 最初 tst-select-first-child-tab
C-N 選択中のタブを移動 次 tst-move-selected-tab-left
C-P 選択中のタブを移動 前 tst-move-selected-tab-right
C-B 選択中のタブ階層移動 上(左) tst-promote-tab
C-F 選択中のタブ階層移動 下(右) tst-demote-tab
C-t C-l 選択中のタブを後へまわす tst-read-selected-tab-later
C-t C-o 現在のタブの折畳み (トグル) tst-toggle-collapse-expand-tree
C-T タブバーの表示 (トグル) tst-toggle-autohide-tabbar