我个人让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 方案