alphapapa / burly.el

Save and restore frames and windows with their buffers in Emacs
GNU General Public License v3.0
301 stars 14 forks source link

Is it possible to not restore point (cursor position)? #60

Closed hubisan closed 1 month ago

hubisan commented 1 year ago

Is it somehow possible to not restore point in buffers when restoring a window configuration with burly-open-bookmark?

When working on a project, I restore the window configuration with burly-open-bookmark. Since point is also restored along with the window configuration, I am compelled to bookmark the window configuration again before switching to another project. This ensures that the cursor is located at the current position when I restore that projects window configuration again.

Findings:

alphapapa commented 1 year ago

Hi Daniel,

Because of the way Burly works (using the bookmark system internally), I think it would be impractical, if not impossible, to do this, because each major mode's bookmark-make-record-function is out of Burly's control. As well, the bookmark jump function is out of Burly's control, and it is already difficult to deal with the way it moves point and changes buffers.

I understand what you're trying to do and why this is annoying. My advice would be to use burly-tabs-mode so that each Burly bookmark is opened in a different tab-bar tab. Then you can easily switch between tabs without losing previous buffer/window points. And then when you want to restore a project's initial view, you can use burly-reset-tab to do so.

Having gotten used to using tab-bar-mode in Emacs this way, I sorely miss it when using older Emacs versions. If you haven't tried it yet, I strongly recommend it. It makes project/workspace management so much easier, especially with burly-tabs-mode.

hubisan commented 1 year ago

I will give tab-bar-mode and burly-tabs-mode a go. Should probably have done this a long time ago. Thanks for the tip.

If it is of use to anyone, found a 'hacky' way to not restore point (not tested extensively):

(require 'map)
(require 'url-util)

(defun my-burly-get-point (filename)
  "Return the last known point for FILENAME.
If the file is currently visited in a buffer, the point from that buffer is
returned. If `saveplace' is enabled and a stored point exists for the file, that
point is returned. Otherwise, nil is returned."
  (if-let ((buffer (find-buffer-visiting filename)))
      (with-current-buffer buffer
        (point))
    (when (require 'saveplace nil t)
      (or save-place-loaded (save-place-load-alist-from-file))
      (let ((point (cdr-safe (assoc filename save-place-alist))))
        (when (integerp point)
          point)))))

(defun my-burly-restore-point (state)
  "Avoid restoring point by modifying it in STATE for each buffer to be restored.
If a buffer is already visiting a file being restored, use its current point
instead. Otherwise, use the saved point from the `saveplace' feature if
available."
  (mapc (lambda (elt)
          ;; Point is inside leaf elements.
          (when (eq (car-safe elt) 'leaf)
            ;; Extract the burly url to get the filename.
            (pcase-let* ((`(leaf . ,attributes) elt)
                         ((map parameters) attributes)
                         ((map burly-url) parameters)
                         (urlobj (url-generic-parse-url burly-url))
                         ((cl-struct url type) urlobj)
                         (subtype (car (last (split-string type "+" 'omit-nulls))))
                         (`(,path . ,query-string) (url-path-and-query urlobj))
                         (query (url-parse-query-string query-string))
                         (point
                          (pcase-exhaustive subtype
                            ("bookmark"
                             (my-burly-get-point (string-trim (car-safe (map-elt query "filename")) "\"" "\"")))
                            ("file" (my-burly-get-point path))
                            ("name" nil))))
              (mapc (lambda (elt)
                      ;; The point element is inside the buffer element.
                      (when (eq (car-safe elt) 'buffer)
                        (mapc (lambda (elt)
                                (when (eq (car-safe elt) 'point)
                                  ;; Change the point.
                                  (when point
                                    (setcdr elt point))))
                              elt)))
                    elt))))
        (car state))
  state)

(advice-add 'burly--bufferize-window-state :filter-args #'my-burly-restore-point)
alphapapa commented 1 year ago

That's a cool hack! :)