Tmux中if-shell结合Vim检测的配置失效问题求助
Tmux if-shell 不生效的原因及解决方法
问题根源
你遇到的核心问题是对Tmux if-shell的执行逻辑理解有误:
- 提前执行的命令替换:你用
$(is_nvim)会在Tmux加载配置时就执行一次is_nvim对应的命令,得到固定的0或1结果,后续不会再重新检测Vim状态,导致if-shell只会执行一次对应的设置,不会动态更新。 - 错误依赖命令输出而非退出码:Tmux if-shell的判断依据是命令的退出状态码(0为真,非0为假),而不是命令的输出内容。你原来的
is_nvim里用echo $?输出状态码完全没必要——直接用检测命令本身的退出码即可。
正确写法
1. 直接在if-shell中使用检测命令
不需要额外定义变量,直接把检测逻辑作为if-shell的第一个参数:
if-shell "ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?|e)(diff)?$'" \ "set -g status-left 'a'" \ "set -g status-left 'b'"
2. 复用检测命令(定义Tmux变量)
如果想复用检测逻辑,可以定义Tmux全局变量,再在if-shell中引用:
# 定义检测命令为Tmux变量 set -g @is_vim_running "ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?|e)(diff)?$'" # 使用if-shell判断 if-shell "$@is_vim_running" "set -g status-left 'a'" "set -g status-left 'b'"
实现动态更新
上面的写法默认只会在Tmux加载配置时执行一次。如果需要每次切换窗格/窗口时自动更新状态栏,需要把if-shell绑定到Tmux的事件钩子:
set -g @is_vim_running "ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?|e)(diff)?$'" # 切换窗格时触发检测 set-hook -g pane-switch "if-shell \"$@is_vim_running\" \"set -g status-left 'a'\" \"set -g status-left 'b'\"" # 切换窗口时触发检测 set-hook -g window-switch "if-shell \"$@is_vim_running\" \"set -g status-left 'a'\" \"set -g status-left 'b'\""
这样每次切换窗格或窗口,Tmux都会重新检测当前窗格是否有Vim运行,并更新status-left的内容。
内容的提问来源于stack exchange,提问作者user14749247
相关产品推荐
相关产品推荐

