[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/tempel 11cfbe239d 36/82: Fix undo
From: |
ELPA Syncer |
Subject: |
[elpa] externals/tempel 11cfbe239d 36/82: Fix undo |
Date: |
Sun, 9 Jan 2022 20:58:43 -0500 (EST) |
branch: externals/tempel
commit 11cfbe239d4e4c33056a8f9bff0331cb96fa8dec
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>
Fix undo
---
tempel.el | 63 ++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/tempel.el b/tempel.el
index 5c9d60587c..d727806c58 100644
--- a/tempel.el
+++ b/tempel.el
@@ -124,34 +124,47 @@ WIDTH, SEP and ELLIPSIS configure the formatting."
'face 'completions-annotations))
width 0 ?\s ellipsis))))
-(defun tempel--update-field (ov after beg end &optional _len)
+(defun tempel--field-modified (ov after beg end &optional _len)
"Update field overlay OV.
AFTER is non-nil after the modification.
BEG and END are the boundaries of the modification."
(when (and after (>= beg (overlay-start ov)) (<= beg (overlay-end ov)))
- (save-excursion
- ;; TODO: We use silent modifications such that the undo list is
- ;; not affected and that the modification hooks are not triggered
- ;; recursively. However since the edits which are made to the
- ;; other fields are not recorded in the undo list, we will end up
- ;; with an invalid undo state after tempel-done.
+ (move-overlay ov (overlay-start ov) (max end (overlay-end ov)))
+ (let ((st (overlay-get ov 'tempel--state)))
+ (when-let (name (overlay-get ov 'tempel--name))
+ (setf (alist-get name (cdr st))
+ (buffer-substring-no-properties
+ (overlay-start ov) (overlay-end ov))))
+ (unless undo-in-progress
+ (template--synchronize-fields st ov)))))
+
+(defun template--synchronize-fields (st current)
+ "Synchronize fields of ST, except CURRENT overlay."
+ (dolist (ov (car st))
+ (unless (eq ov current)
+ (save-excursion
+ (goto-char (overlay-start ov))
+ (let (x)
+ (when-let (str (or (and (setq x (overlay-get ov 'tempel--form))
(eval x (cdr st)))
+ (and (setq x (overlay-get ov 'tempel--name))
(alist-get x (cdr st)))))
+ (tempel--replace (overlay-start ov) (overlay-end ov) ov str)))))))
+
+(defun tempel--replace (beg end ov str)
+ "Replace region beween BEG and END with STR.
+If OV is alive, move it."
+ (let ((old (buffer-substring-no-properties beg end)))
+ (unless (equal str old)
+ (unless (eq buffer-undo-list t)
+ (push (list 'apply #'tempel--replace
+ beg (+ beg (length str)) ov old)
+ buffer-undo-list))
(with-silent-modifications
- (move-overlay ov (overlay-start ov) (max end (overlay-end ov)))
- (let ((st (overlay-get ov 'tempel--state))
- (name (overlay-get ov 'tempel--name))
- str)
- (when name
- (setq str (buffer-substring-no-properties (overlay-start ov)
(overlay-end ov)))
- (setf (alist-get name (cdr st)) str))
- (dolist (other (car st))
- (unless (eq other ov)
- (goto-char (overlay-start other))
- (when-let (str (if-let (form (overlay-get other 'tempel--form))
- (eval form (cdr st))
- (and name (eq name (overlay-get other
'tempel--name)) str)))
- (delete-char (- (overlay-end other) (point)))
- (insert str)
- (move-overlay other (overlay-start other) (point))))))))))
+ (save-excursion
+ (goto-char beg)
+ (delete-char (- end beg))
+ (insert str)
+ (when (overlay-buffer ov)
+ (move-overlay ov beg (point))))))))
(defun tempel--field (st &optional name init)
"Add template field to ST.
@@ -161,8 +174,8 @@ INIT is the optional initial input."
(push ov (car st))
(overlay-put ov 'face 'tempel-field)
(overlay-put ov 'before-string #(" " 0 1 (display (space :width (1)) face
tempel-field)))
- (overlay-put ov 'modification-hooks (list #'tempel--update-field))
- (overlay-put ov 'insert-behind-hooks (list #'tempel--update-field))
+ (overlay-put ov 'modification-hooks (list #'tempel--field-modified))
+ (overlay-put ov 'insert-behind-hooks (list #'tempel--field-modified))
(overlay-put ov 'tempel--state st)
(when name
(overlay-put ov 'tempel--name name)
- [elpa] externals/tempel 4a6fc2d0ab 46/82: Fix customization type, (continued)
- [elpa] externals/tempel 4a6fc2d0ab 46/82: Fix customization type, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 0aa4e8c37f 63/82: Only erase default value if the point is at the beginning or end, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel def7a1ca3f 07/82: README: Update links, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 311f310b82 72/82: Remove todo, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 9cf5cc35b3 16/82: Use insert-file-contents, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel db24ec0c9e 22/82: Reevaluate forms when arbitrary fields are modified, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 09a0e3bfb0 19/82: Improve annotations, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 16b0fa274a 09/82: Rename commands, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 73cee5feb6 12/82: Update comments, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel b54036f1fa 21/82: Add comment, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 11cfbe239d 36/82: Fix undo,
ELPA Syncer <=
- [elpa] externals/tempel ffdf2c792a 77/82: Document the abbrev modes (See #14), ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 460f8fe806 81/82: Fix the MELPA issues, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel aec4f10253 82/82: Addition to GNU ELPA, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel d4bd649645 59/82: Minor renaming, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 2cff879181 30/82: Do not call modification hooks from forms, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 1222c59b30 39/82: Update README, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 07d16fded7 67/82: Update fields when new field is inserted, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel f0df571f66 17/82: Respect derived modes, ELPA Syncer, 2022/01/09
- [elpa] externals/tempel bf95b3f1c2 31/82: Add support for (q (FORM ...) var), ELPA Syncer, 2022/01/09
- [elpa] externals/tempel 64f896d782 44/82: Fix jump to first field, ELPA Syncer, 2022/01/09