emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/iedit ec765ee0c4 018/301: implement interactive string-rec


From: ELPA Syncer
Subject: [nongnu] elpa/iedit ec765ee0c4 018/301: implement interactive string-rectangle mode with universal argument and region selected
Date: Mon, 10 Jan 2022 22:58:46 -0500 (EST)

branch: elpa/iedit
commit ec765ee0c4639ad66530631bfe1653d4850c3709
Author: Le Wang <le.wang@agworld.com.au>
Commit: Le Wang <le.wang@agworld.com.au>

    implement interactive string-rectangle mode with universal argument and 
region selected
---
 iedit.el | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 71 insertions(+), 17 deletions(-)

diff --git a/iedit.el b/iedit.el
index 5b9ae9971a..09bd6d8671 100644
--- a/iedit.el
+++ b/iedit.el
@@ -257,18 +257,27 @@ You can also switch to iedit mode from isearch mode 
directly. The
 current search string is used as occurrence.  All occurrences of
 the current search string are highlighted.
 
-With a prefix argument, the occurrence when iedit is turned off
-last time is used as occurrence.  This is intended to recover
-last iedit which is turned off by mistake.
+With a universal prefix argument and no active region, the
+occurrence when iedit is turned off last time is used as
+occurrence.  This is intended to recover last iedit which is
+turned off by mistake.
+
+With a universal prefix argument and region active, interactively
+edit region as a string rectangle.
 
 Commands:
 \\{iedit-mode-map}"
-  (interactive "P")
+  (interactive "*P")
   (if iedit-mode
       (iedit-done)
-    (let ((occurrence nil))
-      (cond ((and arg iedit-last-occurrence-in-history)
+    (let (occurrence rect-string)
+      (cond ((and arg
+                  (not (use-region-p))
+                  iedit-last-occurrence-in-history)
              (setq occurrence iedit-last-occurrence-in-history))
+            ((and arg
+                  (use-region-p))
+             (setq rect-string t))
             ((and transient-mark-mode mark-active (not (equal (mark) (point))))
              (setq occurrence (regexp-quote (buffer-substring-no-properties
                                              (mark) (point)))))
@@ -284,12 +293,17 @@ Commands:
              (when iedit-only-at-symbol-boundaries
                (setq occurrence (concat "\\_<" (regexp-quote occurrence) 
"\\_>"))))
             (t (error "No candidate of the occurrence, cannot enable iedit 
mode.")))
-      (deactivate-mark)
-      (iedit-start occurrence))))
+      (if rect-string
+          (let ((beg (region-beginning))
+                (end (region-end)))
+            (deactivate-mark)
+            (iedit-rectangle beg end))
+        (deactivate-mark)
+        (iedit-start occurrence)))))
 
 (defun iedit-start (occurrence-exp)
   "Start an iedit for the occurrence-exp in the current buffer."
-  (setq        iedit-mode " Iedit")
+  (setq        iedit-mode (propertize " Iedit" 'face 'font-lock-warning-face))
   (setq iedit-occurrences-overlays nil)
   (setq iedit-unmatched-lines-invisible 
iedit-unmatched-lines-invisible-default)
   (setq iedit-case-sensitive iedit-case-sensitive-default)
@@ -315,6 +329,33 @@ Commands:
                    (concat (substring occurrence-exp 0 50) "...")
                  occurrence-exp)))))
 
+(defun iedit-rectangle (beg end)
+  "Start an iedit for the region as a rectangle"
+  (setq iedit-mode (propertize " Iedit-RECT" 'face 'font-lock-warning-face))
+  (setq iedit-occurrences-overlays nil)
+  (force-mode-line-update)
+  (run-hooks 'iedit-mode-hook)
+  ;; (add-hook 'mouse-leave-buffer-hook 'iedit-done)
+  (add-hook 'kbd-macro-termination-hook 'iedit-done)
+
+  (let ((orig-p (point-marker))
+        (beg-col (progn (goto-char beg) (current-column)))
+        (end-col (progn (goto-char end) (current-column))))
+    (when (< end-col beg-col)
+      (rotatef beg-col end-col))
+    (goto-char beg)
+    (loop do (progn
+               (push (iedit-make-occurrence-overlay (progn
+                                                      (move-to-column beg-col 
t)
+                                                      (point))
+                                                    (progn
+                                                      (move-to-column end-col 
t)
+                                                      (point)))
+                     iedit-occurrences-overlays)
+               (forward-line 1))
+          until (> (point) end))
+    (goto-char orig-p)))
+
 (defun iedit-hide-unmatched-lines ()
   "Hide unmatched lines using invisible overlay."
   (let ((prev-occurrence-end 0)
@@ -372,22 +413,35 @@ occurrences if the user starts typing."
     (overlay-put unmatched-lines-overlay 'intangible t)
     unmatched-lines-overlay))
 
+;; `iedit-occurrence-update' gets called twice when change==0 and occurrence
+;; is zero-width
+;; -- for front and back insertion.
+(defvar iedit-last-overlay nil
+  "records processed overlay so they don't get processed multiple times.  See 
code.")
+(defun iedit-post-command-func ()
+  (remove-hook 'post-command-hook 'iedit-post-command-func t)
+  (setq iedit-last-overlay nil))
+
 (defun iedit-occurrence-update (occurrence after beg end &optional change)
   "Update all occurrences.
 This modification hook is triggered when a user edits any
 occurrence and is responsible for updating all other
 occurrences."
-  (when (and after (not undo-in-progress)) ; undo will do all the work
-    (let ((value (buffer-substring (overlay-start occurrence) (overlay-end 
occurrence)))
+  (when (and after
+             (not undo-in-progress)     ; undo will do all the work
+             (not (< beg (overlay-start occurrence)))
+             (not (eq occurrence iedit-last-overlay)))
+    (setq iedit-last-overlay occurrence)
+    (add-hook 'post-command-hook 'iedit-post-command-func nil t)
+    (let ((replacement-str (buffer-substring-no-properties beg end))
+          (index (- beg (overlay-start occurrence)))
           (inhibit-modification-hooks t))
       (save-excursion
         (dolist (like-occurrence iedit-occurrences-overlays)
-          (if (not (eq like-occurrence occurrence))
-              (progn
-                (goto-char (overlay-start like-occurrence))
-                (delete-region (overlay-start like-occurrence)
-                               (overlay-end like-occurrence))
-                (insert value))))))))
+          (when (not (eq like-occurrence occurrence))
+            (goto-char (+ index (overlay-start like-occurrence)))
+            (delete-region (point) (+ (point) change))
+            (insert replacement-str)))))))
 
 (defun iedit-next-occurrence ()
   "Move forward to the next occurrence in the `iedit'.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]