类似问题论坛应该很多,讲如何高效切窗口的
楼上的人也说了,和楼主说的最接近的可能是 windmove, 允许像 vim 的 c-w hjkl 一样去上下左右移动 focus。不要纠结于光标键(我猜测是箭头键),直接自己绑定相关的函数就行,我自己并不启用 windmove-mode
C-x o 切多个窗口是噩梦,楼上说的 repeat-mode 可以解决。不过我个人是用 ace-window, 当然看得出来楼主懒得每次看窗口 id
另外推荐 winum, 直接给各个窗口加数字 id, 然后自己绑定按键,按数字切换,不用事先看 id, 我绑定到 M-[num]
题外话:目前我正在用 transient 将窗口相关功能的命令都集合起来,作为统一入口触发,顺带支持反复键入,推荐楼主尝试
回到最开始的问题:
- grep 模式,
我印象中的行为是:最开始会尝试分割 window 以创建新窗口,但是它并不是无限分割新建,到一定的程度就不会继续分割了,转而复用已有的窗口。这个肯定可以调,但是我没有研究过 看起来楼主已经发现问题所在了
- compile, 没用过
推荐阅读 The Emacs Window Management Almanac, 我就是从这里看到了 winum, 有空我应该再读一遍这篇
题外话,i3 很好,但没有用过。但我能从 sway, i3 的克隆中看到 i3 的设计还是很到位的
2 个赞
如果觉得用 C-x o 切换窗口不够效率,又不想像用 ace-window 那样盯屏,可以试试坛友开发的 spatial-window (GitHub - lewang/spatial-window: Jump to Emacs windows using keyboard spatial mapping · GitHub)。其核心思想是直接将你键盘上的每个按键,按照其空间位置,映射在屏幕上对应位置的窗口,例如:q 代表左上角,p 代表右上角等等。
另外,开启 repeat-mode 后,可以用 C-x o o o 连续在窗口间跳转,并且小写 o 和大写 O 方向相反。不过,这个功能有时候会有负面效果。比如,你 C-x o 之后想写 ok,但字母 o 会被认为是连续切换窗口,结果就是在另一个你想不到的窗口里写了 k。
回头再说说题主的问题 1。总体上,我也觉得 Emacs 默认提供的窗口管理不如 Vim 的直观和便捷。比如,我想做如下图所示的窗口结构变化:
+---+---+ +---+---+
| | B | | A | B |
| A +---+ => +---+---+
| | C | | C |
+---+---+ +---+---+
在 Vim 里,只需要光标在 C 窗口,然后按 ctrl-w J,搞定!在 Emacs 里,hmm……我不知道最优路径是什么,我会 C-x 1 关掉其他窗口,然后手动 C-x 2 或 C-x 3 分割,然后在每个窗口 C-x b 切换到我要的 buffer。我相信坛友们能提供很多巧妙的脚本或包来解决此问题,只是这些还没有形成我的肌肉记忆。
不过,Emacs 的窗口管理也并非处处不如 Vim。我发现 Emacs 的窗口叠放,有些像真实的文件在桌面上叠放的方式。我不知道术语怎么表达,举例说明吧。比如,我正在唯一的窗口里写代码,这时我运行 M-x compile,输入编译命令并回车后,compile 默认会在右侧打开新的窗口,显示编译结果。如果你此时 C-x o 切换到右边窗口,然后按 q,右侧窗口会被关闭,回到单个窗口的状态。这好像没什么稀奇。但如果你在右边窗口中按 C-x b 切换到其他 buffer,此时,表面上左右两个窗口没有什么本质不同,但实际上,如果你先关闭右侧新切换到的 buffer(按 C-x k RET 或 C-x w q),再按 q 关闭 *compilation* buffer,右侧窗口就会被关闭,回到单个窗口状态。也就是说,刚才右侧窗口里其实只有两个 buffer,全部关闭后,窗口会随之关闭。这很像你在桌面的右侧临时放了一个、又一个文件,然后又把文件全部收走,右侧自然变空,桌面回到单窗口状态。
文字叙述显得琐碎,其实体验起来很符合直觉。我真正想说的是,Emacs 的窗口设计也不乏巧思,只是我自己还并没有完全领悟。
1 个赞
感谢分享!
我试了这个,会提示:
split-window: Window #<B> too small for splitting
切换窗口比较频繁,ace-window 开启了 (ace-window-display-mode 1) 用了段时间,经常要去看窗口编号,增加心智负担。后来绑定到一个按键,无脑往下个窗口移动,好用多了:
(require 'ace-window)
(defun lld/next-window()
"根据当前窗口编号,移动到下一个编号的窗口。"
(interactive)
(let* ((number (string-to-number
(window-parameter
(selected-window) 'ace-window-path)))
(len (length (aw-window-list)))
(number (+ number 1)))
(when (> number len)
(setq number 1))
(dolist (win (aw-window-list))
(when (eq number
(string-to-number
(window-parameter win 'ace-window-path)))
(aw-switch-to-window win)))))
(bind-keys ("C-`" . lld/next-window))
可以用workgroups2(我在维护,是个比较老的软件了,同类软件很多), 特定布局你就以名字如"w1", "w2"什么的保存.然后再载入w1或w2
我目前用的就是 C-x o 然后 repeat,挺好用的。
spacemacs里有一个函数是spacemacs/winum-select-window-[x],绑定了command+x(窗口对应的数字)。
vim管理窗口怎么可能更方便?Emacs有很多种方法,手搓一个hydra,想怎么移动就怎么移动。另外,ace-window那么大的leading char很醒目啊,还可以改成字母 asdfgh……
参考代码:
3 个赞
这个问题我是用 rotate 包解决的(装上了,但是可能一个月都用不到一次……)。emacs 确实没有自带很多功能,需要用包或者自己的小东西填补
但是在其他的垃圾工具面前,vim 和 emacs 其实是一个阵营的,应当团结起来。emacs 很好,vim 也很好
感谢大家。很认同这句话,我下面去研究研究大家的解决方案。
感觉 Emacs 和 Vim 的很多地方是可能是设计哲学不同导致的差异,可能只是我目前没有意识到所以感觉窗口管理 Vim 比 Emacs 的方便,所以想找一个“更方便的” Emacs 窗口操作。比如:对于长 Tab Emacs 是把光标放在第一个位置,而 Vim 是放在最后的位置,我猜测就是因为 Emacs 的复制粘贴或者 C-k 之类的操作都是光标在最前面操作的,Vim 有行模式所以很少需要光标在第一个位置。Vim 的行连接是从上到下进行的,Emacs 的行连接是从下往上进行的,我猜测是因为 Emacs 常常在屏幕下半部分操作的?因为一般是通过 C-L 定位到中间然后向下操作,但是 M-h 又是从上到下进行的..
1 个赞
我发现问题了,如果我把这个取消,当多窗口的时候会自动替换另一个窗口的内容。
比如,当我有两个窗口,在第一个窗口按 M-. 第二个窗口的内容会替换为 xref 了。
1 个赞
这个在 emacs 31 里有一大堆命令可以实现:
window-layout-transpose
Command: Transpose windows under WINDOW.
Properties: event-symbol-element-mask event-symbol-elements modifier-cache
function-history
window-layout-flip-leftright
Command: Horizontally flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-flip-topdown
Command: Vertically flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-flip-topdown
Command: Vertically flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-flip-topdown
Command: Vertically flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-flip-leftright
Command: Horizontally flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-flip-leftright
Command: Horizontally flip windows under WINDOW.
Properties: repeat-map function-history
window-layout-rotate-anticlockwise
Command: Rotate window layout of WINDOW counterclockwise by 90 degrees.
Properties: repeat-map function-history
window-layout-rotate-clockwise
Command: Rotate window layout under WINDOW clockwise by 90 degrees.
Properties: repeat-map function-history
window-layout-rotate-clockwise
Command: Rotate window layout under WINDOW clockwise by 90 degrees.
Properties: repeat-map function-history
window-layout-rotate-anticlockwise
Command: Rotate window layout of WINDOW counterclockwise by 90 degrees.
Properties: repeat-map function-history
rotate-windows
Command: Rotate windows under WINDOW in cyclic ordering.
Properties: repeat-map function-history
rotate-windows-back
Command: Rotate windows under WINDOW backward in cyclic ordering.
Properties: repeat-map function-history
这些命令默认都绑定在 C-x w 下面。
1 个赞
强烈推荐我这个魔改的shackle 和 winnie-mode
github.com:QiangF/emacs-winnie.git