如题,window configuration 很好用,但其痛点是:当window中的原始buffer被killed掉时,便无法恢复到保存时的那个buffer。对于绑定到文件的buffer来说,无论是否被kill,能够随着window布局一起恢复是个很实用的需求。这样每次重新打开emacs,都能快速进入上一次的工作现场。
不知道有没有道友知道现成的 package 或方案?没有话,我就要自己实现一个了。
如题,window configuration 很好用,但其痛点是:当window中的原始buffer被killed掉时,便无法恢复到保存时的那个buffer。对于绑定到文件的buffer来说,无论是否被kill,能够随着window布局一起恢复是个很实用的需求。这样每次重新打开emacs,都能快速进入上一次的工作现场。
不知道有没有道友知道现成的 package 或方案?没有话,我就要自己实现一个了。
可以试试 activities.
这个package可以的,多谢。
如果想要window layout和file的绑定,那只能是往一个给定的window layout里面去填装file buffer,仅此而已。第一步,遍历window-list
,把每个window的位置参数和buffer-file-name
作为成员的属性构建一个window列表。第二步,实现一个restore
函数,读取列表并恢复原窗口布局,打开文件,挂到emacs-startup-hook
上
以下是chat的实现,看上去问题不大:
(defun get-windows-position-and-size ()
"Return a list of positions and file paths of all windows in the current frame."
(let ((window-data '()))
(dolist (window (window-list))
(when (window-live-p window)
(let* ((edges (window-edges window))
(left (nth 0 edges))
(top (nth 1 edges))
(width (nth 2 edges))
(height (nth 3 edges))
(buffer (window-buffer window))
(file-path (buffer-file-name buffer))) ;; Get full file path
;; Store the position, size, and file path as an alist for each window
(push (list :file-path file-path :left left :top top :width width :height height) window-data))))
;; Reverse the list since we used `push`
(reverse window-data)))
(defun recover-windows-from-data (window-data)
"Recover windows according to WINDOW-DATA, which is a list of alists.
Each element of WINDOW-DATA should be an alist with :file-path, :left,
:top, :width, and :height entries."
(let ((current-window (selected-window)))
(delete-other-windows) ;; Start with a single window
(let ((frame (selected-frame))) ;; Get the current frame to set position
(dolist (data window-data)
(let ((file-path (plist-get data :file-path))
(left (plist-get data :left))
(top (plist-get data :top))
(width (plist-get data :width))
(height (plist-get data :height)))
(let ((new-window (split-window current-window)))
(with-selected-window new-window
(if (file-exists-p file-path) ;; Check if the file exists
(let ((buffer (find-file-noselect file-path))) ;; Open the file without selecting it
(set-window-buffer new-window buffer)
;; Resize window to specified height
(resize-window height t)
;; Set window width (optional)
(let ((new-width width))
(if (> new-width (frame-width))
(setq new-width (frame-width))) ;; Prevent exceeding frame width
(if (> new-width 0)
(enlarge-window new-width nil))))
;; If the file doesn't exist, show error message
(let ((error-buffer (generate-new-buffer "*Error File Not Found*")))
(with-current-buffer error-buffer
(insert (format "Error: The file '%s' does not exist." file-path))
(insert "\n\nPlease check the file path.")
(goto-char (point-min))) ;; Move to the beginning of the buffer
(set-window-buffer new-window error-buffer) ;; Show the error buffer
;; Resize window to specified height, if needed
(resize-window height t)
;; Set window width (optional)
(let ((new-width width))
(if (> new-width (frame-width))
(setq new-width (frame-width))) ;; Prevent exceeding frame width
(if (> new-width 0)
(enlarge-window new-width nil)))))))
;; Optional: Adjust the position
(set-frame-position frame left top))))
(setq current-window (next-window current-window))))) ;; Move to the next window
试试workgroups2.
workgroups2更简单好用,3q ~