From 0c154b41ed240d9391e6391968b26847d474a974 Mon Sep 17 00:00:00 2001 From: TOGEP Date: Fri, 7 Aug 2026 17:01:20 +0900 Subject: [PATCH] Migrate terminal multiplexer to Herdr --- .tmux.conf | 107 ----------------------------- .zshrc | 10 --- Brewfile | 1 + herdr/config.toml | 43 ++++++++++++ iterm2/com.googlecode.iterm2.plist | 10 +-- script/link.sh | 27 ++++---- 6 files changed, 62 insertions(+), 136 deletions(-) delete mode 100644 .tmux.conf create mode 100644 herdr/config.toml diff --git a/.tmux.conf b/.tmux.conf deleted file mode 100644 index b2eb48f..0000000 --- a/.tmux.conf +++ /dev/null @@ -1,107 +0,0 @@ -##### Basic ##### - -# Faster key response -set -sg escape-time 0 - -# Mouse support (optional, handy for resizing panes) -set -g mouse on - -# Forward terminal focus events to apps (for nvim FocusGained) -set -g focus-events on - -# 256 color / truecolor -set -g default-terminal "tmux-256color" -set -ga terminal-overrides ",*:Tc" - -# Start numbering at 1 (optional) -set -g base-index 1 -setw -g pane-base-index 1 - -set -g pane-border-style "fg=#45475a" -set -g pane-active-border-style "fg=#89b4fa" - -# Status line -set -g status-interval 3 -set -g status-left-length 50 -set -g status-right-length 150 -set -g status-style "bg=#11111b,fg=#cdd6f4" -set -g status-left "#[fg=#89b4fa,bold] #S #[default]" -set -g status-right "#(task rc._forcecolor=off rc.color=off +ACTIVE 2>/dev/null | awk 'NR==4{print substr(\$0, index(\$0,\$2))}' | cut -c-40) | #{b:pane_current_path} | %H:%M" - -# Key binds -# Reload tmux.conf -bind-key r source-file ~/.tmux.conf \; display-message "tmux.conf reloaded" - -# Split panes (more ergonomic) -bind-key | split-window -h -c "#{pane_current_path}" -bind-key - split-window -v -c "#{pane_current_path}" - -# Navigate panes (vim-like) -bind-key h select-pane -L -bind-key j select-pane -D -bind-key k select-pane -U -bind-key l select-pane -R - -# Resize panes (repeatable) -bind-key -r H resize-pane -L 5 -bind-key -r J resize-pane -D 5 -bind-key -r K resize-pane -U 5 -bind-key -r L resize-pane -R 5 - -# Quick layout cycling -bind-key Space next-layout - -# Ctrl-q to open an AI agent popup in the current pane's directory. -# Keeps a persistent session named "q-popup" and attaches/creates as needed. -bind-key -n C-q display-popup -d "#{pane_current_path}" -w 80% -h 80% -E \ - "tmux new-session -A -s q-popup 'source ~/.zprofile && codex'" - -# sesh -bind-key "T" run-shell "sesh connect \"$( - sesh list --icons | fzf-tmux -p 80%,70% \ - --no-sort --ansi --border-label ' sesh ' --prompt '⚡ ' \ - --header ' ^a all ^t tmux ^g configs ^x zoxide ^d tmux kill ^f find' \ - --bind 'tab:down,btab:up' \ - --bind 'ctrl-a:change-prompt(⚡ )+reload(sesh list --icons)' \ - --bind 'ctrl-t:change-prompt(🪟 )+reload(sesh list -t --icons)' \ - --bind 'ctrl-g:change-prompt(⚙️ )+reload(sesh list -c --icons)' \ - --bind 'ctrl-x:change-prompt(📁 )+reload(sesh list -z --icons)' \ - --bind 'ctrl-f:change-prompt(🔎 )+reload(fd -H -d 2 -t d -E .Trash . ~)' \ - --bind 'ctrl-d:execute(tmux kill-session -t {2..})+change-prompt(⚡ )+reload(sesh list --icons)' \ - --preview-window 'right:55%' \ - --preview 'sesh preview {}' -)\"" - -# --- Toggle shared todo pane in current session --- -# t はデフォルトで時計なので消す -unbind t -# Prefix+t: -# - 現在 window の最左に todo pane をトグル -bind-key t run-shell "todo_file=\$HOME/Documents/Note/Kanban/work.md; wtarget=\$(tmux display-message -p '#{session_name}:#{window_index}'); todo_pane=\$(tmux show-options -w -t \"\$wtarget\" -qv @todo_pane_id || true); if [ -n \"\$todo_pane\" ] && tmux display-message -p -t \"\$todo_pane\" '#{pane_id}' >/dev/null 2>&1; then tmux kill-pane -t \"\$todo_pane\"; prev_layout=\$(tmux show-options -w -t \"\$wtarget\" -qv @todo_prev_layout || true); if [ -n \"\$prev_layout\" ]; then tmux select-layout -t \"\$wtarget\" \"\$prev_layout\" >/dev/null 2>&1 || true; fi; tmux set-option -w -t \"\$wtarget\" -u @todo_prev_layout; tmux set-option -w -t \"\$wtarget\" -u @todo_pane_id; exit 0; fi; prev_layout=\$(tmux display-message -p -t \"\$wtarget\" '#{window_layout}'); tmux set-option -w -t \"\$wtarget\" @todo_prev_layout \"\$prev_layout\"; new_pane=\$(tmux split-window -f -t \"\$wtarget\" -hb -p 25 -P -F '##{pane_id}' \"nvim \\\"\$todo_file\\\"\"); tmux set-option -w -t \"\$wtarget\" @todo_pane_id \"\$new_pane\"" - -##### Work integration ##### -# Assumes you have ~/bin/work in PATH. -# Prefix+w: create/attach a work session using the current pane's directory. -bind-key w run-shell "work '#{pane_current_path}'" - -##### Quality-of-life ##### - -# New windows/panes inherit current path -bind-key c new-window -c "#{pane_current_path}" - -# Copy mode -setw -g mode-keys vi -if-shell -b '[ "$(uname)" = "Darwin" ]' { - set -s copy-command "pbcopy" - display "using pbcopy as copy-command" -} - -# tpm -set -g @plugin 'tmux-plugins/tpm' -set -g @plugin 'tmux-plugins/tmux-sensible' -set -g @plugin 'tmux-plugins/tmux-yank' -set -g @plugin 'alexwforsythe/tmux-which-key' -set -g @plugin 'tmux-plugins/tmux-pain-control' - -# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) -run '~/.tmux/plugins/tpm/tpm' diff --git a/.zshrc b/.zshrc index 51591aa..83cbd02 100644 --- a/.zshrc +++ b/.zshrc @@ -59,16 +59,6 @@ fpath=( ${fpath} ) -tpop() { - local session_name=claude - tmux has-session -t "$session_name" 2>/dev/null - if [ $? -eq 0 ]; then - tmux popup tmux attach -t "$session_name" - else - tmux popup tmux new -s "$session_name" - fi -} - _kubectl_lazy_completion() { unfunction kubectl 2>/dev/null [[ $commands[kubectl] ]] && source <(command kubectl completion zsh) diff --git a/Brewfile b/Brewfile index 5388913..d078f3a 100644 --- a/Brewfile +++ b/Brewfile @@ -5,6 +5,7 @@ brew "fd" brew "fzf" brew "git-delta" brew "htop" +brew "herdr" brew "neovim" brew "plantuml" brew "ripgrep" diff --git a/herdr/config.toml b/herdr/config.toml new file mode 100644 index 0000000..751c27f --- /dev/null +++ b/herdr/config.toml @@ -0,0 +1,43 @@ +onboarding = false + +[theme] +name = "catppuccin" + +[terminal] +shell_mode = "auto" +new_cwd = "follow" + +[keys] +prefix = "ctrl+b" +reload_config = "prefix+shift+r" +workspace_picker = "prefix+w" +goto = "prefix+g" +new_tab = "prefix+c" +previous_tab = "prefix+p" +next_tab = "prefix+n" +switch_tab = "prefix+1..9" +focus_pane_left = "prefix+h" +focus_pane_down = "prefix+j" +focus_pane_up = "prefix+k" +focus_pane_right = "prefix+l" +split_vertical = ["prefix+v", "prefix+|"] +split_horizontal = "prefix+minus" +close_pane = "prefix+x" +zoom = "prefix+z" +resize_mode = "prefix+r" + +[[keys.command]] +key = "ctrl+q" +type = "popup" +command = "exec codex" +description = "open Codex" +width = "80%" +height = "80%" + +[[keys.command]] +key = "prefix+t" +type = "popup" +command = "exec nvim ~/Documents/Note/Kanban/work.md" +description = "open todo list" +width = "90%" +height = "90%" diff --git a/iterm2/com.googlecode.iterm2.plist b/iterm2/com.googlecode.iterm2.plist index 48ab66f..b7dab7a 100644 --- a/iterm2/com.googlecode.iterm2.plist +++ b/iterm2/com.googlecode.iterm2.plist @@ -383,7 +383,7 @@ Idle Code 0 Initial Text - tmux + herdr Jobs to Ignore rlogin @@ -1143,7 +1143,7 @@ Idle Code 0 Initial Text - tmux + herdr Initial Use Transparency Jobs to Ignore @@ -1877,7 +1877,7 @@ Idle Code 0 Initial Text - tmux + herdr Jobs to Ignore rlogin @@ -2918,7 +2918,7 @@ Mouse Reporting Name - tmux + herdr Non Ascii Font Monaco 12 Non-ASCII Anti Aliased @@ -3373,7 +3373,7 @@ Idle Code 0 Initial Text - tmux + herdr Instant Replay Jobs to Ignore diff --git a/script/link.sh b/script/link.sh index 2f492a6..0c28250 100755 --- a/script/link.sh +++ b/script/link.sh @@ -13,30 +13,29 @@ for dotfile in "${DOTFILES_DIR}"/.??*; do ln -fnsv "$dotfile" "$HOME" done -NVIM_CONFIG_DIR="$HOME/.config/nvim" -mkdir -p "$NVIM_CONFIG_DIR" - -legacy_nvim_init="$NVIM_CONFIG_DIR/init.vim" -if [ -L "$legacy_nvim_init" ] && [ "$(readlink "$legacy_nvim_init")" = "$DOTFILES_DIR/nvim/init.vim" ]; then - rm "$legacy_nvim_init" -fi - -link_nvim_path() { +link_config_path() { local source_path=$1 local destination_path=$2 if [ -e "$destination_path" ] && [ ! -L "$destination_path" ]; then - echo "Error: refusing to replace existing Neovim path: $destination_path" >&2 + echo "Error: refusing to replace existing config path: $destination_path" >&2 exit 1 fi ln -fnsv "$source_path" "$destination_path" } -link_nvim_path "$DOTFILES_DIR/nvim/init.lua" "$NVIM_CONFIG_DIR/init.lua" -link_nvim_path "$DOTFILES_DIR/nvim/lua" "$NVIM_CONFIG_DIR/lua" -link_nvim_path "$DOTFILES_DIR/nvim/lazy-lock.json" "$NVIM_CONFIG_DIR/lazy-lock.json" -link_nvim_path "$DOTFILES_DIR/nvim/.stylua.toml" "$NVIM_CONFIG_DIR/.stylua.toml" +NVIM_CONFIG_DIR="$HOME/.config/nvim" +mkdir -p "$NVIM_CONFIG_DIR" + +link_config_path "$DOTFILES_DIR/nvim/init.lua" "$NVIM_CONFIG_DIR/init.lua" +link_config_path "$DOTFILES_DIR/nvim/lua" "$NVIM_CONFIG_DIR/lua" +link_config_path "$DOTFILES_DIR/nvim/lazy-lock.json" "$NVIM_CONFIG_DIR/lazy-lock.json" +link_config_path "$DOTFILES_DIR/nvim/.stylua.toml" "$NVIM_CONFIG_DIR/.stylua.toml" + +HERDR_CONFIG_DIR="$HOME/.config/herdr" +mkdir -p "$HERDR_CONFIG_DIR" +link_config_path "$DOTFILES_DIR/herdr/config.toml" "$HERDR_CONFIG_DIR/config.toml" if [ ! -e "$HOME/.config/karabiner/karabiner.json" ]; then mkdir -p "$HOME/.config/karabiner/" && touch "$HOME/.config/karabiner/karabiner.json"