emacs-format-all-the-code icon indicating copy to clipboard operation
emacs-format-all-the-code copied to clipboard

Avoid repositioning the buffer after formatting?

Open ianyepan opened this issue 3 years ago • 13 comments

As titled, I noticed that when I invoke format-all's command to format the current buffer, the buffer will reposition itself (most likely because there are bits of code 'outside' of the buffer that have been formatted), resulting in an overhead to try to find my cursor position again. Is there a way for format-all to remember the buffer position and the cursor position and restore that after the buffer is formatted?

ianyepan avatar Jan 31 '22 17:01 ianyepan

I might have found a workaround. But there are some edge cases that behaves weirdly though.

(defun stable/format-all-buffer ()
  "Auto-format whole buffer without repositioning the buffer."
  (interactive)
  (let ((windowstart (window-start)))
    (format-all-buffer)
    (set-window-start (selected-window) windowstart)))

ianyepan avatar Jan 31 '22 17:01 ianyepan

I found a better workaround based on your approach. I'm sure this will work. The point is to remove and add the hook again.

I hope this approach will help the maintainer fix this bug.


;; remove hook initially assigned when autoload
(remove-hook 'before-save-hook 'format-all--buffer-from-hook t)

;; add hook with -format-all-buffer() again
(add-hook 'before-save-hook '-format-all-buffer))

(defun -format-all-buffer ()
  "format-all-buffer without jumps of cursor"
  (interactive)
  (let ((point (point)) (wstart (window-start)))
    (format-all-buffer)
    (goto-char point)
    (set-window-start (selected-window) wstart)))

thyeem avatar Feb 08 '22 18:02 thyeem

Thanks for the snippet!

The point is to remove and add the hook again.

Can you kindly explain this part a bit? And why it might fix the edge cases I'm experiencing?

ianyepan avatar Feb 08 '22 20:02 ianyepan

Nothing special. The problem was that your solution didn't work as well. I assumed that there was something wrong with the hook. (Obviously, no other reasons to come up with)

And I tried replacing the hook (remove and add), it worked well. I'm suspicious of conflicts (if any) around the hook.

I'm not an elisper unlike you :) Please take a closer look based on this assumption.

thyeem avatar Feb 09 '22 00:02 thyeem

I'm encountering this issue as well. My current solution based on the snipped above (probably very bad because i'm new to emacs/spacemacs):

  ;; Set up 'format-all' to format on save
  (use-package format-all
    :init
    (add-hook 'solidity-mode-hook
              (lambda ()
                (format-all-ensure-formatter)
                (add-hook
                 'before-save-hook
                 `format-all-buffer--no-bufferjump)))
    )

  ;; Custom 'format' function with fixed buffer jumping
  (defun format-all-buffer--no-bufferjump ()
    "format-all-buffer without jumps of cursor"
    (interactive)
    (let ((point (point)) (wstart (window-start)))
      (format-all-buffer)
      (goto-char point)
      (set-window-start (selected-window) wstart)))

Are there any plans to fix this bug? Thanks.

rappie avatar Mar 28 '22 15:03 rappie

i have the problem . but above solution not grace. the author why not fix it. the problem very suffer pain

zcjava avatar Dec 09 '22 22:12 zcjava

Sorry about the long delay. Does the above commit improve things?

lassik avatar Dec 10 '22 16:12 lassik

Sorry about the long delay. Does the above commit improve things?

ye fixed it , but curror stay old position, why not keep stay old code line position?do u know my mean? do u have some choose ,people can config choose cursor pository mode

zcjava avatar Dec 10 '22 17:12 zcjava

the effect like prettier-js format html. after format, the curror return old code line star position.like below:

https://user-images.githubusercontent.com/1551382/206868929-715c252f-70c3-44e3-a183-1bbc4b53b9a5.mov

zcjava avatar Dec 10 '22 18:12 zcjava

Thank you for trying to improve this issue.

As 'zcjava' is saying, it does save/restore the window position now but the cursor jumps to a new location.

An easy way to reproduce this is to add some useless empty newlines above the cursor, scroll down so they are off screen, and then run the formatter to remove them.

rappie avatar Dec 12 '22 16:12 rappie

May be we can put a invisible text property at the cursor point before format, after format, move the cursor to the new position with the text property.

tangxinfa avatar Jan 28 '23 02:01 tangxinfa

Sorry, I'm very busy with other stuff and don't have time to look into this.

If you can send pull requests which improve some aspect of the problem without breaking anything, I'll merge them.

lassik avatar Jan 29 '23 16:01 lassik

Bump because I am having the same problem

yaaama avatar Jul 15 '23 09:07 yaaama