我个人让emacs、readline和tmux的快捷键尽量统一。所以我设置了非常多的快捷键,像C-h这种都改了。桌面的快捷键靠xremap。
我emacs用的是陈斌的配置, 我bspwm和tmux快捷键设置和emacs设置相适应, 但还是感觉太累了, 智力负担很重. 我不愿意用GUI emacs, 直接在terminal里面运行. 不用tmux直接开terminal窗口的话, 在bspwm里面emacs最多只能有0.6的面积, 用着也不太舒服, 拧巴的很
我用的是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) 比如我的部分配置如下: 比如同是在终端下
- 当终端下打开tmux时 是 按下C-, 实际发送的是`C-cp’ (C-c 是我tmux的prefix)
- 当终端下打开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
的命令,并按回车
效果如下面动图:
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 " ] }
最后附上 other-window 切换window 的动图
嗯, 看起来不错, 我研究研究, 我想想我这个该怎么改, 谢了哥们
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,很多行为也是相当古怪。有没有什么替代用品啊
screen?
不知道,我目前没有这个需求⋯⋯一般需要远程运行东西不中断的话我都直接 nohup 了⋯⋯
反馈一下,后来我在 HN 上找到一个比较轻量的替代品 dtach 可以支持 remote persistence,虽然没有 session detach 功能,但我后来想了想其实主动 detach 只是我被 tmux 养成的没什么必要的使用场景。
nohup 是不错的,但是它没法儿挂起一些 shell 之类的任务还把他保持在前端……
公司生产服务器上不让乱装其他软件,只能在自己的开发测试服务器上装,自己用。个人觉得 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 时颜色:
发现了一个tmux的替代品zellij
这玩意儿是 vim 绑键,把 C-p 给重映射了,没了 C-p 我根本活不了
这个较早之前说会支持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冲突。试用过一段完全没法在工作中正常使用,只能放弃。