如何保存/管理(命名)layout?

我知道ivy可以用来保存和管理layout,但是有个疑问:

如何保存/管理当前的 layout:保存到文件中,并且命名以便下次使用(这个可以用ivy实现吗?)。

非 Spacemacs 用户 :innocent:

可以保存下来吗

(defun my/load-my-layout ()
  (interactive)
  (persp-load-state-from-file (concat persp-save-dir "ztlevi")))

(defun my/save-my-layout ()
  (interactive)
  (if (yes-or-no-p "Do you want to save layout?")
      (persp-save-state-to-file (concat persp-save-dir "ztlevi"))))

不过自从我习惯了spacemacs/ivy-persp-switch-project,基本上就不用上面的函数了。

(defun spacemacs/ivy-persp-switch-project (arg)
  (interactive "P")
  (require 'counsel-projectile)
  (advice-add 'counsel-projectile-switch-project-action
              :before #'spacemacs/ivy-persp-switch-project-advice)
  (ivy-read "Switch to Project Perspective: "
            (if (projectile-project-p)
                (cons (abbreviate-file-name (projectile-project-root))
                      (projectile-relevant-known-projects))
              projectile-known-projects)
            :action #'counsel-projectile-switch-project-action
            :caller 'spacemacs/ivy-persp-switch-project)
  (advice-remove 'counsel-projectile-switch-project-action
                 'spacemacs/ivy-persp-switch-project-advice))

我用start-process开了个buffer 或者是我在shell里运行了sqlite3

下次重启的时候 怎么恢复这两个buffer呢?

如果只是打开个文件 意义不是很大吧

保存layout 最基础的函数是 current-window-configuration 是一个C函数

如果你kill了shell 他并不能给你创建一个shell

persp-mode或eyebrowse建立layouts,内置的desktop-mode来保存它们。

  (desktop-save-mode 1)
  (push '(company-posframe-mode . nil)
      desktop-minor-mode-table)
  (run-with-idle-timer 30 t (lambda () (desktop-save "~/.emacs.d")))

用这个

这个功能我之前也需要。写了几个简单的函数来搞的,原则就是暴力出奇迹,直接把内存中的ivy-views变量存到文件中,需要的时候从文件中读出来赋值就行:


;;; 存入 `~/.emacs.d/ivy-views'文件中
(defun peng-save-ivy-views ()
  (interactive)
  (with-temp-file "~/.emacs.d/ivy-views"
    (prin1 ivy-views (current-buffer))
    (message "save ivy-views to ~/.emacs.d/ivy-views")))
;;; 从文件中加载
(defun peng-load-ivy-views ()
  (interactive)
  (setq ivy-views
        (with-temp-buffer
          (insert-file-contents "~/.emacs.d/ivy-views")
          (read (current-buffer))))
  (message "load ivy-views"))

;;; 清除所有的views
(defun peng-clear-ivy-views ()
  (interactive)
  (setq ivy-views nil))

;;; 退出自动保存
(add-hook 'kill-emacs-hook #'(lambda ()
                               (peng-save-ivy-views)))

;;; 启动自动加载
(add-hook 'emacs-startup-hook #'(lambda ()
                               (peng-load-ivy-views)))

可以根据需要再修改一下。应该可以满足你的需求。

1 个赞

很好用,虽然我已经转 eyebrowser 了emmm

主要是这个不能快速在layout之间切换,eyebrowser可以在modeline上面显示一些信息

ivy-views 压根保存不了,它里面主要是 windows-configuration 对象,没有办法打印出来。emacs 重启后是无法从文件里恢复的。

workgroups2 支持重启后恢复,不过问题比较多,特别是针对 emacs 28 和 simple-modeline 有冲突。

动态保存效果好像不好,我的做法是直接写死,因固定的也就几种layout。ivy-views的写法中有一个sexp没在文档里面,可以包含任何代码,这个就灵活了。

(setq ivy-views '(("{99} current + book"
                     (horz
                      (buffer "*Org Agenda*")
                      (sexp (progn
                              (bookmark-jump "当前书目")
                              (org-noter)))))))

感觉重点应该是写一个 “ivy–get-view-config” 的函数,生成一个当前显示的所有 buffer 的 TREE,其中每一个 buffer 用 bookmark 来捕获。

还真得被我找到一个实现这个功能的:

https://github.com/alphapapa/burly.el

M-x burly-bookmark-windows

1 个赞

不知您有没有, 使用过的 类似笔记了, 或是 有别人用过的 心得之类的

也是, 还是真在这找到了, 像你说的一样, 但是明天看看, 看看 我能不能学会用

安装:

(use-package burly
  :quelpa (burly :fetcher github :repo "alphapapa/burly.el")
  :custom
  (burly-bookmark-prefix " ")
  :bind
  ("C-x r w" . burly-bookmark-windows))

按 “C-x r w” 将当前窗口布局添加为 bookmark,按 “C-x r b” 选择打开 bookmark。

Bury 基于 Emacs 内置的 bookmark,对于特殊的 Buffer 支持有限(如:shell),只有很 少一些特殊的 mode 会提供 bookmark 支持(如:eshell-bookmark)。当然自已添加实现 也不是很麻烦,比如我常用 redis,如下所示添加 bookmark 支持:

;; redis
(use-package redis
  :config
  ;; redis-cli buffer bookmark
  (defun my/redis-cli--bookmark-jump (bookmark)
    "Default bookmark handler for redis-cli buffers."
    (let ((default-directory (bookmark-prop-get bookmark 'path))
          (redis-process-buffer-name (bookmark-prop-get bookmark 'name))
          (redis-cli-executable (bookmark-prop-get bookmark 'executable))
          (args (bookmark-prop-get bookmark 'args)))
      (apply #'redis-cli args)))
  (defun my/redis-cli--bookmark-make-record ()
    "Make a emacs bookmark entry for a redis-cli buffer."
    (let* ((command (process-command (get-buffer-process (current-buffer))))
           (executable (car command))
           (args (cdr command)))
      (cons (buffer-name)
            `((name . ,(buffer-name))
              (path . ,default-directory)
              (executable . ,executable)
              (args . ,args)
              (handler . my/redis-cli--bookmark-jump)))))
  (defun my/redis-cli--comint-mode-hook-function ()
    (if (eq major-mode 'redis-cli-mode)
        (set (make-local-variable 'bookmark-make-record-function)
             'my/redis-cli--bookmark-make-record)))
  (add-hook 'comint-mode-hook 'my/redis-cli--comint-mode-hook-function))
1 个赞

多谢。。。…

和书签功能整合在一起的设计非常方便。。。

多谢, 达到目的了, 在这里找到了个, 用 burly.el 的, 可以新开 同样的 frarme, 当我是 2个, 或 3个, 显示器时, 也行

alphapapa/burly.el: Save and restore frames and windows with their buffers in Emacs

> (defun bss/duplicate-frame ()
>   (interactive)
>   (let* (($my-burly-url (burly-windows-url))
>          $frame)
>     (make-frame-on-monitor "Virtual2" nil (list (cons 'name "Virtual2")))
>     (select-frame-set-input-focus (get-a-frame "Virtual2"))
>     (burly-open-url $my-burly-url) ;
>     ))