2016-03-26T03:28:31+09:00

El Capitan の ターミナルウインドウのタイトルに表示される Working Directory の話

今更ながら、OS を El Capitan にアップグレードしました。Mountain Lion からの二つ飛ばしで一気に最新版に追い付きました。これでしばらくは OS のアップグレードに気を払わなくても良い・・ ・と信じたいです。最近の OS は機能的には十分だし、ささやかであったとしても毎度のごとく導入される非互換性に頭を悩ましたくないのです。

E lCapitan で起きたターミナル周りの変化で、気になったものをいくつか。ターミナルのデフォルトの設定では、ウインドウタイトルにシェルの working directory 名とそのプロキシーアイコンが表示されます。

これは、ワーキングディレクトリの URL を特殊なエスケープシーケンスを送ると設定することができます。update_terminal_cwd というエスケープシーケンスを送るシェル関数が /etc/bashrc で PROMPT_COMMAND に設定されています。PROMPT_COMMAND に設定されたシェルコマンドは、プロンプトが更新されるたびに(すなわち何かコマンドが実行されるたびに)実行され、ターミナルタイトルの表示がワーキングディレクトリを追随するようになっています。この仕組みは、Mac OS X 10.7 Lion の時に導入されました。

ターミナルタイトルに送る URL のパーセントエスケープ

エスケープシーケンスとして送る URL は、URL ですから 2 バイト文字などはパーセントエスケープされていなければなりません。しかし、OS X 10.10 までの、update_terminal_cwd の実装ではスペース文字しかエスケープするようになっておらず、そのためディレクトリ名が日本語だとタイトルの表示がワーキングディレクトリを追随していませんでした。そのため、自分は Perl で2バイト文字もちゃんとパーセントエスケープする自作関数を PROMPT_COMMAND に設定していました。

OS X 10.11 El Capitan では、/etc/bashrc が提供する update_terminal_cwd もアップデートされて2バイト文字もちゃんとエスケープするようになっています。しかも、自分のように Perl などを使ったりせず、bash の機能だけを使った男気溢れる実装になっていることに感銘を受けました。

こころで、ターミナルタイトルに設定されるワーキングディレクトリの URL を外部のプロセスから取得できたら便利だと思いませんか? 例えば、AppleScript から取得できたらいろいろ応用が考えられます。Finder で選択されている場所と同じワーキングディレクトリのターミナルを探して前面に持ってくることができたら、便利だと思いませんか?「フォルダに新規ターミナル」がサービスメニューとしてありますが、これだと同じフォルダにいくつものターミナルが開かれてターミナルウインドウが散らかりがちになってしまいますね。

拙作 Open in Terminal は、指定したフォルダがワーキングディレクトリになっているターミナルを探して、無ければ新しいターミナルを開くアプリケーションです。残念ながら後述する理由で、今のところ OS X 10.11 El Capitan に対応していません。

さて、残念ながら、ターミナルタイトルに設定されるワーキングディレクトリの URL の取得はターミナル.app の AppleScript のサポートに含まれていません。テクニカルには、まったく難しいことはなく、自分にやらせてくれたら30分で終わる仕事なのですが。実際、僕はワーキングディレクトリを取得するスクリプティング機能追加を作って快調に利用していました (TerminalControl.osax ) 。スクリプティング機能追加は、別のプロセスに実行コードを差し込むことができます。Objective-C の柔軟で動的な性質を利用すればターミナル.app 内のターミナルタブオブジェクトにアクセスして、設定されているワーキングディレクトリを取得することなど容易い話なのです。

しかし、スクリプティング機能追加を別のプロセスに差し込むことは、OS X 10.11 で登場した System Integrity Protection (SIP) の影響で利用できなくなってしまいました。確かに危険な香りのする利用方法ですが、その便利さゆえに多くの機能強化系ソフトで利用され、El Capitan で動かなくなったツールが少なくないようです。

ターミナルタイトルにパスを設定する

Mac OS X 10.6 以前は、プロキシーアイコンなど表示されませんでしたが、これまたエスケープシーケンスを使って current working directory のパスをターミナルウインドウのタイトルに表示する設定が普及していました。

export PROMPT_COMMAND='echo -ne "\033]0;${PWD/#$HOME/~}\007"'

しかし、パス中の2バイト文字は表示されないという問題があり、エスケープシーケンスではなくAppleScript を使ってターミナルタイトルにパスを設定するコマンドを作っていました (SmartTitle ) 。

しかし、OS X 10.11 El Capitan では、ターミナルタイトルを設定するエスケープシーケンスに2バイト文字が含まれていても、ちゃんと動作します。さらに、プロキシーアイコンも表示されます。

遡って確認したら、OS X 10.7 のターミナルから動作しました。

さて、なんでこんな古のテクニックを調査しだしたかというと、El Capitan から update_terminal_cwd が設定するワーキングディレクトリの URL を取得できなくなったから。Open in Terminal は Mac OS X 10.6 以前では SmartTitle で設定したターミナルタイトルから現在のワーキングディレクトリを判断する仕様でした。同様の仕組みを復活させることを検討中です(手元の Open in Terminal はそのような仕様ですでに稼動しています)。果たしてターミナルタイトルに依存してよいものか、OS にデフォルトで設定されている仕組みを殺してしまってよいものか、思案中です。