Emacs,切换到上一个窗口。

99
在Emacs中,C-x o将我带到下一个窗口。
那么在Emacs中,哪个键盘宏可以带我到上一个窗口呢?
13个回答

110

您可能还想尝试使用windmove,它可以让您根据窗口的几何形状导航到所选择的窗口。我在我的.emacs文件中添加以下内容,以使用C-x箭头键更改窗口。

(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <right>") 'windmove-right)
(global-set-key (kbd "C-x <left>") 'windmove-left)

15
注意,调用(windmove-default-keybindings)将这些函数绑定到SHIFT +上/下/左/右键,我认为这比您的C-x绑定更方便(它会与previous-buffernext-buffer的默认绑定发生冲突)。lkahtz:(kbd)函数可以让你使用字符串表示法指定按键,这种更可读的语法在Emacs中使用C-h kC-h c来描述绑定时也被使用。 - phils
4
我不赞成使用箭头键。但是我还是点了赞,因为这很有帮助。 :smug: - Bjorn
2
@phils SHIFT + <keys> 干扰了 Emacs 23 中默认启用的 shift-selection-mode。 - legends2k
2
legends2k: True;虽然你也可以传递一个参数给windmove-default-keybindings,以指定与箭头键一起使用的不同修饰符,因此该函数仍然对使用shift-selection-mode的人很有用。 - phils
1
@phils同意,_meta_似乎是一个不错的替代方案;如Emacs Wiki所示 - legends2k
显示剩余4条评论

94
那就是 C-- C-x o。 换句话说,用参数-1来执行C-x o。你可以通过在C-u和命令之间插入数字参数来指定要移动的窗口数量,例如C-u 2 C-x o。(其中C--C-u - 1的快捷方式)

你可以使用 C-x z 来重复上一个命令,快速切换窗口。 - Joseph Tesfaye

32

个人而言,我更喜欢使用 window-number.el

要选择不同的窗口,请使用 Ctrl-x, Ctrl-j n

其中,n 是窗口的编号,每个窗口的模型行都会显示它的编号,如截图所示。

只需下载window-number.el,将其放置在emacs的加载路径中,并在您的.emacs中使用以下内容:

 (autoload 'window-number-mode "window-number"
   "A global minor mode that enables selection of windows according to
 numbers with the C-x C-j prefix.  Another mode,
 `window-number-meta-mode' enables the use of the M- prefix."
   t)

还有一个类似的模式叫做switch-window.el,它在窗口中显示大号数字...(按下数字可以切换窗口并恢复显示。)


(来源:tapoueh.org)


2
不错,但我建议不要将某个东西绑定到C-x C-j,因为如果你(require 'dired-x),那就是dired-jump的默认绑定。(如果你想覆盖它,请参阅M-x customize-group RET dired-keys RET。) - phils
1
发布这篇文章后,我决定尝试一下 switch-window.el,它使用 C-x o,当只有两个窗口处于活动状态时,它会选择另一个窗口。我认为最明智的做法是将 C-x o 重新绑定到执行 window-number 技巧上,你对 dired-jump 的看法是正确的。个人而言,我不太喜欢频繁切换窗口,更喜欢使用 C-x b,但增强版的 C-x o 也很令人愉悦。 - ocodo
在我的Emacs相关页面上,@semente发布了两个新的Emacs24主题。http://jasonm23.github.com/EmacsFodder/Emacs/2012/06/29/two-new-emacs24-themes/ - ocodo
http://jasonm23.github.io 或 http://emacsfodder.github.io 可能有你需要的内容。请注意,所示的模式行格式化程序(main-line)未得到维护,(据我所知,没有power-line版本)。 - ocodo
1
@petrux 我认为这可能是两个主题中的一个。另外,如果想要一个酷炫的模式行,请尝试 https://gist.github.com/jasonm23/8554119 - ocodo
显示剩余2条评论

14
如果你经常使用多个emacs窗口(>3),并且想要节省一些按键操作,可以将以下内容添加到你的初始化文件中,这样会更加方便:
(defun frame-bck()
  (interactive)
  (other-window-or-frame -1)
)
(define-key (current-global-map) (kbd "M-o") 'other-window-or-frame)
(define-key (current-global-map) (kbd "M-O") 'frame-bck)

现在只需使用M-o快速循环浏览窗口。


1
这正是我需要的解决方案。我想要的只是将窗口切换命令设置为单个重复按键。谢谢!顺便说一下,我确实不得不将other-window-or-frame更改为other-window才能使其正常工作。我使用的是Emacs 24.2.1版本。 - Geoff
我认为这些绑定非常好(特别是当你有2个或更多窗口时),谢谢。正如所说,需要改为“other-window”才能使其正常工作。 - Ev Dolzhenko

13

这里有些非常好且全面的回答,但为了以最简单的方式回答问题:

 (defun prev-window ()
   (interactive)
   (other-window -1))

 (define-key global-map (kbd "C-x p") 'prev-window)

2
我不知道从什么时候开始,但是emacs现在内置了“previous-window”。 - Arne
1
@Arne 这不是一个可调用的函数,因此应该有不同的用途。 - Joseph Tesfaye
(global-set-key (kbd "C-x p") 'previous-window-any-frame) 可以正常工作。 - David C. Norris

4
基于@Nate的想法,稍作修改以支持在窗口之间反向循环。
;; Windows Cycling
(defun windmove-up-cycle()
  (interactive)
  (condition-case nil (windmove-up)
    (error (condition-case nil (windmove-down)
         (error (condition-case nil (windmove-right) (error (condition-case nil (windmove-left) (error (windmove-up))))))))))

(defun windmove-down-cycle()
  (interactive)
  (condition-case nil (windmove-down)
    (error (condition-case nil (windmove-up)
         (error (condition-case nil (windmove-left) (error (condition-case nil (windmove-right) (error (windmove-down))))))))))

(defun windmove-right-cycle()
  (interactive)
  (condition-case nil (windmove-right)
    (error (condition-case nil (windmove-left)
         (error (condition-case nil (windmove-up) (error (condition-case nil (windmove-down) (error (windmove-right))))))))))

(defun windmove-left-cycle()
  (interactive)
  (condition-case nil (windmove-left)
    (error (condition-case nil (windmove-right)
         (error (condition-case nil (windmove-down) (error (condition-case nil (windmove-up) (error (windmove-left))))))))))

(global-set-key (kbd "C-x <up>") 'windmove-up-cycle)
(global-set-key (kbd "C-x <down>") 'windmove-down-cycle)
(global-set-key (kbd "C-x <right>") 'windmove-right-cycle)
(global-set-key (kbd "C-x <left>") 'windmove-left-cycle)

4

补充@Nate、@aspirin和@Troydm的答案,如果你决定将windmove命令绑定到任何你选择的键组合中,我认为以下内容会是非常有帮助的:

(setq windmove-wrap-around t)

默认情况下,当你试图移动到一个不存在的窗口时,会出现错误,这在一段时间后会变得很烦人。然而,当设置windmove-wrap-around时,例如尝试从底部框架移动时,会选择框架中最顶部的窗口,这可能更符合你的直觉行为。


4

M-nM-p 对我来说是最有意义的,因为它们类似于C-n(下一行)和C-p(上一行):

(define-key global-map (kbd "M-p") 'previous-multiframe-window)
(define-key global-map (kbd "M-n") 'other-window)

(受以下两个答案的启发:这个那个

我已经点赞并使用了这个配置。问题在于 M-nM-p 在终端(gdb、python、ielm 等)中已经被占用,因此您将不得不切换回另一种方法来跳出终端缓冲区。 - mihai
在那些环境中,它们被用于什么? - tshepang
这是我目前见过的最好的,它不会与其他东西相冲突,并且运行得非常好!谢谢! - aurelien

3

参考Nate的答案,我将使用传统的p键代替箭头键移动,使用n键向移动,使用f键向移动,使用b键向移动。 我还将使用Super键代替Ctrl键,因为C-p,C-n,C-f和C-b是默认移动键。 结合使用M键,这些键可以让您跳过字符和行,而不是在每次按键后逐个进行。 因此,Super键是最好的选择,可以使其成为易于绑定的键。 现在,您无需再将手从Home Row上拿开了!

(global-set-key (kbd "s-p") `windmove-up)
(global-set-key (kbd "s-n") `windmove-down)
(global-set-key (kbd "s-f") `windmove-right)
(global-set-key (kbd "s-b") `windmove-left)

希望这能帮到你!

2
(global-unset-key (kbd "M-j"))
(global-unset-key (kbd "M-k"))
(global-set-key (kbd "M-j") (lambda () (interactive) (other-window 1)))
(global-set-key (kbd "M-k") (lambda () (interactive) (other-window -1)))

altjaltk可以循环浏览您可见的缓冲区,确切地说是向前和向后。


M-k是一个相当有用的快捷键。还有其他替代方案吗? - A_P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接