mirror of
https://github.com/vale981/apheleia
synced 2025-03-04 09:01:42 -05:00
Preserve marks as well as points (#198)
Marks are processed in almost exactly the same way as point; in particular going through exactly the same `apheleia--align-point` function. This works with minimal changes because markers act like numbers, but also can be passed to `set-marker` to mutate their state. --------- Co-authored-by: Radon Rosborough <radon@intuitiveexplanations.com>
This commit is contained in:
parent
49701675a8
commit
615b0f5591
2 changed files with 54 additions and 31 deletions
|
@ -27,6 +27,8 @@ The format is based on [Keep a Changelog].
|
||||||
* Prettier is now enabled in `svelte-mode`.
|
* Prettier is now enabled in `svelte-mode`.
|
||||||
* More tree-sitter based major modes have been added to
|
* More tree-sitter based major modes have been added to
|
||||||
`apheleia-mode-alist` ([#191]).
|
`apheleia-mode-alist` ([#191]).
|
||||||
|
* All marks (the current `(mark)`, and the `mark-ring`) are now
|
||||||
|
adjusted, alongside `(point)` ([#197]).
|
||||||
* Built-in formatters now use a new `"apheleia-npx"` built-in script
|
* Built-in formatters now use a new `"apheleia-npx"` built-in script
|
||||||
instead of the legacy `npx` keyword. The effect of the new script is
|
instead of the legacy `npx` keyword. The effect of the new script is
|
||||||
the same, except that it also works with Yarn PNP projects as well
|
the same, except that it also works with Yarn PNP projects as well
|
||||||
|
@ -104,6 +106,7 @@ The format is based on [Keep a Changelog].
|
||||||
[#182]: https://github.com/radian-software/apheleia/pull/182
|
[#182]: https://github.com/radian-software/apheleia/pull/182
|
||||||
[#187]: https://github.com/radian-software/apheleia/pull/187
|
[#187]: https://github.com/radian-software/apheleia/pull/187
|
||||||
[#196]: https://github.com/radian-software/apheleia/pull/196
|
[#196]: https://github.com/radian-software/apheleia/pull/196
|
||||||
|
[#197]: https://github.com/radian-software/apheleia/issues/197
|
||||||
[#208]: https://github.com/radian-software/apheleia/discussions/208
|
[#208]: https://github.com/radian-software/apheleia/discussions/208
|
||||||
[#209]: https://github.com/radian-software/apheleia/pull/209
|
[#209]: https://github.com/radian-software/apheleia/pull/209
|
||||||
[#213]: https://github.com/radian-software/apheleia/pull/213
|
[#213]: https://github.com/radian-software/apheleia/pull/213
|
||||||
|
|
|
@ -120,12 +120,18 @@ contains the patch."
|
||||||
(apheleia--log
|
(apheleia--log
|
||||||
'rcs "Applying RCS patch from %S to %S" patch-buffer content-buffer)
|
'rcs "Applying RCS patch from %S to %S" patch-buffer content-buffer)
|
||||||
(let ((commands nil)
|
(let ((commands nil)
|
||||||
(point-list nil)
|
(pos-list nil)
|
||||||
(window-line-list nil))
|
(window-line-list nil))
|
||||||
(with-current-buffer content-buffer
|
(with-current-buffer content-buffer
|
||||||
(push (cons nil (point)) point-list)
|
(push `(:type point :pos ,(point)) pos-list)
|
||||||
|
(when (marker-position (mark-marker))
|
||||||
|
(push `(:type marker :pos ,(mark-marker)) pos-list))
|
||||||
|
(dolist (m mark-ring)
|
||||||
|
(when (marker-position m)
|
||||||
|
(push `(:type marker :pos ,m) pos-list)))
|
||||||
(dolist (w (get-buffer-window-list nil nil t))
|
(dolist (w (get-buffer-window-list nil nil t))
|
||||||
(push (cons w (window-point w)) point-list)
|
(push
|
||||||
|
`(:type window-point :pos ,(window-point w) :window ,w) pos-list)
|
||||||
(push (cons w (count-lines (window-start w) (point)))
|
(push (cons w (count-lines (window-start w) (point)))
|
||||||
window-line-list)))
|
window-line-list)))
|
||||||
(with-current-buffer patch-buffer
|
(with-current-buffer patch-buffer
|
||||||
|
@ -173,10 +179,12 @@ contains the patch."
|
||||||
(let ((text-start (alist-get 'marker deletion)))
|
(let ((text-start (alist-get 'marker deletion)))
|
||||||
(forward-line (alist-get 'lines deletion))
|
(forward-line (alist-get 'lines deletion))
|
||||||
(let ((text-end (point)))
|
(let ((text-end (point)))
|
||||||
(dolist (entry point-list)
|
(dolist (pos-spec pos-list)
|
||||||
;; Check if the (window) point is within the
|
(let ((p (plist-get pos-spec :pos)))
|
||||||
;; replaced region.
|
;; Check if the point, or marker, or window
|
||||||
(cl-destructuring-bind (w . p) entry
|
;; point, is within the replaced region.
|
||||||
|
;; Markers pretend to be numbers, so we can
|
||||||
|
;; run this in any of the three cases.
|
||||||
(when (and (< text-start p)
|
(when (and (< text-start p)
|
||||||
(< p text-end))
|
(< p text-end))
|
||||||
(let* ((old-text (buffer-substring-no-properties
|
(let* ((old-text (buffer-substring-no-properties
|
||||||
|
@ -191,31 +199,43 @@ contains the patch."
|
||||||
(apheleia--align-point
|
(apheleia--align-point
|
||||||
old-text new-text old-relative-point))))
|
old-text new-text old-relative-point))))
|
||||||
(goto-char text-start)
|
(goto-char text-start)
|
||||||
(push `((marker . ,(point-marker))
|
(push
|
||||||
(command . set-point)
|
`((command . move-cursor)
|
||||||
(window . ,w)
|
(cursor . ,pos-spec)
|
||||||
(relative-point . ,new-relative-point))
|
(offset . ,(- new-relative-point
|
||||||
commands))))))))))))))
|
old-relative-point)))
|
||||||
|
commands))))))))))))))
|
||||||
(with-current-buffer content-buffer
|
(with-current-buffer content-buffer
|
||||||
(let ((move-to nil))
|
;; We run both `goto-char' and `set-window-point' to offset
|
||||||
(save-excursion
|
;; point and window point, don't want to chance that both
|
||||||
(dolist (command (nreverse commands))
|
;; changes will stack on top of each other.
|
||||||
(goto-char (alist-get 'marker command))
|
(let ((orig-point (point)))
|
||||||
(pcase (alist-get 'command command)
|
(dolist (command (nreverse commands))
|
||||||
(`addition
|
(pcase (alist-get 'command command)
|
||||||
(insert (alist-get 'text command)))
|
(`addition
|
||||||
(`deletion
|
(save-excursion
|
||||||
(let ((text-start (point)))
|
(goto-char (alist-get 'marker command))
|
||||||
(forward-line (alist-get 'lines command))
|
(insert (alist-get 'text command))))
|
||||||
(delete-region text-start (point))))
|
(`deletion
|
||||||
(`set-point
|
(save-excursion
|
||||||
(let ((new-point
|
(goto-char (alist-get 'marker command))
|
||||||
(+ (point) (alist-get 'relative-point command))))
|
(forward-line (alist-get 'lines command))
|
||||||
(if-let ((w (alist-get 'window command)))
|
(delete-region (alist-get 'marker command) (point))))
|
||||||
(set-window-point w new-point)
|
(`move-cursor
|
||||||
(setq move-to new-point)))))))
|
(let ((cursor (alist-get 'cursor command))
|
||||||
(when move-to
|
(offset (alist-get 'offset command)))
|
||||||
(goto-char move-to))))
|
(pcase (plist-get cursor :type)
|
||||||
|
(`point
|
||||||
|
(goto-char
|
||||||
|
(+ orig-point offset)))
|
||||||
|
(`marker
|
||||||
|
(set-marker
|
||||||
|
(plist-get cursor :pos)
|
||||||
|
(+ (plist-get cursor :pos) offset)))
|
||||||
|
(`window-point
|
||||||
|
(set-window-point
|
||||||
|
(plist-get cursor :window)
|
||||||
|
(+ orig-point offset))))))))))
|
||||||
;; Restore the scroll position of each window displaying the
|
;; Restore the scroll position of each window displaying the
|
||||||
;; buffer.
|
;; buffer.
|
||||||
(dolist (entry window-line-list)
|
(dolist (entry window-line-list)
|
||||||
|
|
Loading…
Add table
Reference in a new issue