发现咱们这里没人用tmux

我个人让emacs、readline和tmux的快捷键尽量统一。所以我设置了非常多的快捷键,像C-h这种都改了。桌面的快捷键靠xremap。

我emacs用的是陈斌的配置, 我bspwm和tmux快捷键设置和emacs设置相适应, 但还是感觉太累了, 智力负担很重. 我不愿意用GUI emacs, 直接在terminal里面运行. 不用tmux直接开terminal窗口的话, 在bspwm里面emacs最多只能有0.6的面积, 用着也不太舒服, 拧巴的很 :joy:

我用的是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 个赞

嗯, 看起来不错, 我研究研究, 我想想我这个该怎么改, 谢了哥们

zellij 默认 keybinding 确实对 emacs 用户很不友好,而且对终端用户也极不友好,终端里面最常用的 ctrl+p 默认进 pane mode ,它设计像 emacs 里面搞了一堆 mode,不同 mode 用不同键触发,导致占用了太多键位,为了解这问题又搞了个 lock mode。尝试过几次放弃了,最近又尝试一次解锁了老 tmux 用户正确使用姿势 (dotfiles/dot_config/zellij/config.kdl at main · tennix/dotfiles · GitHub),现在用起来还挺好的。之前用了近两年 kitty 也是配成 tmux 模式 (λ => 函舍空间 / Replace Tmux and Alacritty with Kitty Terminal) 老实说除了远程 session 保持不支持外 kitty 用起来挺爽的,不过 kitty 在 parallels 虚拟机里面颜色显示诡异问题一直找不到解法,所以最近才又考虑 zellij + alacrity 方案

虽然现在不用 Kitty 了,但是我比较同意 Kitty 作者的说法 Frequently Asked Questions - kitty, kitty tmux like daemon · Issue #391 · kovidgoyal/kitty · GitHub

远程持久化时还是要用tmux,本地我都是 ddterm:joy:

:smiling_face_with_tear:我目前也就一个远程持久化的需求要用 tmux,很多行为也是相当古怪。有没有什么替代用品啊

screen?

不知道,我目前没有这个需求⋯⋯一般需要远程运行东西不中断的话我都直接 nohup 了⋯⋯

反馈一下,后来我在 HN 上找到一个比较轻量的替代品 dtach 可以支持 remote persistence,虽然没有 session detach 功能,但我后来想了想其实主动 detach 只是我被 tmux 养成的没什么必要的使用场景。

nohup 是不错的,但是它没法儿挂起一些 shell 之类的任务还把他保持在前端……

1 个赞

公司生产服务器上不让乱装其他软件,只能在自己的开发测试服务器上装,自己用。个人觉得 tmux 还挺爽的

我以前也这样搞过,不过当时没适应,感觉太割裂了。 然后找到了这个配置:GitHub - samoshkin/tmux-config: Tmux configuration, that supercharges your tmux to build cozy and cool terminal environment 里面也有提到local 和 remote tmux 嵌套的问题,还配了一张图说这个事儿,可以点过去看看。 解决方案是 f12 来开启和关闭本地的tmux key绑定。我现在用的就是这个方案,我个人使用场景下,基本上很少本地和远程轮换着切。 我自己配置里面的代码就这些,额外加了点儿配置用来在开启和关闭的keybinding展示不同的颜色:

#### Nesting local and remote sessions

bind -T root F12  \
  set prefix None \;\
  set key-table off \;\
  set window-status-current-format "#[fg=#002b36,bg=#002b36]#[fg=color166,bg=default] #I  #{b:pane_current_path} #[fg=#002b36,bg=#002b36,nobold,nounderscore,noitalics]" \;\
  if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\
  refresh-client -S \;\

bind -T off F12 \
  set -u prefix \;\
  set -u key-table \;\
  set -u window-status-current-format \;\
  refresh-client -S

关闭和开启 keybinding 时颜色: image

1 个赞

发现了一个tmux的替代品zellij

这玩意儿是 vim 绑键,把 C-p 给重映射了,没了 C-p 我根本活不了 :face_holding_back_tears:

这个较早之前说会支持windows,所以当初关注了一段时间,后来听说又不支持了,然后好感就下降不少了(虽说现在我开发工作基本上不再windows上,但也不像拿起来再试了)。另外,如果想把左下角的zellij给去了,得自己改代码编译,好像涉及到宣传问题。

zellij默认键设置与命令行readline冲突太多,真要用起来只能在配置文件中删除默认的键配置(clear-defaults=true),再按个人的习惯添加一些mode和快捷键。其中主要是tmux mode,可以把所有其它mode的操作都映射到tmux mode下的快捷键来触发,来模拟tmux的习惯用法。比如

keybinds {
    normal clear-defaults=true {
        bind "Ctrl b" { SwitchToMode "Tmux"; }
    }
    tmux clear-defaults=true {
        // Tab
        bind "n" { GoToNextTab; }
        bind "c" { NewTab; SwitchToMode "Normal"; }
        // other key bindings
    }
}

这个不好使。内存占用大,完全不像rust的风格;快捷键跟emacs冲突。试用过一段完全没法在工作中正常使用,只能放弃。