burly.el icon indicating copy to clipboard operation
burly.el copied to clipboard

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

Open hubisan opened this issue 1 year ago • 3 comments

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:

  • Removing position from the value returned by bookmark-make-record doesn't seem to work (with an advice).
  • Removing point from the state argument of burly--bufferize-window-state seems to crash Emacs. Maybe I had a mistake in the filtering function.

hubisan avatar May 24 '23 10:05 hubisan

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.

alphapapa avatar May 24 '23 11:05 alphapapa

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)

hubisan avatar May 25 '23 12:05 hubisan

That's a cool hack! :)

alphapapa avatar May 25 '23 15:05 alphapapa