My daily macOS terminal: Ghostty, tmux, zsh and Neovim for running web apps on the Mac and working on ROS 1 / ROS 2 inside Docker containers and robots over SSH.
Install · Features · Keys · Documentation · Develop
One repository for the whole terminal: the emulator, the multiplexer, the shell and the editor share
one theme and one font, and know about each other. The prompt is a plain ASCII folder branch >,
the tab and tmux window titles say which host you are on, Ctrl-h/j/k/l moves between tmux panes
and Neovim splits, and yanks reach the macOS clipboard from inside containers and SSH sessions.
git clone git@github.com:agus-darmawan/dotfiles.git ~/dotfiles
cd ~/dotfiles && ./install.shThe installer runs the Brewfile, backs up existing configs to ~/.dotfiles-backup/,
links everything with GNU Stow, adds an iTerm2 profile, prepares ~/.ssh/config with the
containers and robots host files and ~/.config/apps, and installs the zsh and Neovim plugins.
Then open Ghostty and type t. Check the result with ~/dotfiles/tests/smoke.sh.
Step by step: docs/INSTALL-MACOS.md.
Inside a dev container (Ubuntu 20.04+), a Jetson or a robot: ~/dotfiles/container/install.sh
(guide).
Terminal and tmux
- Ghostty with Catppuccin Mocha, JetBrainsMono Nerd Font and a drop-down quick terminal on
cmd+`. - Prefer iTerm2?
install.shadds a matching profile: Preferences → Profiles → dotfiles (Catppuccin Mocha) → Set as Default. - The VS Code terminal uses the same shell; add the font and title settings from vscode/.
- tmux status bar on top: session, windows (named after the folder, or the host in SSH panes), Cloudflare Tunnel, CPU, GPU, RAM, CPU temperature, download/upload speed, running containers, battery, time, all plain text.
- No tmux plugins. Popups for lazygit, lazydocker and btop; fuzzy pickers for projects, sessions, SSH hosts, containers and web apps.
dev <host>opens a session on a container or robot over SSH (windows code, build, run).F12hands every key to a tmux running on the robot.
Web apps
app molly(orC-a a) opens a registered app in its own tmux window and starts it: PM2, docker compose orpnpm dev, picked from what the folder contains.tunshows what the Cloudflare Tunnel serves;tun add gcs.example.com 5173adds a hostname with its DNS record,tun share 3000gives a temporary public URL.- PM2 and Docker shortcuts:
pml,pmlog,dps,dcu,dcl, lazydocker onC-a D. Guide: docs/WEB.md.
Neovim
- Own modular config, every language in one registry file: LSP, formatter, linter and parser.
- C++ (clangd), Python, CMake, ROS launch/URDF/xacro XML,
.msg/.srv, TypeScript and Next.js, Dart, Docker, Bash, Lua, Markdown. - 20 plugins: blink.cmp completion, snacks.nvim pickers and explorer, which-key, gitsigns, lazygit.
ROS 1 and ROS 2 (containers and robots)
Space rbbuilds the package you are editing with colcon or catkin: errors land in the quickfix list,compile_commands.jsonis merged and clangd restarts.- Pickers for topics, nodes, launch files and executables (
ros2 launch/roslaunch,ros2 run/rosrun); syntax for.msg,.srvand.actionfiles. - Shell helpers inside containers and on robots (never on the Mac), for ROS 2 (colcon) and ROS 1 (catkin):
ros,rosdomain/rosmaster,cb/cbp/ct,rtopic,rnode.
Containers and robots
ssh humble,ssh jazzy,ssh noetic: host entries for the dev containers are ready in~/.ssh/config.d/containers.dsh/C-a dopens the best shell in any running container;dev <host>opens a full session in it over SSH.- SSH multiplexing: extra panes on the same robot connect instantly;
sall go2 lite3types into several robots at once. NVIM_OFFLINE=1on machines without internet skips every automatic download.
tmux prefix Ctrl-a · Neovim leader Space
| Keys | Action |
|---|---|
t |
attach or create the tmux session main |
C-a | · C-a - |
split right · split down |
C-h/j/k/l |
move between tmux panes and Neovim splits |
C-a f · C-a s |
open a project · switch session |
C-a S · C-a d |
SSH to a host · shell into a container |
C-a a |
open a web app in a new window |
C-a g · C-a b |
lazygit · btop |
Space Space · Space / |
find files · grep |
gd · K · Space ca |
definition · hover · code action |
Space rb · Space rt |
build this ROS package · ROS topics (containers) |
Space gg |
lazygit |
Every key: docs/KEYMAPS.md
| For | Document |
|---|---|
| Everything in one PDF (LaTeX) | User manual |
| Installing on the Mac, iTerm2 and VS Code | INSTALL-MACOS.md |
| Learning the setup step by step (Bahasa Indonesia) | TUTORIAL.md |
| All shortcuts: Ghostty, tmux, Neovim | KEYMAPS.md |
| Shell commands: web apps, Docker, SSH, ROS, git | COMMANDS.md |
| Web apps, Cloudflare Tunnel, PM2 | WEB.md |
| ROS dev containers over SSH, robots | CONTAINER.md |
| Local overrides, status bar, languages | CUSTOMIZE.md |
| Something broken | TROUBLESHOOTING.md |
All guides: docs/.
Personal overrides stay out of git: ~/.zshrc.local, ~/.config/tmux/tmux.local.conf,
~/.config/git/config.local, ~/.config/nvim/lua/config/local.lua, ~/.ssh/config.d/.
~/dotfiles/tests/smoke.sh # links, tmux, zsh helpers, every Neovim pluginThe ci workflow runs on every push: ShellCheck, StyLua and syntax checks; a full install.sh on
macOS followed by the smoke test; and container/install.sh inside the ros:noetic, ros:humble
and ros:jazzy images, where Neovim builds a real catkin or ament package.
Update with git pull && ./install.sh --no-brew; remove the links with ./install.sh --unlink.
Released under the MIT License.


