让Emacs GUI中的框架行为与终端中的框架相同

6

在终端中,Emacs 使用类似 F1、F2 …… 的名称来管理多个框架,因为它不能创建多个操作系统窗口。我希望 GUI 版本也能这样做,即不创建多个操作系统窗口,而是在一个单独的 Emacs 窗口内创建许多虚拟框架。是否有一种方法可以做到这一点?


请参考 https://www.gnu.org/software/emacs/manual/html_node/emacs/Non_002dWindow-Terminals.html#Non_002dWindow-Terminals。 - tripleee
2个回答

2
如果您的意思是想通过名称访问框架,那么是的,您可以使用Icicles来实现这一点。
默认情况下,C-x 5 o绑定了multi-command icicle-select-frame。这使您可以按名称选择一个或多个框架。
框架的名称来自其name框架参数。必要时会添加后缀[NUMBER]以使其唯一。例如,在以其缓冲区命名框架的上下文中,如果您有两个显示缓冲区*Help*的框架,则其中一个框架将被称为*Help*[2]以供此命令使用。
使用C-x 5 o进行框架选择时会使用补全和循环。补全可以是纯Emacs补全或正则表达式(包括子字符串)补全。(它还可以是几种模糊匹配之一。)
(如果出于某种原因,您希望帧名称仅为F1F2等,就像终端Emacs一样,则只需要在框架参数name的级别进行操作。 您可以使用钩子等来完成这些操作。)

1
我认为这个问题更多地涉及到类似于“屏幕”的功能,即能够在虚拟框架之间切换。我也曾经希望过这样的功能。 - tripleee
我想这样的事情可能可以通过save-window-configuration及其相关函数来完成,但我现在没有实验的地方。 - tripleee
使用 emacs -nw 命令,C-x 5 2 可以创建一个看起来像全新的 Emacs 会话,你可以通过 C-x 5 o 切换回之前的工作。非常方便,试一下吧! - tripleee
@triplee:不,这与新的Emacs会话完全不同。 C-x 5 2 做的事情与以往一样:创建一个新框架。而 C-x 5 o 做的也是它一直在做的事情:选择另一个框架。我理解 OP 的问题是如何在使用 GUI Emacs 时通过名称选择框架(例如,而不仅仅是通过 other-frame 循环),(它还可能包括如何将框架命名为 F1 等)。 - Drew
1
emacs -nw中显然没有“框架”这个功能。我想这个功能是在v23版本中引入的;如果你尝试在没有GUI的情况下使用框架命令,旧版Emacs只会发出哔哔声。 - tripleee
显示剩余7条评论

2

有一种方法可以在GUI中模拟终端emacs的帧切换行为。以下是我所做的。基本上它使用make-frame-invisible来隐藏非活动帧。在archlinux和i3上运行良好。

(defsubst +amos--is-frame-daemons-frame (f)
(and (daemonp) (eq f terminal-frame)))

(defun +amos--frame-list-without-daemon ()
"Return a list of frames without the daemon's frame."
(if (daemonp)
    (filtered-frame-list
    #'(lambda (f) (not (+amos--is-frame-daemons-frame f))))
    (frame-list)))

(defun +amos/workspace-new ()
(interactive)
(let ((name (frame-parameter nil 'name))
        (oframe (selected-frame)))
    (select-frame (if (s-starts-with? "F" name)
                    (make-frame)
                    (make-frame `((name . ,name)))))
    (make-frame-invisible oframe t))
(setq +amos--frame-list (reverse (+amos--frame-list-without-daemon))))

(setq +amos-tmux-need-switch nil)

;; TODO ring lru
(defun +amos/workspace-delete ()
(interactive)
(let ((f (selected-frame)))
    (select-frame (previous-frame))
    (make-frame-visible)
    (delete-frame f))
(setq +amos--frame-list (reverse (+amos--frame-list-without-daemon)))
(+doom-modeline|set-selected-window)
(realign-windows)
(when +amos-tmux-need-switch
    (shell-command! "tmux switch-client -t amos\; run-shell -t amos '/home/amos/scripts/setcursor.sh $(tmux display -p \"#{pane_tty}\")'")
    (setq +amos-tmux-need-switch nil)))

(defun +amos/workspace-switch-to (index)
(interactive)
(when (< index (length +amos--frame-list))
    (let ((frame (nth index +amos--frame-list))
        (oframe (selected-frame)))
    (select-frame frame)
    (raise-frame frame)
    (make-frame-invisible oframe t)
    (setq +amos-tmux-need-switch nil)
    (realign-windows)
    (recenter))))

(defun +amos/workspace-switch-to-1 () (interactive) (+amos/workspace-switch-to 0))
(defun +amos/workspace-switch-to-2 () (interactive) (+amos/workspace-switch-to 1))
(defun +amos/workspace-switch-to-3 () (interactive) (+amos/workspace-switch-to 2))
(defun +amos/workspace-switch-to-4 () (interactive) (+amos/workspace-switch-to 3))
(defun +amos/workspace-switch-to-5 () (interactive) (+amos/workspace-switch-to 4))
(defun +amos/workspace-switch-to-6 () (interactive) (+amos/workspace-switch-to 5))
(defun +amos/workspace-switch-to-7 () (interactive) (+amos/workspace-switch-to 6))
(defun +amos/workspace-switch-to-8 () (interactive) (+amos/workspace-switch-to 7))
(defun +amos/workspace-switch-to-9 () (interactive) (+amos/workspace-switch-to 8))
(defun +amos-workspace-cycle (off)
(let* ((n (length +amos--frame-list))
        (index (-elem-index (selected-frame) +amos--frame-list))
        (i (% (+ off index n) n)))
    (+amos/workspace-switch-to i)))
(defun +amos/workspace-switch-left ()  (interactive) (+amos-workspace-cycle -1))
(defun +amos/workspace-switch-right () (interactive) (+amos-workspace-cycle +1))

(defun +amos|maybe-delete-frame-buffer (frame)
(let ((windows (window-list frame)))
    (dolist (window windows)
    (let ((buffer (window-buffer (car windows))))
        (when (eq 1 (length (get-buffer-window-list buffer nil t)))
        (kill-buffer buffer))))))
(add-to-list 'delete-frame-functions #'+amos|maybe-delete-frame-buffer)

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