如何快速把左右两屏调整为上下两屏呢?

有时候打开左右两个 window 进行操作, 然后由于某些原因又想把这两个按上下分屏, 有没有什么办法呢? 求教.

法一、直接写个命令,把这个需求手动模拟,一步一步实现:

(defun split-window-left/right->up/down ()
  "把左右两屏调整为上下两屏.
       A
A|B => -
       B"
  (interactive)
  (let ((buf (current-buffer)))
    ;; 选中左侧 window
    (select-window (frame-first-window))
    ;; 删掉右侧 window
    (delete-other-windows)
    ;; 分屏、选中下边 window
    (select-window (split-window-below))
    ;; 切换至最近 buffer
    (switch-to-buffer (other-buffer))
    ;; 选中原来 buffer 所在的 window
    (select-window (get-buffer-window buf))))

法二、我不习惯 Emacs 默认的分屏命令,因为我觉得同一个 Buffer 分成两个 Window 没什么用。所以我有:

(defun chunyang-split-window-right ()
  "Split window with another buffer."
  (interactive)
  (select-window (split-window-right))
  (switch-to-buffer (other-buffer)))

(defun chunyang-split-window-below ()
  "Split window with another buffer."
  (interactive)
  (select-window (split-window-below))
  (switch-to-buffer (other-buffer)))

分别绑定到 C-x 3C-x 2。之后

  • 把左右两屏调整为上下两屏:C-x 1 C-x 2
  • 把上下两屏调整为左右两屏:C-x 1 C-x 3
3 个赞

两种方法都很赞, 看来要多多学习 elisp 啊. 多谢大神.

另: 把名字写在方法名里真是太棒了:grinning:

如果你用的是spacemacs的话是有快捷键的。

SPC w S-<方向键> 可以移动当前的frame,比如这种情况:

       A
A|B => -
       B

可以把光标定位到A上然后按SPC w S-<up>

3 个赞

赞, spacemacs 用过就是感觉有点不习惯vim按键, 没有很好地迁移过去😂

我用的是这个:

(defun toggle-window-split ()
  (interactive)
  (if (= (count-windows) 2)
      (let* ((this-win-buffer (window-buffer))
             (next-win-buffer (window-buffer (next-window)))
             (this-win-edges (window-edges (selected-window)))
             (next-win-edges (window-edges (next-window)))
             (this-win-2nd (not (and (<= (car this-win-edges)
                                         (car next-win-edges))
                                     (<= (cadr this-win-edges)
                                         (cadr next-win-edges)))))
             (splitter
              (if (= (car this-win-edges)
                     (car (window-edges (next-window))))
                  'split-window-horizontally
                'split-window-vertically)))
        (delete-other-windows)
        (let ((first-win (selected-window)))
          (funcall splitter)
          (if this-win-2nd (other-window 1))
          (set-window-buffer (selected-window) this-win-buffer)
          (set-window-buffer (next-window) next-win-buffer)
          (select-window first-win)
          (if this-win-2nd (other-window 1))))))

http://www.emacswiki.org/emacs/ToggleWindowSplit

2 个赞

wiki 真是内容丰富, 不过不知道怎么搜索:joy:

spacemacs可以不用vim的按键的,配置文件里面可以默认使用emacs模式。然后用M-m代替SPC就可以了。

M-m / SPC 两个 leader key 不会按错吗?我设了同一个,任何时候只管按就是了,不用区分 evil 到底处于什么模式。

不用evil,space就是普通空格,只能用M-m

我用的是 mac,于是我把 leader key 换成了 s-. 也就是 command + ‘.’ ,能很方便的按到。

这是为了避免不同的人定义相同名字的函数,elisp没有名字空间的概念.

想请教一下这个问题:能不能在我打开agenda view的时候固定为左右分屏,agenda view在右边?

emacs默认的方法好像会检测显示器的比例,我更换显示器的时候发现在一个显示器里是左右分屏,另一个却是上下分。

差不多是的。实际检测的是 Emacs 的宽度(即水平方向能显示的英文字符的数量)和高度(即垂直方向……),究竟是左右还是上下分屏取决于它们与 split-height-thresholddsplit-width-threshold 的关系(Emacs manual 中有解释),大概是这个关系:

(cond ((> emacs-height split-height-threshold)  (上下分屏))  ; 一般总是不满足
      ((> emacs-width  split-width-threshold)   (左右分屏))  ; 你的左右分屏时的情况
      (t                                        (上下分屏))) ; 你的上下分屏时的情况

比如我的 13 英寸笔记本下最大化 Emacs 应用程序时的参数如下:

(list split-height-threshold split-width-threshold)
    ⇒ (80 160)

(list (window-height) (window-width))
    ⇒ (48 177)

可以发现此时 Emacs 宽度足够(177 > 160)所以会左右分屏。此时要是我把 Emacs 宽度缩小一点(比如宽度至 159),就会变成上下分屏了。

C-x 4 b 等命令的分屏规律也一样。


方法之一是把 split-width-threshold 调小些,如果可以的话,再把 Emacs 拉扁些。

本来也可以像下面那样设置 display-buffer-alist 选项来无视宽度高度、总是左右分屏的,但是由于 org-mode shadow 了这个选项,所以不好用了。

(add-to-list 'display-buffer-alist
             `(,(rx (or "*Org Agenda*" "* Agenda Commands*"))
               (display-buffer-in-side-window)
               (side . right)))
4 个赞