画面共有のたびに「それ何?」と聞かれるようになった話
IT技術
最近、社内MTGやペアプロで画面共有をするたびに、そんな質問を浴びるようになりました。
VSCodeの機能でもなければ、Neovimの最新プラグインでもありません。AIコーディング全盛の今、私たちはVSCodeをそっと閉じ、ターミナル(CLI)の世界へ回帰しました。
この記事では、私たち2人のエンジニア(あらい & いながき)が構築した「手と脳を止めない最強のターミナル環境」の全貌を紹介します。
環境の土台(AeroSpace / WezTerm)
まずは、CLIツールたちが最高のパフォーマンスを発揮するための「土台」作りです。マウス操作への依存を減らし、環境のすべてをコード(dotfiles)で管理するための基盤を紹介します。
場面:ランチャーも出ない画面の切り替え
画面共有中、私がSlackで飛んできた仕様を確認し、瞬時にエディタ(ターミナル)へ戻った時のこと。
「いまどうやって切り替えました? ランチャーもCmd+Tabも出ませんでしたよね?」
かつての私は、アプリを切り替えるためにCmd+Tabを連打し、トラックパッドをスワイプして仮想デスクトップを探し回り、ウィンドウの端をマウスでリサイズしていました。まさに「手は動いているが、思考は止まっている」状態です。この無駄な時間を解消してくれたのが、タイル型ウィンドウマネージャの AeroSpace です。
AeroSpace — 思考を止めないウィンドウ管理
AeroSpaceはMacのウィンドウを自動で敷き詰めてくれるツール。Magnetなどの有料ツールも検討しましたが、設定をTOMLで完結できる点が決め手でした。先ほどの「切り替え」の正体は、アプリの頭文字へのワークスペース強制バインドです。
1# ~/.config/aerospace/aerospace.toml(抜粋)
2
3[[on-window-detected]]
4
5if.app-id = 'com.tinyspeck.slackmacgap'
6
7run = 'move-node-to-workspace S'数字での管理ではなく「Alt+Sで絶対Slack」が反射で開くように設計しています。「どこにいるか」を探すのではなく「何を見たいか」でキーを叩くため、画面共有越しには一瞬でワープしたように見えます。
実践での課題:モニタ構成の環境差分をどう吸収するか
AeroSpaceを使い込むと、ある課題にぶつかりました。自宅はトリプルモニタ、外出先はMac単体。この環境差分を、単一のconfigでどう破綻せずに運用するか。ここでAeroSpaceの workspace-to-monitor-force-assignment を使い、「マッチしなければ最初の有効なモニタ(main)へ落ちる」という仕様を設計として使い切りました。
1# ~/.config/aerospace/aerospace.toml(※一部抜粋して簡略化しています)
2
3persistent-workspaces = ["M", "S", "A"] # ...実際は他のワークスペースも指定
4
5[workspace-to-monitor-force-assignment]
6
7M = '^built-in' # 内蔵(全環境で確実にマッチ)
8
9S = '^VG' # 縦モニタ(自宅のみマッチ。他はmainへフォールバック)
10
11A = 'main' # メインモニタ
12
13# ...中略(他の数字・アルファベットのワークスペース設定が続く)...S = '^VG' は自宅ならASUSの縦モニタへ割り当てられますが、外出先ならマッチせず main(内蔵)へ自然に着地します。環境分岐のif文やシェルスクリプトを一切書かずに、宣言的なTOMLだけで差分を吸収できました。
余談:AeroSpace単体だと「いまどの窓がアクティブか」を見失うため、mozumasuさんの記事を参考に
bordersバイナリでアクティブウィンドウに枠線をつけています。この方の開発環境には我々2人とも多大な影響を受けています。
WezTerm — AI時代のターミナル回帰
ウィンドウ管理の次は、ターミナルそのものです。私は現在 WezTerm を愛用しています。
AI時代になり、Cursorなどのエディタへ一度は移行しました。しかし、エディタ内でもClaude Code等のAIエージェントを動かすようになると、結局ターミナルペインでの作業時間が一番長くなったのです。「どうせずっとターミナルにいるなら、キーボード操作で完結する洗練された環境を作りたい」。設定がLuaで書け、GPUレンダリングで高速、かつ細部までカスタマイズができるWezTermに行き着きました。
一昔前なら、難解なLuaやTOMLをイチから書くのは時間のかかる作業でした。しかし今はAIの時代です。Claudeに「WezTermをこんな見た目にしたい」と投げれば、精度の高いコードが即座に返ってきます。AIの進化が、dotfilesメンテのハードルを劇的に下げてくれました。これが、私たちが今CLIへ回帰している最大の理由です。
CLI/TUI操作の高速化
土台は整いました。ここからはWezTermの上で動く「コマンド一発で世界が変わる」ツール群を紹介します。どれも導入コストは5分ほどですが、日々の作業効率を底上げしてくれます。
zoxide —の呪縛からの解放
たぶん私が最初に「それ何?」と聞かれたのは、zoxide です。
画面共有中、ターミナルに z project-〇〇 と打ち込んだ瞬間、深い階層の目的ディレクトリへジャンプしました。
普段の cd は遅いというより、脳が止まります。Tab補完を頼りにゆっくり打ったり、cd ../../../ と階層を数えたりしていると、当初の「バグの原因を直す」という思考から離れてしまいます。zoxide は過去に訪れたディレクトリを学習し、部分一致で一気にジャンプできます。
1# .zshrc に追記するだけ
2eval "$(zoxide init zsh)"頻繁に行くディレクトリほど優先度が上がるため、使い込むほど精度が増します。私の1日数十回の cd 操作は、ほぼすべてこれに置き換わりました。
fzf — あいまい検索の万能ナイフ
ディレクトリ移動が速くなると、次は「ファイル選び」や「コマンド履歴検索」を高速化したくなります。
あらいさんと画面共有中、私が何気なく Ctrl+R を押すと、画面下半分にコマンド履歴が展開し、数文字打っただけで目的のDockerコマンドが浮かび上がりました。
fzf は、あらゆる「一覧から1つ選ぶ」行為を高速なあいまい検索に置き換えます。
1# .zshrc
2eval "$(fzf --zsh)"
3export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
4export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
5export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
6export FZF_DEFAULT_OPTS='--preview "bat --color=always --style=numbers --line-range=:500 {}"'ポイントは、検索バックエンドに fd(高速で .gitignore を尊重)、プレビューに bat(シンタックスハイライト)を指定している点です。
| キー | 機能 |
|---|---|
Ctrl+R | コマンド履歴のあいまい検索 |
Ctrl+T | カレント以下のファイル検索(プレビュー付き) |
Alt+C | カレント以下のディレクトリにcd |
そして非常に便利なのが、zoxideとの連携コマンド zi です。行き先が明確なら z、うろ覚えなら zi を叩いてfzfのUIから絞り込む。思考を邪魔しないこの体験は、CLI環境構築において大きな感動でした。
lazygit — TUIで動くGitクライアント
複雑なgit操作(ステージング、リベース、stashなど)をコマンドだけで完結させるのは手間がかかります。そこで lazygit です。
あらいさんとペアプロ中、「ちょっとコミット整えますね」と lazygit と打った瞬間、ターミナルが色分けされたUIに切り替わりました。「えっ、いまGUI開きました?」と驚かれましたが、これもCLI上で動いています。
起動は1秒未満。左手だけで95%の操作が完結します。特に commit, stash, cherry-pick などの操作が、カーソルを上下に動かすだけで完了するのは非常に快適です。コマンドの長い引数を思い出す時間も、別ウィンドウへ視線を移すコンテキストスイッチも削減されます。

↑このようなUIで非常に使いやすいです。
yazi — ターミナルの中で動くファイラ(ハブ)
最近はMac標準搭載のFinderはほとんど開かず、このyaziというツールで代替しています。
yazi はTUIで動くファイルマネージャですが、本当の価値は単なるファイラではなく「CLIツールを束ねるハブ」になることです。
1# keymap.toml 抜粋
2[manager]
3
4prepend_keymap = [
5 { on = "z", run = "plugin zoxide", desc = "Jump via zoxide" },
6 { on = "Z", run = "plugin fzf", desc = "Jump via fzf" },
7 { on = [ "g", "i" ], run = "plugin lazygit", desc = "Open lazygit" },
8]yaziの中から z でzoxide、Z でfzf、g → i でlazygitが起動します。ファイル操作中に「コミットしたい」と思えば g → i を押し、終わればまたyaziに戻ってくる。Finderの中からfzfを呼ぶ発想はなかなか出ませんが、ディレクトリ移動もウィンドウ切り替えもなく操作が完結する、これがTUIの柔軟なところです。
fzf及びzoxideの動きはお見せできませんが、yazi上でlazygitを起動してコミットする流れや、実際の表示などをお見せします!ハマりどころメモ:yaziの画像プレビューはターミナル(WezTerm等)と
chafaなどの補助ツールに依存します。最初は画像が表示されず少し苦戦しました。導入時はプレビューを一旦諦め、後からじっくり設定を整えるのがおすすめです。
cmux — AI時代のターミナルマルチプレクサ
ここまで紹介した強力なツール群を、さらに高い次元で統合するツールを紹介します。
「その左の縦タブは何なんですか」
最近の社内MTGで一番聞かれるのがこれです。私が乗り換えた cmux というターミナル統合環境。ひとことで言うと「Claude CodeなどのAIエージェント利用を前提に設計されたマルチプレクサ」です。
なぜ cmux なのか?
WezTerm単体の分割やtmuxではなく、cmuxを選んだ理由は3つあります。
- ワークスペースが「縦タブ」で常時可視:tmuxのセッションと違い、左サイドバーに
apifrontendのように案件単位で並べておけるため、コンテキストを見失いません。 - ペイン分割が
Cmd + \\/Cmd + -で終わる:Vimライクなキーバインドに設定でき、思考を遮ることなく瞬時に画面を分割できます。 Cmd + Shift + \\で「ペインとしてのブラウザ」が開く:単なるChromeの埋め込みではなく、ターミナルと同じレイアウトに混ざるブラウザペインです。localhost:3000をCmd+Tab無しで直接覗ける体験は非常に便利です。- Claude Codeの入力待ち通知が標準搭載:特に設定することなく、Claude Codeが入力待ちになると通知をしてくれます。それだけでなく、入力待ちになっているワークスペース及びペインがわかりやすく表示されるので非常に使いやすいです。
lazygitとcmux、そしてAIエージェント
私は左にyazi、右にClaude Codeという構成で1日を始めます。このレイアウトを自動化するため、zshrcに cdev という関数を用意しています。
1cdev() {
2 local dir="${1:-$(pwd)}"
3 local ws="$CMUX_WORKSPACE_ID"
4 local yazi_surface="$CMUX_SURFACE_ID"
5
6 # 現在のペインの右に新しいペイン(surface)を作り、そのIDを取得する
7 local claude_out=$(cmux new-split right --workspace "$ws" --surface "$yazi_surface")
8 local claude_surface=$(echo "$claude_out" | grep -oE 'surface:[0-9]+' | head -1)
9
10 # 取得した各ペインに対して、外部からコマンドを流し込む
11 _cdev_send "$yazi_surface" "cd $dir && yazi ."
12 _cdev_send "$claude_surface" "cd $dir && cmux claude-teams"
13}tmuxの send-keys のように複雑なペイン番号を管理する必要はありません。cmuxが提供する $CMUX_WORKSPACE_ID などの環境変数を使うことで、「現在のシェルがどのペインにいるか」をスクリプトで特定し、別ペインにAIエージェントを自動起動できます。
difit-cmux:コードレビューを「Cmd+\ で開く」に変える
私はコードレビュー(自分の差分確認含む)を difit に寄せています。これをcmuxと連携させる自作スクリプト difit-cmux をこちらを参考に書きました。
1#!/bin/bash
2CMUX="/Applications/cmux.app/Contents/Resources/bin/cmux"
3
4# いま見ているターミナルの cwd を、外部から直接取得する
5targetDir=$("$CMUX" sidebar-state | awk -F= '/^focused_cwd=/{print $2}')
6cd "$targetDir" || exit 1
7
8"$CMUX" notify --title "Difit" --body "Loading diff: $targetDir"
9# ... (現在のブランチ状態を見て、difitのサブコマンドを自動で切り替える処理) ...
10
11# サーバが応答するまでcurlでポーリング待機
12while ! curl -s http://localhost:4966/ >/dev/null 2>&1; do sleep 0.5; done
13
14# cmuxのブラウザペインで開き、生成されたsurface IDを取得
15browserSurface=$("$CMUX" --json browser open-split "http://localhost:4966/" \
16 | grep -o '"ref" *: *"surface:[^"]*"' | head -1 | grep -o 'surface:[0-9]*')
17
18# ペインが閉じられたかを監視し、閉じたらdifitサーバも落とす
19while "$CMUX" surface-health 2>&1 | grep -q "$browserSurface"; do sleep 1; done
20kill_difitAeroSpace側でこれをホットキーに割り当てておくと、キーボードから手を離さずに「左:エディタ / 右:ブラウザで差分」がターミナル内に開きます。ペインを閉じれば裏のサーバも自動で落ちるため、「diffを読むためにブラウザを開いてタブを探す」という工程が丸ごと省略されます。
以下は実際にcmux上でdifitを起動してセルフコードレビューを行うデモ動画になります。
ハマりどころと回避策(cmux × difit 編)
実際に構築する中で踏んだいくつかの罠と、その回避策も共有しておきます。
| 罠 | 症状 | 回避策 |
|---|---|---|
| ポート競合 | Address already in use | trap コマンドを活用し、起動前後に lsof で対象プロセスを終了させる |
| サーバ起動遅延 | ブラウザに「接続できません」 | 上記コードのように、curl ヘルスチェックがOKを返すまで待機する |
| ゾンビプロセス | ペインを閉じても裏で生きる | surface-health でペインを監視し、消えたら自身でサーバも終了させる |
| Automation Mode | sidebar-state が空を返す | 重要: 設定で「Automation Mode」を必ずONにする(ここで時間を溶かしました) |
おわりに:なぜ僕らはCLIに投資し続けるのか
AeroSpaceでウィンドウ管理を自動化し、WezTermを土台に据え、zoxide/fzf/yaziで操作を効率化し、cmuxでAIとブラウザを統合する。
少しマニアックに見えるかもしれませんが、コンテキストスイッチ(画面やツールの切り替えによる思考の停止)をゼロに近づけることは、開発の生産性に直結します。手と脳がスムーズに同期する感覚は、日々の開発体験を大きく向上させてくれます。
画面共有のたびに「それ何?」と聞かれる日々は、まだまだ続きそうです。皆さんもぜひ、AIの手を借りながら「自分に合ったターミナル環境」を育ててみてください。
紹介したツールたちのリンク
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!カジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
カレーが好きです



