[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/iedit 070775fb85 296/301: New feature: apply kmacro on occ
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/iedit 070775fb85 296/301: New feature: apply kmacro on occurrences |
Date: |
Mon, 10 Jan 2022 22:59:12 -0500 (EST) |
branch: elpa/iedit
commit 070775fb85b233351bd17b534d2dec9157f5311e
Author: Victor Ren <victorhge@gmail.com>
Commit: Victor Ren <victorhge@gmail.com>
New feature: apply kmacro on occurrences
This feature eliminates a restriction of Iedit - modifications can only
happen
inside of occurrences. The occurrences are used as start points when
executing
kmacro.
---
iedit-lib.el | 109 ++++++++++++++++++++++++++++++++++++++++++++++-----------
iedit-tests.el | 41 ++++++++++++++++++++--
2 files changed, 126 insertions(+), 24 deletions(-)
diff --git a/iedit-lib.el b/iedit-lib.el
index cfe0fb1f43..571ea3eb7a 100644
--- a/iedit-lib.el
+++ b/iedit-lib.el
@@ -3,7 +3,7 @@
;; Copyright (C) 2010 - 2019, 2020, 2021 Victor Ren
-;; Time-stamp: <2021-12-23 18:32:28 Victor Ren>
+;; Time-stamp: <2021-12-23 19:28:21 Victor Ren>
;; Author: Victor Ren <victorhge@gmail.com>
;; Keywords: occurrence region simultaneous rectangle refactoring
;; Version: 0.9.9.9
@@ -56,6 +56,8 @@
(eval-when-compile (require 'cl-lib))
+(require 'kmacro)
+
(declare-function c-before-change "cc-mode.el")
(defgroup iedit nil
@@ -162,6 +164,13 @@ that is going to be changed.")
(defvar iedit-before-buffering-point nil
"This is buffer local variable which is the point before modification.")
+(defvar iedit-buffering-overlay nil
+ "This is buffer local variable which is the current overlay before starting
recording kmacro.")
+
+(defvar iedit-start-kmacro-offset nil
+ "This is buffer local variable which is the offset from the
+ current overlay start before starting recording kmacro.")
+
;; `iedit-record-changes' gets called twice when change==0 and
;; occurrence is zero-width (beg==end) -- for front and back insertion.
(defvar iedit-skip-modification-once t
@@ -214,6 +223,8 @@ It replaces `inhibit-modification-hooks' which prevents
calling
(make-variable-buffer-local 'iedit-before-buffering-string)
(make-variable-buffer-local 'iedit-before-buffering-undo-list)
(make-variable-buffer-local 'iedit-before-buffering-point)
+(make-variable-buffer-local 'iedit-buffering-overlay)
+(make-variable-buffer-local 'iedit-start-kmacro-offset)
(make-variable-buffer-local 'iedit-skip-modification-once)
(make-variable-buffer-local 'iedit-aborting)
(make-variable-buffer-local 'iedit-buffering)
@@ -258,6 +269,9 @@ It replaces `inhibit-modification-hooks' which prevents
calling
(define-key map (kbd "M-D") 'iedit-delete-occurrences)
(define-key map (kbd "M-N") 'iedit-number-occurrences)
(define-key map (kbd "M-B") 'iedit-toggle-buffering)
+ (define-key map [remap kmacro-start-macro-or-insert-counter]
'iedit-start-kmacro)
+ (define-key map [remap kmacro-end-or-call-macro]
'iedit-end-and-call-kmacro)
+ (define-key map [remap kmacro-end-and-call-macro]
'iedit-end-and-call-kmacro)
(define-key map (kbd "M-<") 'iedit-goto-first-occurrence)
(define-key map (kbd "M->") 'iedit-goto-last-occurrence)
(define-key map (kbd "C-?") 'iedit-help-for-occurrences)
@@ -316,6 +330,12 @@ It should be set before occurrence overlay is created.")
(defun iedit--quit ()
"Quit the current mode by calling mode exit function."
(interactive)
+ (when iedit-buffering
+ (setq iedit-buffering nil)
+ (when defining-kbd-macro
+ (kmacro-keyboard-quit)
+ (force-mode-line-update t)
+ (setq defining-kbd-macro nil)))
(funcall iedit-lib-quit-func))
(defun iedit-make-markers-overlays (markers)
@@ -445,16 +465,20 @@ there are."
(setq iedit-lib-quit-func mode-exit-func)
(add-hook 'post-command-hook 'iedit-update-occurrences nil t)
(add-hook 'before-revert-hook iedit-lib-quit-func nil t)
- (add-hook 'kbd-macro-termination-hook iedit-lib-quit-func nil t)
+;; (add-hook 'kbd-macro-termination-hook iedit-lib-quit-func nil t)
(add-hook 'change-major-mode-hook iedit-lib-quit-func nil t)
(setq iedit-after-change-list nil))
(defun iedit-lib-cleanup ()
"Clean up occurrence overlay, invisible overlay and local variables."
+ (when iedit-buffering
+ (if defining-kbd-macro
+ (iedit-end-and-call-kmacro nil)
+ (iedit-stop-buffering)))
(iedit-cleanup-occurrences-overlays)
(remove-hook 'post-command-hook 'iedit-update-occurrences t)
(remove-hook 'before-revert-hook iedit-lib-quit-func t)
- (remove-hook 'kbd-macro-termination-hook iedit-lib-quit-func t)
+ ;; (remove-hook 'kbd-macro-termination-hook iedit-lib-quit-func t)
(remove-hook 'change-major-mode-hook iedit-lib-quit-func t)
(setq iedit-lib-quit-func nil)
(setq iedit-occurrences-overlays nil)
@@ -941,7 +965,6 @@ FORMAT."
(iedit-barf-if-buffering)
(iedit-apply-on-occurrences 'delete-region))
-;; todo: add cancel buffering function
(defun iedit-toggle-buffering ()
"Toggle buffering.
This is intended to improve iedit's response time. If the number
@@ -952,11 +975,7 @@ be applied to other occurrences when buffering is off."
(interactive "*")
(if iedit-buffering
(iedit-stop-buffering)
- (iedit-start-buffering))
- (message (concat "Modification Buffering "
- (if iedit-buffering
- "started."
- "stopped."))))
+ (iedit-start-buffering)))
(defun iedit-start-buffering ()
"Start buffering."
@@ -964,9 +983,61 @@ be applied to other occurrences when buffering is off."
(setq iedit-before-buffering-string (iedit-current-occurrence-string))
(setq iedit-before-buffering-undo-list buffer-undo-list)
(setq iedit-before-buffering-point (point))
- (buffer-disable-undo)
+ (setq iedit-buffering-overlay (iedit-find-current-occurrence-overlay))
(message "Start buffering editing..."))
+(defun iedit-start-kmacro ()
+ "Start recording subsequent keyboard input, defining a keyboard macro.
+The relative position of the current occurrence is remembered."
+ (interactive)
+ (iedit-barf-if-buffering)
+ (setq iedit-buffering t)
+ (setq iedit-buffering-overlay (iedit-find-current-occurrence-overlay))
+ (setq iedit-start-kmacro-offset (- (point) (overlay-start
iedit-buffering-overlay)))
+ (let ((map (make-sparse-keymap)))
+ (define-key map [remap kmacro-end-or-call-macro]
'iedit-end-and-call-kmacro)
+ (set-transient-map map (lambda () iedit-buffering)))
+ (kmacro-start-macro nil)
+ (message "Start recording keyboard input..."))
+
+(defun iedit-end-and-call-kmacro (arg &optional no-repeat)
+ "Call last keyboard macro, ending it first if currently being defined, apply
it on all the occurrences.
+
+If iedit is buffering, call it only once.
+
+If the defining macro was not started from `iedit-start-macro',
+end it only.
+
+This command is intended to eliminate a restriction of other
+commands - monidfications allowed only inside of occurrences.
+The recorded modifications can be outside of the occurrences.
+The cursor is moved to the relative positon of every occurrence
+before calling the last keboard macro."
+ (interactive "P")
+ (cond
+ ((and iedit-buffering (not defining-kbd-macro))
+ (kmacro-call-macro arg no-repeat))
+ ((and defining-kbd-macro (null iedit-buffering-overlay))
+ (kmacro-end-macro arg))
+ (t (if (and (not defining-kbd-macro) (null iedit-buffering-overlay))
+ (setq iedit-start-kmacro-offset (- (point) (overlay-start
(iedit-find-current-occurrence-overlay))))
+ ;; (and defining-kbd-macro iedit-buffering-overlay)
iedit-start-kmacro was called
+ (kmacro-end-macro nil)
+ (setq iedit-buffering nil))
+ (let ((iedit-updating t))
+ (save-excursion
+ (when iedit-buffering-overlay (iedit-move-conjoined-overlays
iedit-buffering-overlay))
+ (dolist (another-occurrence iedit-occurrences-overlays)
+ (when (not (eq another-occurrence
iedit-buffering-overlay))
+ (goto-char (+ (overlay-start another-occurrence)
iedit-start-kmacro-offset))
+ (kmacro-call-macro nil t)
+ (iedit-move-conjoined-overlays another-occurrence)))))
+ (setq iedit-buffering-overlay nil)
+ (if (iedit-same-length)
+ (message "Keyboard macro applied to the occurrences.")
+ (iedit--quit)
+ (message "Abort Iedit mode due to different change made to
occurrrences.")))))
+
(defun iedit-case-pattern (beg end)
"Distinguish the case pattern of the text between `beg' and `end'.
@@ -1012,11 +1083,8 @@ it is captilized.'"
'no-change)))))
(defun iedit-stop-buffering ()
- "Stop buffering and apply the modification to other occurrences.
-If current point is not at any occurrence, the buffered
-modification is not going to be applied to other occurrences."
- (let ((ov (iedit-find-current-occurrence-overlay)))
- (when ov
+ "Stop buffering and apply the modification to other occurrences."
+ (let ((ov iedit-buffering-overlay))
(let* ((beg (overlay-start ov))
(end (overlay-end ov))
(modified-string (buffer-substring-no-properties beg end))
@@ -1030,7 +1098,7 @@ modification is not going to be applied to other
occurrences."
(goto-char beg)
(insert-and-inherit iedit-before-buffering-string)
(goto-char iedit-before-buffering-point)
- (buffer-enable-undo)
+ ;; (buffer-enable-undo)
(setq buffer-undo-list iedit-before-buffering-undo-list)
;; go back here if undo
(push (point) buffer-undo-list)
@@ -1050,10 +1118,11 @@ modification is not going to be applied to other
occurrences."
modified-string))
(t modified-string))))
(iedit-move-conjoined-overlays occurrence))))
- (goto-char (+ (overlay-start ov) offset))))))
+ (goto-char (+ (overlay-start ov) offset))
+ (message "Buffered modification applied."))))
(setq iedit-buffering nil)
- (message "Buffered modification applied.")
- (setq iedit-before-buffering-undo-list nil))
+ (setq iedit-before-buffering-undo-list nil)
+ (setq iedit-buffering-overlay nil))
(defun iedit-move-conjoined-overlays (occurrence)
"This function keeps overlays conjoined after modification.
@@ -1164,8 +1233,6 @@ Return nil if occurrence string is empty string."
(defun iedit-cleanup-occurrences-overlays (&optional beg end inclusive)
"Remove overlays from list `iedit-occurrences-overlays'."
- (when iedit-buffering
- (iedit-stop-buffering))
;; Close overlays opened by `isearch-range-invisible'
(isearch-clean-overlays)
(when iedit-hiding
diff --git a/iedit-tests.el b/iedit-tests.el
index d3fc19834b..51801e4bb3 100644
--- a/iedit-tests.el
+++ b/iedit-tests.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2010 - 2019, 2020 Victor Ren
-;; Time-stamp: <2021-12-23 18:19:15 Victor Ren>
+;; Time-stamp: <2021-12-23 19:28:33 Victor Ren>
;; Author: Victor Ren <victorhge@gmail.com>
;; Version: 0.9.9.9
;; X-URL: https://github.com/victorhge/iedit
@@ -595,9 +595,9 @@ foo
(iedit-toggle-buffering)
(should (string= (buffer-string)
"foo
- barfoo
+ foo
barfoo
- barfoo")))))
+ foo")))))
(ert-deftest iedit-buffering-undo-test ()
(with-iedit-test-fixture
@@ -634,6 +634,41 @@ foo
foo"))
)))
+(ert-deftest iedit-buffering-quit-test ()
+ (with-iedit-test-fixture
+"foo
+ foo
+ barfoo
+ foo"
+ (lambda ()
+ (iedit-mode) ;turnoff
+ (setq iedit-auto-buffering t)
+ (push nil buffer-undo-list)
+ (call-interactively 'iedit-mode)
+ (insert "bar")
+ (run-hooks 'post-command-hook)
+ (should (string= (buffer-string)
+"barfoo
+ foo
+ barfoo
+ foo"))
+ (call-interactively 'iedit--quit)
+ (should (string= (buffer-string)
+"barfoo
+ foo
+ barfoo
+ foo"))
+ (should (= (point) 4))
+ (push nil buffer-undo-list)
+ (undo 1)
+ (should (= (point) 1))
+ (should (string= (buffer-string)
+"foo
+ foo
+ barfoo
+ foo"))
+ )))
+
(ert-deftest iedit-rectangle-start-test ()
(with-iedit-test-fixture
"foo
- [nongnu] elpa/iedit 85fad4a3b7 233/301: Merge pull request #73 from lionel-/feature-mode-line, (continued)
- [nongnu] elpa/iedit 85fad4a3b7 233/301: Merge pull request #73 from lionel-/feature-mode-line, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit a7f5ed7cf9 257/301: Turn off iedit-mode at running `iedit-mode-toggle-on-function` twice, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit 5050b7e88e 260/301: Fix a failed test case when Emacs is compiled without GUI, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit afca4e6bbf 213/301: Rename hook functions, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit 7ab2509231 225/301: Expand iedit-regexp-quote with passthrough, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit efe98b2015 248/301: fix `iedit-mode-on-fuction problem, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit 01fa1e5925 217/301: Fix error if sgml-electric-tag-pair-mode not bound, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit d7db0e5d19 279/301: Replace `iedit-lib-aborting-hook' with a callback function, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit dbf3f9a0e3 290/301: Add iedit-update-key-bindings, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit 351bee5e0d 292/301: New iedit-record-changes, ELPA Syncer, 2022/01/10
- [nongnu] elpa/iedit 070775fb85 296/301: New feature: apply kmacro on occurrences,
ELPA Syncer <=
- [nongnu] elpa/iedit 3c7159a107 298/301: Avoid calling `iedit-lib-cleanup` twice, ELPA Syncer, 2022/01/10