α版の頃から追っかけてましたが、ついに 3.3.0 正式版がリリースされましたね! 合わせて以下の記事も続編として公開しております。
左から順に今いるディレクトリのブランチ名、実行中のプロセス、バッテリー・CPU・メモリ・ネットワークの状態、現在時刻が表示されています。それぞれの配置や並べるコンポーネントは GUI で簡単に設定できるようになっています(Preferences > Profiles > Session > Status bar enabled > Configure Status Bar から設定できます)。
テキストの字体や色は自由に変更できますが、Auto-Rainbow をクリックすると、いい感じに色をつけてくれます。
tmux Integration と組み合わせると吉
iTerm2 には tmux Integration という機能がありまして、これは tmux の Control Mode を使って tmux の各ウィンドウを iTerm2 のタブに統合できるのです。
便利な機能なのですが、tmux のステータスバーが消えちゃうのが難点でした。これを iTerm2 のステータスバーで代替できるようになったのです。
コンポーネントを自作する
もちろん、このコンポーネントは自作も可能です。実は、最初のスクリーンショットに挙げている機能のうち、バッテリーの状態は自作したコンポーネントで表示しています。
(2019/8/13 追記)
以下のコードは初めて自作コンポーネントに挑戦する人には複雑すぎるので、続編として簡単なコンポーネントの作り方をまとめました。Python 使わなくても自作が可能ですので参考にしてください。
(2019/5/11 追記)
バッテリー状態の表示は他の人にも便利そうだったので、提案したところ、作者によってネイティブのものが実装されました(20190511 nightly build)。とはいえ、コンポーネントの自作手法としては相変わらず有用だと思われますので、以下のソースは残しておきます。
iTerm2 には昔から AppleScript を使った API が用意されていたのですが、最近はこれが Python3 で書けるようになりました。
事前準備
Python Runtime はメニューからインストールする必要があります。Scripts > Manage > Install Python Runtime の順にクリックするとインストールされます。
- インストールパスは
~/Library/ApplicationSupport/iTerm2
です。 - すでにインストール済みの方は Check for Updated Runtime という表示になっているかもしれません。
ドキュメントやサンプルスクリプトはここにあります。
- Python API — iTerm2 Python API 0.26 documentation
- Status Bar Component — iTerm2 Python API 0.26 documentation
今回はこれを使ってバッテリー残量を表すコンポーネントを自作してみました。
実際には Objective-C のコードを叩いたりなど、いくらか複雑なことをしていますが、ここには簡略化したものを載せておきます。これを ~/Library/ApplicationSupport/iTerm2/Scripts/Autolaunch/battery.py
というファイル名で保存すると GUI から選択できるようになります。
#!/usr/bin/env python3
from iterm2 import Connection, StatusBarComponent, StatusBarRPC, run_forever
from iterm2.statusbar import Knob
from math import floor
from subprocess import CalledProcessError, check_output
from typing import List
import re
chars = ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"]
thunder = "ϟ"
width = 5
async def main(connection: Connection) -> None:
component: StatusBarComponent = StatusBarComponent(
"Battery",
"Show battery remaining",
[],
"|███▎ | 66% 2:34",
30,
"cx.remora.battery",
)
plugged = "🔌"
@StatusBarRPC
async def battery_status(knobs: List[Knob]) -> str:
try:
out: str = check_output(args=["/usr/bin/pmset", "-g", "batt"]).decode(
"utf-8"
)
except CalledProcessError as err:
return "`pmset` cannot be executed"
matched1 = re.match(r".*; (.*);", out, flags=re.S)
if matched1:
status: str = matched1[1]
else:
return plugged
matched2 = re.match(r".*?(\d+)%", out, flags=re.S)
if matched2:
percent: int = int(matched2[1])
else:
return plugged
battery: str
if status == "charged":
battery = width * chars[-1]
elif status == "charging":
mid: int = floor(width / 2)
battery = mid * " " + thunder + (width - mid - 1) * " "
elif status == "discharging":
unit: int = len(chars)
total_char_len: int = len(chars) * width
char_len: int = floor(total_char_len * percent / 100)
full_len: int = floor(char_len / unit)
remained: int = char_len % unit
space_len: int = width - full_len - (0 if remained == 0 else 1)
battery = chars[-1] * full_len
if remained != 0:
battery += chars[remained - 1]
battery += " " * space_len
else:
battery = " " * width
matched = re.match(r".*?(\d+:\d+)", out, flags=re.S)
elapsed: str = matched[1] if matched and matched[1] != "0:00" else ""
last_status: str = "{0} |{1}| {2:d}% {3}".format("🔋", battery, percent, elapsed)
return last_status
await component.async_register(connection, battery_status, timeout=None)
run_forever(main)
スクリプトの状況はメニューアイテム Scripts > Manage > Console から閲覧可能です。
表示イメージは Code-Hex/battery を参考にしました。コンポーネントを作る際は async/await のような結構新し目の機能を使ってコーディングするようです。上記のサンプルスクリプトでは Type Annotation も頑張ってつけていますが必須ではありません。battery_status
という、文字列を返す関数だけが肝で、あとはコピペでいけると思います。
最後に
最初はゴリゴリインターフェイスが変わって大変だったのですが、beta になってだいぶ仕様が固まってきたようです。公式の Issues を随時確認して利用してください。