emacs如何记忆和切换窗口布局?

这个还没试过。 window-configuration-to-register 是不是得离开之前先regist?那就非常麻烦了。

其实上面那个elscreen正好就是解决这个问题的。不过它有点缺陷。

难道没人告诉你这个插件:

zygospore,GitHub - LouisKottmann/zygospore.el: reversible C-x 1 for Emacs

还有一个persp-mode 应该也满足需求

个人认为,tabspace 也是一个不错的workspace管理插件,是在emacs29+ tab-bar-mode的基础上运作的

这个没太看明白它的介绍。

多谢各位。我先用着tabbar,回头抽空试试其他的。

这是我的一个命令,可能正好满足你的要求。

(defvar im/fullscreen-alist nil
  "Alist to save window configurations used to toggle fullscreen layout.
Item should be (win-id-list window-configuration buffers-info updated-at) style.")

(defun im/toggle-fullscreen (&optional arg)
  "Toggle fullscreen easily. Recommended binding to C-x 1 or F11."
  (interactive "P")
  (if (minibufferp) (exit-minibuffer))
  (cl-labels
      ((win-id (window) ; Is there a simpler way to get the window id?
         (let ((ws (format "%s" window)))
           (string-match "^#<window \\([0-9]+\\)" ws)
           (string-to-number (match-string 1 ws))))
       (save-layout ()
         (let (win-ids wc)
           (walk-window-tree (lambda (w)
                               (push (win-id w) win-ids))) ; use win-ids to distinguish different layouts
           (setq im/fullscreen-alist
                 (cl-remove-if (lambda (c) (equal (car c) win-ids)) im/fullscreen-alist)) ; ensure update
           (setq wc (list win-ids
                          (current-window-configuration)
                          (mapconcat (lambda (w) (buffer-name (window-buffer w))) (window-list) ", ")
                          (time-to-seconds)))
           (setq im/fullscreen-alist (cons wc im/fullscreen-alist))))
       (switch-layout ()
         (cl-labels
             ((wc-list (id-string) ; get the saved layout
                (assoc (mapcar #'string-to-number (split-string id-string ", ")) im/fullscreen-alist))
              (ids-str (ids)
                (mapconcat #'number-to-string ids ", "))
              (sort-fn (wcs) ; sort by created/updated time
                (sort wcs (lambda (x y) (not (time-less-p (cadddr (wc-list x)) (cadddr (wc-list y)))))))
              (annotation-fn (wc) ; display more useful information
                (let ((item (wc-list wc)))
                  (concat (make-string (- 30 (length (ids-str (car item)))) ? )
                          (format "%-30s" (format-seconds "%Y %D %H %M %z%S"
                                                          (float-time (time-subtract (time-to-seconds) (cadddr item)))))
                          (caddr item)))))
           (let* ((collection (mapcar (lambda (c) (ids-str (car c))) im/fullscreen-alist))
                  (item (minibuffer-with-setup-hook
                            (lambda ()
                              (let ((map (make-composed-keymap nil (current-local-map))))
                                (define-key map (kbd "C-k")
                                            (lambda ()
                                              (interactive)
                                              (cl-loop for i from 0 for wc in im/fullscreen-alist
                                                       unless (= i vertico--index) collect wc into rs
                                                       finally (setq im/fullscreen-alist rs))
                                              (throw 'fullscreen-minibuffer 'del)))
                                (define-key map (kbd "C-S-k")
                                            (lambda ()
                                              (interactive)
                                              (setq im/fullscreen-alist nil)
                                              (throw 'fullscreen-minibuffer 'clear)))
                                (use-local-map map)))
                          (catch 'fullscreen-minibuffer
                            (completing-read "Layout: "
                                             (lambda (input _pred action)
                                               (pcase action
                                                 ('metadata
                                                  `(metadata (category . toggle-fullscreen)
                                                             (display-sort-function . ,#'sort-fn)
                                                             (annotation-function . ,#'annotation-fn)))
                                                 ('(boundaries . _) nil)
                                                 (_
                                                  (complete-with-action action collection input nil))))
                                             nil t nil nil (car collection))))))
             (cond ((eq item 'del) (im/toggle-fullscreen 1))
                   ((eq item 'clear) (message "Clear done."))
                   (t (if-let (wc (cadr (wc-list item))) (set-window-configuration wc))))))))
    ;; single window: try to choose and switch to another layout
    (if (equal (selected-window) (next-window))
        (if (zerop (length im/fullscreen-alist))
            (user-error "No saved window configuration found")
          (switch-layout))
      (if arg
          ;; call with prefix: switch layout only
          (progn
            (save-layout)
            (switch-layout))
        ;; multiple windows: add/update before delete others windows
        (save-layout)
        (delete-other-windows)))))


建议将命令绑定到 C-x 1,我是绑定到了 f11。

希望可以给你一定思路。

多谢! 我试试。

请问 tab-bar-go-to-tab-macro 是怎么实现的呢


(defmacro my/tab-bar-go-to-tab-macro (number)
    (let ((fun (intern (format "my/tab-bar-go-to-tab-%d" number))))
        `(defun ,fun ()
             ,(format "go to tab %d" number)
             (interactive)
             (tab-bar-select-tab ,number))))