发现咱们这里没人用tmux

我用的是hyprland + alacritty(tmux as tab ) +emacs(gui) 我写了个脚本other-window 通过xremap 绑定在 space+o 上 来实现类似于 emacs 的`C-x o’ 的功能 这个脚本里可以判断当前窗口class 与window title 是不是 emacs/tmux 来做特殊的逻辑判断, 可以将emacs 的window 与 tmux 的pane 及 系统级的window 一视同仁 原理是 tmux 可以通过 以下两行代码 获取到当前pane 与最后一个pane的id , 是最后一个pane 则切换到下一个系统级的window,否则就在pane间切换

            last_pane_id=$(tmux list-panes -t $tmux_session -F "#{pane_id}"|tail -n 1)
            cur_pane_id=$(tmux display-message -t $tmux_session -p '#{pane_id}')

emacs 则需要利用 after-focus-change-function 在emacs 刚获得焦点时,记录下当前emacs window 是哪个 当焦点在emacs window 中轮换一圈后 就切换到下一个system window

resize-window 与一样 将emacs 的window 与 tmux 的pane 及 系统级的window 一视同仁 地调整窗口大小

      super-C-l: { launch: ["resize-window" ,"right"]}
      super-C-h: { launch: ["resize-window" ,"left"]}
      super-C-k: { launch: ["resize-window" ,"up"]}
      super-C-j: { launch: ["resize-window" ,"down"]}

toggle-fullscreen 也类似 一视同仁的实现最大化窗口

xremap 可以根据当前window title 是什么 来执行不同的按键绑定 (目前仅支持wlroots/kde clients) 比如我的部分配置如下: 比如同是在终端下

  1. 当终端下打开tmux时 是 按下C-, 实际发送的是`C-cp’ (C-c 是我tmux的prefix)
  2. 当终端下打开emacs时 是 按下C-, 实际发送的是C-,
  - name: terminal tmux
    application:
      only: [dterm,bterm,kitty,/Alacritty.*/,/foot.*/]
    window:
      only: [/TMUX:/ ]
    remap:
      C-comma: [C-c ,p]
      C-dot: [C-c ,n]
      C-C: C-c
  - name: terminal emacs
    application:
      only: [bterm,dterm,kitty,Alacritty,foot,foot-ws,Alacritty-ws]
    window:
      only: [/GNU\/Emacs/ , /History/, /Last command output/, /EDITING SCROLLBACK/ ]
    remap:
      C-comma: C-comma
      C-dot: C-dot

# 更多配置参见 https://github.com/jixiuf/vmacs/blob/master/linux/etc/xremap.yaml#L152

tmux.conf 下配置window title 的格式

set -g set-titles on
set -g set-titles-string 'TMUX:#{session_name}:#{pane_title}'

emacs 里也要配置frame-title-format 以更改window title ,如我的配置如下:

(setq  frame-title-format '("「"mode-line-buffer-identification "」("  (:propertize ("" mode-name) ) ") "   mode-line-misc-info   " GNU/Emacs<" (:eval (expand-file-name default-directory)) ">"))

我用tmux 是因为tmux 提供了很多命令用于控制tmux 的行为,比如 tmux send-keys cd /tmp 配合我的其他几个脚本 authtype.sh hypr-run-or-raise tmux.sh cd.sh open-with cwd term.sh


(defun term-compile ()
  (interactive)
  (if current-prefix-arg
      (call-process "sh" nil nil nil "-c"
                    (format "hypr-run-or-raise  --cd  'dterm' --auto-type '--key ctrl+u --key ctrl+l --type \"%s\" --key enter' -- term.sh  --working-directory=$(cwd||echo $HOME) --class=dterm --tmux-session dterm" compile-command))
    (call-process "sh" nil nil nil "-c"
                  (format "hypr-run-or-raise --workspace current --cd --auto-type '--key ctrl+u --key ctrl+l --type \"%s\" --key enter' 'foot.*|dterm|bterm|Alacritty|kitty' -- term.sh  --working-directory=$(cwd||echo $HOME) --class=bterm --tmux-session bterm" compile-command))
    ))

我可以实现 快速在当前目录打开一个终端,并cd 到当前目录,并执行指定的命令 比如上面r term-compile 在打开终端后 按下ctrl-u 及C-l清屏, 然后输入 compile-command 的命令,并按回车 效果如下面动图: latest hypr-run-or-raise 的–cd 参数 支持从emacs title 中取当前default-directory 然后打开一个终端并cd 到相应目录(支持tramp)

      super-C-t: { launch: ["sh","-c","hypr-run-or-raise --cd --toggle --move-to-current-workspace-if-floating --hide-front-floating-window 'foot|foot-ws|bterm|dterm|Alacritty|kitty|org.wezfurlong.wezterm|Alacritty-ws' -- term.sh  --class=dterm --working-directory=$(cwd||echo $HOME) --tmux-session dterm " ] }

latest 最后附上 other-window 切换window 的动图 latest

2 个赞