feat: udpate fish

This commit is contained in:
2026-09-16 21:44:25 +08:00
parent 0b2d2b6c6d
commit 2060bbd23a
5 changed files with 240 additions and 1 deletions
+6 -1
View File
@@ -32,8 +32,13 @@ function ff
for __f in ~/.dotfile/fish/functions/*.fish
functions -e (basename $__f .fish) 2>/dev/null
end
set -e __f
source ~/.config/fish/config.fish
# fish 对已加载过的 autoload 函数不会在 functions -e 后重新加载,
# 必须显式 source 一遍,否则函数(含 ff 自身)会丢失
for __f in ~/.dotfile/fish/functions/*.fish
source $__f
end
set -e __f
echo "Fish configuration reloaded!"
case edit
vim ~/.config/fish/custom.fish
+2
View File
@@ -53,6 +53,8 @@
path = ~/.dotfile/git/.gitconfig.personal
[includeIf "gitdir:~/workrepo/"]
path = ~/.gitconfig.work
[includeIf "gitdir:~/repo/"]
path = ~/.gitconfig.work
[rebase]
autoSquash = true
autoStash = true
+57
View File
@@ -0,0 +1,57 @@
# herdr
个人 herdr 配置与迁移笔记。配置由 `tmux/.tmux.conf` 映射而来。
- `config.toml` — 真实配置,经 `script/herdr-init.sh` 软链到 `~/.config/herdr/config.toml`
- 校验:`herdr config check`
- 热重载:`prefix+shift+r`(本配置改为 `prefix+r`)或 `herdr server reload-config`
- 默认值参考:`herdr --default-config`
- 官方速查:https://herdr.dev/docs/concepts/ ,给 agent 看的:`herdr --skill`
## 概念对照
| tmux | herdr | 说明 |
|---|---|---|
| session | workspace | herdr 的 workspace 对应“一个项目/任务”,侧栏按 workspace 汇总 agent 状态 |
| (无对应) | session | herdr 的 named session 是**独立的 server 命名空间**(`herdr session attach work`),跟 tmux 的 session 不是一回事 |
| window | tab | |
| pane | pane | 只能向右(right)或向下(down)切 |
| prefix mode | prefix mode (`ctrl+b`) | 相同;另有 terminal mode / navigate mode |
| status bar + 脚本 | sidebar | 鼠标可点、可拖分隔条、右键菜单 |
| (无对应) | agent | herdr 识别 pane 里的 coding agent,状态 `working`/`blocked`/`done`/`idle`/`unknown` |
| tmux-resurrect | session.json + `[experimental] pane_history` | 布局自动持久化,agent 原生会话恢复需要装 integration |
| tpm 插件 | 无插件系统 | fzf 类能力内建(`prefix+w` workspace picker、`prefix+g` goto);自定义动作用 `[[keys.command]]` |
| tmux over ssh | `herdr --remote <ssh-target>` | 远端跑 server,本地 attach |
## 和 tmux 的主要差异
1. **鼠标优先**。所有交互都能用鼠标完成;键位是可选层。`prefix+?` 可实时列出当前所有有效绑定。
2. **agent 感知**。侧栏能看到每个 pane 里的 agent 状态,`blocked`(等你审批/回答)会被顶到前面。tmux 只能靠 pane 标题自己写。
3. **CLI + 本地 socket API**。`herdr pane split/run/read/wait-output`、`herdr agent prompt/wait` 这类命令可以从脚本或 agent 内部驱动布局和读输出,tmux 的 `send-keys` 做不到等待与状态判定。
4. **配置是单个 TOML**,没有插件系统,也没有 `run-shell` 状态栏脚本;但支持
`[[keys.command]]` 自定义命令(`type = "shell"` / `"pane"` / `"popup"`,可指定宽高百分比),基本能覆盖原来用插件/脚本做的事。
5. **直接快捷键**。除 `prefix+...` 外还支持 `ctrl+alt+...` 这类直通键位(适合想摆脱 prefix 的用法)。反过来,被 OS 或外层终端占用的组合 herdr 收不到,表现为“绑了没反应”。
6. **没有 `escape-time` / `terminal-overrides` / 真彩色开关**。那些是 tmux 作为终端适配层才需要的,herdr 自己处理能力协商。通知走 `[ui.toast] delivery`,剪贴板走 `[ui] copy_on_select`。
7. **不支持嵌套启动**(`experimental.allow_nested = false`):herdr pane 里再跑 `herdr` 会被拒绝。tmux 里 `tmux` 是能套的。
8. `[remote] manage_ssh_config` 默认开启:`herdr --remote` 会生成一份私有 ssh config,**先 include 你的 `~/.ssh/config`**,再补 `ServerAliveInterval`/`ServerAliveCountMax` 兜底,并用私有 control socket 复用连接。所以 `~/.ssh/config` 里已有的 keepalive 仍然优先,我们的 `Include ~/.ssh/config.d/*` 也照常生效。
## 切换时的注意事项
- **分屏按分隔线的形状记**:`|` 是竖线 → 切成左右;`-` 是横线 → 切成上下。herdr 就是按形状命名的(`split_vertical` = 竖线 = 向右切,`split_horizontal` = 横线 = 向下切),而 tmux 的 `splitw -v/-h` 按“排列方向”命名,两者相反:tmux `splitw -v`(上下堆叠)对应 herdr `split_horizontal`,tmux `splitw -h`(左右并排)对应 `split_vertical`。本配置按形状对齐(`-` 上下、`|` 左右)。
- **`herdr` 裸跑会 attach;`herdr server` 是前台 headless server**。别为了“看看帮助”敲 `herdr server`——它不返回,会把调用它的地方永久挂住(踩过一次:pi 的 bash 工具卡了 46 分钟)。要看帮助用 `herdr --help`、`herdr <group>`(如 `herdr pane`);停 server 用 `herdr server stop`。
- **prefix 都是 `ctrl+b`**,两套配置不冲突,但同时开难免按错。切过去之前建议先退掉 tmux,避免双层状态栏/双层 prefix。
- **没有 `-c '#{pane_current_path}'` 这个开关**:新建 pane/tab 的目录策略在 `[terminal] new_cwd`(`follow` / `home` / `current` / 固定路径),本配置是 `follow`。
- **resize 步长不可配**。tmux 那边是固定 10 格;herdr 直接绑定(本配置 `prefix+shift+hjkl`)用默认步长,或 `prefix+r` 进 resize mode 再动。
- **`mouse on/off` 没有运行时快捷键**:由 `[ui] mouse_capture` 决定,运行时去 `prefix+s` 设置面板改。用 `copy_on_select = false` 可以在拖选后保留选区,等 `Ctrl+C` 再复制。
- **复制模式**:`mode-keys vi` 在 herdr 没有等价配置。本配置给 `copy_mode` 绑了 `prefix+[`(herdr 0.8.2 支持该校验通过,但未写进 `--default-config`),复制模式的内部键位不可配;平时直接鼠标拖选即可。想把 scrollback 丢进 `$EDITOR` 用 `prefix+e`。
- **中文/IME**:如果你在 pane 里用 pi/claude/codex 这类自绘光标的 TUI 遇到输入法候选框错位,可试开
`[experimental] reveal_hidden_cursor_for_cjk_ime = true`(可用 `cjk_ime_agents` 限定只对某些 agent 生效)。默认关闭。
- **别再跑 tpm**:`script/tmux-init.sh` 会克隆 tpm 并装插件,那是 tmux 的;herdr 不需要。两套可以并存,但别指望插件搬到 herdr。
- **升级**:`herdr update`(stable 通道);0.8.2 → 0.9.0 已经可用。用包管理器装的则走包管理器。
## 迁移状态
- [x] `herdr/config.toml`(tmux 键位/UI 行为映射,`herdr config check` 通过)
- [x] `script/herdr-init.sh`(软链 + 备份 + 幂等 + 校验)
- [ ] 装 agent integration(`herdr integration install claude` 等),才有原生会话恢复与状态上报
- [ ] 需要时启用 `reveal_hidden_cursor_for_cjk_ime`
+106
View File
@@ -0,0 +1,106 @@
# herdr 配置 —— 由 ~/.dotfile/tmux/.tmux.conf 映射而来
#
# 仓库内真实文件: ~/.dotfile/herdr/config.toml
# 由 script/herdr-init.sh 软链到: ~/.config/herdr/config.toml
#
# 校验: herdr config check
# 热重载: prefix+shift+r,或 herdr server reload-config
# 默认值: herdr --default-config
#
# 这里只写与 herdr 默认值不同(或需要显式强调)的键,未写到的沿用默认。
# 概念对照: tmux session → herdr workspace,tmux window → herdr tab,tmux pane → herdr pane
[keys]
# ---------------------------------------------------------------- 前缀
# tmux 里的 prefix 相关行都被注释掉了,所以沿用 ctrl+b(herdr 默认值,无需显式设置)
# prefix = "ctrl+b"
# tmux: bind r source-file ~/.tmux.conf \; display-message "Config reloaded"
reload_config = "prefix+r" # herdr 默认是 prefix+shift+r
# ---------------------------------------------------------------- 分屏
# 按“分隔线的形状”对齐:
# | 是竖线 → 把 pane 切成左右
# - 是横线 → 把 pane 切成上下
# herdr 就是按分隔线形状命名的,而 tmux 的 -v/-h 按“排列方向”命名,所以二者相反:
# tmux splitw -v(上下堆叠)= 横线 = herdr split_horizontal(向下切)
# tmux splitw -h(左右并排)= 竖线 = herdr split_vertical (向右切)
# tmux: bind - splitw -v -c '#{pane_current_path}' → 切成上下
split_horizontal = "prefix+minus"
# tmux: bind | splitw -h -c '#{pane_current_path}' → 切成左右
split_vertical = "prefix+|"
# tmux 的 -c '#{pane_current_path}' 对应 [terminal] new_cwd = "follow"(默认值)
# ---------------------------------------------------------------- pane 切换
# 注释写的是“绑定 hjkl 键为面板切换”,其中 h/l 两行被注释掉了,这里按原意启用
focus_pane_left = "prefix+h"
focus_pane_down = "prefix+j"
focus_pane_up = "prefix+k"
focus_pane_right = "prefix+l"
# tmux: bind -r K/J/H/L resizep -U/-D/-L/-R 10
# herdr 可直接绑定 resize,不必先进入 resize mode;步长不可配(tmux 那边是 10 格)
resize_pane_up = "prefix+shift+k"
resize_pane_down = "prefix+shift+j"
resize_pane_left = "prefix+shift+h"
# 注: tmux 里 prefix+shift+l 被后面的 `bind L switch-client -l` 覆盖,此处留给“回上一个”
# 向右 resize 用 prefix+r 进 resize mode,或在此写回 "prefix+shift+l"
# tmux: bind L switch-client -l (注释写“返回上一个窗口”)
previous_tab = "prefix+shift+l"
# 想要真正的“来回切换”(不按顺序),可改为 last_pane = "prefix+shift+l"
# tmux: bind M command-prompt -p "插入窗口到位置:" "move-window -b -t ':%%'"
# herdr 没有“输入索引插入”这种交互,改成相邻平移
move_tab_previous = "alt+shift+left"
move_tab_next = "alt+shift+right"
# ---------------------------------------------------------------- 复制模式
# tmux: setw -g mode-keys vi(tmux 默认用 prefix+[ 进入 copy mode)
# herdr 0.8.2 支持 copy_mode 键(未写进 --default-config,但 herdr config check 认可)
copy_mode = "prefix+["
# tmux 里没有的: 把 scrollback 丢给 $EDITOR(herdr 默认 prefix+e)
# edit_scrollback = "prefix+e"
# ---------------------------------------------------------------- 故意不复刻的 tmux 绑定
# tmux: bind -r j select-pane -t .+1 \; resize-pane -Z
# 它覆盖了上面的 `bind j select-pane -D`,含义是“切到下一个 pane 且每次都 toggle zoom”,
# 语义含糊,不复刻。循环切换用 herdr 默认的 prefix+tab / prefix+shift+tab,
# zoom 用 prefix+z。
# tmux: bind m (切换鼠标模式)
# herdr 没有鼠标开关的运行时按键: 行为由 [ui] mouse_capture 决定,
# 运行时可开 prefix+s(设置)面板调整。
# herdr 自带、tmux 那边靠插件实现的能力(均为默认键):
# prefix+w workspace picker(≈ tmux-fzf)
# prefix+g goto
# prefix+? 列出所有有效绑定
[terminal]
# tmux 新建 pane/window 都带 -c '#{pane_current_path}'
new_cwd = "follow"
[ui]
# tmux: set -g mouse on
mouse_capture = true
# tmux: set -s set-clipboard on
copy_on_select = true
# tmux: set-titles on / set-titles-string "#{session_name}"
window_title = "{workspace}"
# tmux: automatic-rename on(窗口名跟随当前目录)→ 关掉 herdr 的新 tab 命名询问
prompt_new_tab_name = false
# tmux 风格: 只要内部分隔线,不要外面那圈边框
pane_outer_borders = false
# tmux: set -as terminal-features ",*:osc9" + allow-passthrough,让外层终端弹通知
# herdr 直接把 pane 里的通知转发给外层终端(Ghostty)
[ui.toast]
delivery = "terminal"
[session]
# 近似替代 tmux-resurrect 的会话恢复
# (原生会话恢复需要对应 agent 装了 herdr integration,如 herdr integration install claude)
resume_agents_on_restore = true
[experimental]
# 近似替代 tmux-resurrect 的 scrollback 恢复: 重启 server 后保留 pane 屏幕历史
pane_history = true
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
# 将 herdr 配置链接到 dotfile
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck disable=SC1091
source "$SCRIPT_DIR/common/help.sh"
usage() {
cat <<'EOF'
用法: herdr-init
将 ~/.dotfile/herdr/config.toml 软链接到 herdr 配置路径:
$XDG_CONFIG_HOME/herdr/config.toml(默认 ~/.config/herdr/config.toml)
已有配置会备份为 *.backup.<时间戳>。
选项:
-h, --help 显示此帮助
EOF
}
dotfile_help_requested "${1:-}" && dotfile_show_help
set -e
SRC="$HOME/.dotfile/herdr/config.toml"
CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
DEST_DIR="$CONFIG_HOME/herdr"
DEST="$DEST_DIR/config.toml"
if [ ! -f "$SRC" ]; then
echo "错误: 未找到 $SRC" >&2
exit 1
fi
echo "初始化 herdr 配置..."
echo "目标路径: $DEST"
mkdir -p "$DEST_DIR"
if [ -L "$DEST" ] && [ "$(readlink -f "$DEST")" = "$(readlink -f "$SRC")" ]; then
echo "软链接已存在且指向正确位置,无需操作。"
exit 0
fi
if [ -e "$DEST" ] || [ -L "$DEST" ]; then
BACKUP="$DEST.backup.$(date +%Y%m%d%H%M%S)"
mv "$DEST" "$BACKUP"
echo "已将现有配置备份到 $BACKUP"
fi
ln -s "$SRC" "$DEST"
if [ -L "$DEST" ] && [ "$(readlink -f "$DEST")" = "$(readlink -f "$SRC")" ]; then
echo "软链接创建成功: $DEST -> $SRC"
else
echo "软链接创建失败,请检查路径和权限。" >&2
exit 1
fi
if command -v herdr >/dev/null 2>&1; then
echo "校验配置:"
herdr config check || true
if pgrep -x herdr >/dev/null 2>&1; then
echo "herdr 正在运行,可在 herdr 内用 prefix+shift+r 热重载"
fi
else
echo "未找到 herdr,跳过配置校验"
fi