Saving evil global marks with desktop.el

What are you trying to do?

i am trying to save the variable evil-markers-alist when calling doom/save-session (which is basically a wrapper for desktop-save). so that when i call doom/load-session (wrapper for desktop-read) all global marks are restored.

the issue might be, that evil stores marks in the variable evil-markers-alist as markers an elisp datatype that can’t trivially be serialized and restored later.

in a similar post:

hendrik proposes the solution: “we have to swap out those markers with (path . pos) cons cells, where path is a string and pos is an integer.”

my attempt at solving the problem

(after! desktop
  (add-to-list 'desktop-globals-to-save 'evil-markers-alist) ;; alternatively maybe use: `desktop-locals-to-save` ?

  (add-hook! 'desktop-locals-to-save
    (kill-local-variable 'evil-markers-alist)
    (dolist (entry evil-markers-alist)
      (when (markerp (cdr entry))
        (setcdr entry (cons (file-truename (buffer-file-name (marker-buffer (cdr entry))))
                            (marker-position (cdr entry))))))))

results

this attempt does correctly serializes the variable, however after doing the following:

  1. opening a file
  2. setting a global mark with m M
  3. calling doom/quicksave-session
  4. restarting emacs
  5. calling doom/quickload-session
  6. accessing the mark: ' M

i get the message that the mark is not set (even though it should have been restored).

resolved

after hacking around, i found it can be achieved using the following code:

(require 'desktop)

 (defun z-serialize-evil-global-markers-alist ()
   "evil stores marks in the variable 'evil-markers-alist' as markers an elisp datatype that can’t
    trivially be serialized and restored later.

    (path . pos) cons cells, where path is a string and pos is an integer, and those are trivial to
    serialize."
   (mapcar (lambda (it)
             (if (markerp (cdr it))
                 (let ((marker-file (file-truename (buffer-file-name (marker-buffer (cdr it))))))
                   (when marker-file     ;; only if marker associated with a file.
                     (cons (car it)
                           (cons marker-file
                                 (marker-position (cdr it))))))
               it))
           (default-value 'evil-markers-alist))) ;; only use global marks

(after! desktop
 (defvar z-evil-global-markers-alist nil)

 (add-to-list 'desktop-globals-to-save 'z-evil-global-markers-alist)

 (add-hook! 'desktop-save-hook
   (setq z-evil-global-markers-alist (z-serialize-evil-global-markers-alist)))

 (add-hook! 'desktop-after-read-hook
   (setq-default evil-markers-alist z-evil-global-markers-alist)))

(however i would now advise to use dooms workspaces module instead, so i will keep this here for anyone looking to solve this issue)