Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

use symbol instead of word when region not active #1

Closed
wants to merge 15 commits into from

3 participants

Le Wang victorhge Tassilo Horn
Le Wang
Collaborator

No description provided.

victorhge
Owner

What is the problem your patch is solving? Would you give me an example?

BR/
Victor Ren

Le Wang
Collaborator
Le Wang
Collaborator
victorhge
Owner
Le Wang added some commits
Le Wang fix search to use regexp-quote when needed 45784a9
Le Wang implement interactive string-rectangle mode with universal argument a…
…nd region selected

Conflicts:

	iedit.el
9a37ca1
Le Wang Merge branch 'master' of github.com:lewang/iedit
Conflicts:
	iedit.el
448ceb3
Le Wang add edit rectangle option
when region is activ eand Universal prefix arg is given, the region is edited
as a rectangle.
c854c28
Le Wang lewang closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 2 changed files with 131 additions and 52 deletions. Show diff stats Hide diff stats

  1. +3 3 README
  2. +128 49 iedit.el
6 README
... ... @@ -1,5 +1,5 @@
1 1 iedit - a better alternative of replace-string
2   -
3   -It is an Emacs minor mode and allow you edit one occurrence of some text in a
  2 +---------------------------------------------------------------------------------
  3 +It is an Emacs minor mode and allows you to edit one occurrence of some text in a
4 4 buffer (possibly narrowed), and simultaneously have all other occurrences edited
5   -the same way.
  5 +in the same way.
177 iedit.el
... ... @@ -1,11 +1,11 @@
1 1 ;;; iedit.el --- Edit multiple regions with the same content simultaneously.
2 2
3   -;; Copyright (C) 2010, 2011 Victor Ren
  3 +;; Copyright (C) 2010, 2011, 2012 Victor Ren
4 4
5   -;; Time-stamp: <2012-01-14 23:12:48 Victor Ren>
  5 +;; Time-stamp: <2012-01-17 02:58:46 Victor Ren>
6 6 ;; Author: Victor Ren <victorhge@gmail.com>
7 7 ;; Keywords: occurrence region replace simultaneous
8   -;; Version: 0.90
  8 +;; Version: 0.91
9 9 ;; X-URL: http://www.emacswiki.org/emacs/iedit.el
10 10 ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x
11 11
@@ -30,7 +30,7 @@
30 30 ;; This package provides a more intuitive way of replace-string operation:
31 31 ;;
32 32 ;; - Select the occurrence in the buffer
33   -;; In Transient Mark mode, just mark a region, the content of the
  33 +;; In Transient Mark mode, just mark a region, the content of the
34 34 ;; region will be used as the occurrence. (if Transient Mark mode is disabled,
35 35 ;; using C-u C-x C-x or C-SPC C-SPC to activate it just for this one time).
36 36 ;;
@@ -42,8 +42,8 @@
42 42 ;;
43 43 ;; - Finish - by pressing C-; again
44 44
45   -;; If Transient Mark mode is disabled or the region is not active,
46   -;; the `current-word' is used as the occurrence by default.
  45 +;; If Transient Mark mode is disabled or the region is not active, the current
  46 +;; symbol (returns from `current-word') is used as the occurrence by default.
47 47
48 48 ;; You can also switch to iedit mode from isearch mode directly. The current
49 49 ;; search string is used as the occurrence.
@@ -56,7 +56,7 @@
56 56 ;; (define-key isearch-mode-map (kbd "C-;") 'iedit-mode)
57 57
58 58 ;;; todo:
59   -;; - C-n,C-p is slow when unmachted lines are hided.
  59 +;; - C-n,C-p is slow when unmatched lines are hided.
60 60 ;; - Lazy highlight feature (from isearch)?
61 61 ;; - toggle blank line between matched lines?
62 62 ;; - ert unit test
@@ -65,6 +65,11 @@
65 65 ;;; Contributors
66 66 ;; Adam Lindberg <eproxus@gmail.com> added a case sensitivity option that can be toggled.
67 67
  68 +;; Tassilo Horn <tassilo@member.fsf.org> added an option to match only complete
  69 +;; words, not inside words
  70 +
  71 +;; Le Wang <l26wang@gmail.com> proposed to match only complete symbols, not inside symbols.
  72 +
68 73 ;;; Code:
69 74
70 75 (eval-when-compile (require 'cl))
@@ -80,16 +85,24 @@
80 85 :type 'face
81 86 :group 'iedit)
82 87
83   -(defcustom iedit-current-word-default 't
84   - "If no-nil, use current word by default for the occurrence."
  88 +(defcustom iedit-current-symbol-default t
  89 + "If no-nil, use current symbol by default for the occurrence."
85 90 :type 'boolean
86 91 :group 'iedit)
87 92
88   -(defcustom iedit-case-sensitive-default 't
  93 +(defcustom iedit-case-sensitive-default t
89 94 "If no-nil, matching is case sensitive"
90 95 :type 'boolean
91 96 :group 'iedit)
92 97
  98 +(defcustom iedit-only-at-symbol-boundaries t
  99 + "If no-nil, matches have to start and end at symbol boundaries.
  100 + For example, when invoking iedit-mode on the \"in\" in the
  101 + sentence \"The king in the castle...\", the \"king\" is not
  102 + edited."
  103 + :type 'boolean
  104 + :group 'iedit)
  105 +
93 106 (defcustom iedit-unmatched-lines-invisible-default nil
94 107 "If no-nil, hide lines that do not cover any occurrences by
95 108 default."
@@ -108,7 +121,7 @@ default."
108 121
109 122 (or (assq 'iedit-mode minor-mode-alist)
110 123 (nconc minor-mode-alist
111   - (list '(iedit-mode iedit-mode))))
  124 + (list '(iedit-mode iedit-mode))))
112 125
113 126 (defvar iedit-occurrences-overlays nil
114 127 "The occurrences slot contains a list of overlays used to
@@ -227,44 +240,70 @@ This is like `describe-bindings', but displays only Iedit keys."
227 240 If iedit mode is off, turn iedit mode on, off otherwise.
228 241
229 242 In Transient Mark mode, when iedit mode is turned on, all the
230   -occurrences of the current region are highlighted. If one
  243 +occurrences of the current region are highlighted. If one
231 244 occurrence is modified, the change are propagated to all other
232 245 occurrences simultaneously.
233 246
234 247 If Transient Mark mode is disabled or the region is not active,
235   -the `current-word' is used as occurrence. All the occurrences of
236   -the `current-word' are highlighted.
  248 +the current symbol (returns from `current-word') is used as the
  249 +occurrence by default. The occurrences of the current
  250 +symbol, but not include occurrences that are part of other
  251 +symbols, are highlighted. This is good for renaming refactoring
  252 +during programming. If you still want to match all the
  253 +occurrences, even though they are parts of other symbols, you may
  254 +have to select the symbol first.
237 255
238 256 You can also switch to iedit mode from isearch mode directly. The
239 257 current search string is used as occurrence. All occurrences of
240 258 the current search string are highlighted.
241 259
242   -With a prefix argument, the occurrence when iedit is turned off
243   -last time is used as occurrence. This is intended to recover
244   -last iedit which is turned off by mistake.
  260 +With a universal prefix argument and no active region, the
  261 +occurrence when iedit is turned off last time is used as
  262 +occurrence. This is intended to recover last iedit which is
  263 +turned off by mistake.
  264 +
  265 +With a universal prefix argument and region active, interactively
  266 +edit region as a string rectangle.
245 267
246 268 Commands:
247 269 \\{iedit-mode-map}"
248   - (interactive "P")
  270 + (interactive "*P")
249 271 (if iedit-mode
250 272 (iedit-done)
251   - (let ((occurrence nil))
252   - (cond ((and arg iedit-last-occurrence-in-history)
  273 + (let (occurrence rect-string)
  274 + (cond ((and arg
  275 + (not (use-region-p))
  276 + iedit-last-occurrence-in-history)
253 277 (setq occurrence iedit-last-occurrence-in-history))
  278 + ((and arg
  279 + (use-region-p))
  280 + (setq rect-string t))
254 281 ((and transient-mark-mode mark-active (not (equal (mark) (point))))
255   - (setq occurrence (buffer-substring-no-properties (mark) (point))))
  282 + (setq occurrence (regexp-quote (buffer-substring-no-properties
  283 + (mark) (point)))))
256 284 ((and isearch-mode (not (string= isearch-string "")))
257   - (setq occurrence (buffer-substring-no-properties (point) isearch-other-end))
  285 + (setq occurrence (funcall (if isearch-regexp
  286 + 'eval
  287 + 'regexp-quote)
  288 + (buffer-substring-no-properties
  289 + (point) isearch-other-end)))
258 290 (isearch-exit))
259   - ((and iedit-current-word-default (current-word t))
260   - (setq occurrence (current-word)))
  291 + ((and iedit-current-symbol-default (current-word t))
  292 + (setq occurrence (regexp-quote (current-word)))
  293 + (when iedit-only-at-symbol-boundaries
  294 + (setq occurrence (concat "\\_<" (regexp-quote occurrence) "\\_>"))))
261 295 (t (error "No candidate of the occurrence, cannot enable iedit mode.")))
262   - (deactivate-mark)
263   - (iedit-start occurrence))))
  296 + (if rect-string
  297 + (let ((beg (region-beginning))
  298 + (end (region-end)))
  299 + (deactivate-mark)
  300 + (iedit-rectangle beg end))
  301 + (deactivate-mark)
  302 + (iedit-start occurrence)))))
264 303
265 304 (defun iedit-start (occurrence-exp)
266 305 "Start an iedit for the occurrence-exp in the current buffer."
267   - (setq iedit-mode " Iedit")
  306 + (setq iedit-mode (propertize " Iedit" 'face 'font-lock-warning-face))
268 307 (setq iedit-occurrences-overlays nil)
269 308 (setq iedit-unmatched-lines-invisible iedit-unmatched-lines-invisible-default)
270 309 (setq iedit-case-sensitive iedit-case-sensitive-default)
@@ -275,21 +314,48 @@ Commands:
275 314 ;; Find and record each occurrence's markers and add the overlay to the occurrences
276 315 (let ((counter 0)
277 316 (case-fold-search (not iedit-case-sensitive)))
278   - (save-excursion
279   - (goto-char (point-min))
280   - (while (search-forward occurrence-exp nil t)
281   - (push (iedit-make-occurrence-overlay (match-beginning 0) (match-end 0))
282   - iedit-occurrences-overlays)
283   - (setq counter (1+ counter))) ; at less 1
  317 + (save-excursion
  318 + (goto-char (point-min))
  319 + (while (re-search-forward occurrence-exp nil t)
  320 + (push (iedit-make-occurrence-overlay (match-beginning 0) (match-end 0))
  321 + iedit-occurrences-overlays)
  322 + (setq counter (1+ counter))) ; at less 1
284 323 (setq iedit-occurrences-overlays (nreverse iedit-occurrences-overlays))
285 324 (if iedit-unmatched-lines-invisible
286 325 (iedit-hide-unmatched-lines))
287   - (message "%d matches for \"%s\""
288   - counter
  326 + (message "%d matches for \"%s\""
  327 + counter
289 328 (if (> (length occurrence-exp) 50)
290 329 (concat (substring occurrence-exp 0 50) "...")
291 330 occurrence-exp)))))
292 331
  332 +(defun iedit-rectangle (beg end)
  333 + "Start an iedit for the region as a rectangle"
  334 + (setq iedit-mode (propertize " Iedit-RECT" 'face 'font-lock-warning-face))
  335 + (setq iedit-occurrences-overlays nil)
  336 + (force-mode-line-update)
  337 + (run-hooks 'iedit-mode-hook)
  338 + ;; (add-hook 'mouse-leave-buffer-hook 'iedit-done)
  339 + (add-hook 'kbd-macro-termination-hook 'iedit-done)
  340 +
  341 + (let ((orig-p (point-marker))
  342 + (beg-col (progn (goto-char beg) (current-column)))
  343 + (end-col (progn (goto-char end) (current-column))))
  344 + (when (< end-col beg-col)
  345 + (rotatef beg-col end-col))
  346 + (goto-char beg)
  347 + (loop do (progn
  348 + (push (iedit-make-occurrence-overlay (progn
  349 + (move-to-column beg-col t)
  350 + (point))
  351 + (progn
  352 + (move-to-column end-col t)
  353 + (point)))
  354 + iedit-occurrences-overlays)
  355 + (forward-line 1))
  356 + until (> (point) end))
  357 + (goto-char orig-p)))
  358 +
293 359 (defun iedit-hide-unmatched-lines ()
294 360 "Hide unmatched lines using invisible overlay."
295 361 (let ((prev-occurrence-end 0)
@@ -314,8 +380,8 @@ Commands:
314 380 (defun iedit-done ()
315 381 "Exit iedit mode."
316 382 (let ((ov (car iedit-occurrences-overlays)))
317   - (if ov
318   - (setq iedit-last-occurrence-in-history
  383 + (if ov
  384 + (setq iedit-last-occurrence-in-history
319 385 (buffer-substring (overlay-start ov) (overlay-end ov)))))
320 386 (remove-overlays (point-min) (point-max) iedit-occurrence-overlay-name t)
321 387 (remove-overlays (point-min) (point-max) iedit-invisible-overlay-name t)
@@ -347,22 +413,35 @@ occurrences if the user starts typing."
347 413 (overlay-put unmatched-lines-overlay 'intangible t)
348 414 unmatched-lines-overlay))
349 415
  416 +;; `iedit-occurrence-update' gets called twice when change==0 and occurrence
  417 +;; is zero-width
  418 +;; -- for front and back insertion.
  419 +(defvar iedit-last-overlay nil
  420 + "records processed overlay so they don't get processed multiple times. See code.")
  421 +(defun iedit-post-command-func ()
  422 + (remove-hook 'post-command-hook 'iedit-post-command-func t)
  423 + (setq iedit-last-overlay nil))
  424 +
350 425 (defun iedit-occurrence-update (occurrence after beg end &optional change)
351 426 "Update all occurrences.
352 427 This modification hook is triggered when a user edits any
353 428 occurrence and is responsible for updating all other
354 429 occurrences."
355   - (when (and after (not undo-in-progress)) ; undo will do all the work
356   - (let ((value (buffer-substring (overlay-start occurrence) (overlay-end occurrence)))
  430 + (when (and after
  431 + (not undo-in-progress) ; undo will do all the work
  432 + (not (< beg (overlay-start occurrence)))
  433 + (not (eq occurrence iedit-last-overlay)))
  434 + (setq iedit-last-overlay occurrence)
  435 + (add-hook 'post-command-hook 'iedit-post-command-func nil t)
  436 + (let ((replacement-str (buffer-substring-no-properties beg end))
  437 + (index (- beg (overlay-start occurrence)))
357 438 (inhibit-modification-hooks t))
358 439 (save-excursion
359 440 (dolist (like-occurrence iedit-occurrences-overlays)
360   - (if (not (eq like-occurrence occurrence))
361   - (progn
362   - (goto-char (overlay-start like-occurrence))
363   - (delete-region (overlay-start like-occurrence)
364   - (overlay-end like-occurrence))
365   - (insert value))))))))
  441 + (when (not (eq like-occurrence occurrence))
  442 + (goto-char (+ index (overlay-start like-occurrence)))
  443 + (delete-region (point) (+ (point) change))
  444 + (insert replacement-str)))))))
366 445
367 446 (defun iedit-next-occurrence ()
368 447 "Move forward to the next occurrence in the `iedit'.
@@ -375,13 +454,13 @@ beginning of the buffer."
375 454 (when in-occurrence
376 455 (setq pos (next-single-char-property-change pos 'iedit-occurrence-overlay-name)))
377 456 (setq pos (next-single-char-property-change pos 'iedit-occurrence-overlay-name))
378   -
  457 +
379 458 (if (/= pos (point-max))
380 459 (setq iedit-forward-success t)
381 460 (if (and iedit-forward-success in-occurrence)
382 461 (progn (message "This is the last occurrence.")
383 462 (setq iedit-forward-success nil))
384   - (progn
  463 + (progn
385 464 (if (get-char-property (point-min) 'iedit-occurrence-overlay-name)
386 465 (setq pos (point-min))
387 466 (setq pos (next-single-char-property-change (point-min) 'iedit-occurrence-overlay-name)))
@@ -404,12 +483,12 @@ the buffer."
404 483 ;; At the start of the first occurrence
405 484 (if (or (and (eq pos (point-min))
406 485 (not (get-char-property (point-min) 'iedit-occurrence-overlay-name)))
407   - (and (eq (point) (point-min))
  486 + (and (eq (point) (point-min))
408 487 in-occurrence))
409 488 (if (and iedit-forward-success in-occurrence)
410 489 (progn (message "This is the first occurrence.")
411 490 (setq iedit-forward-success nil))
412   - (progn
  491 + (progn
413 492 (setq pos (previous-single-char-property-change (point-max) 'iedit-occurrence-overlay-name))
414 493 (if (not (get-char-property (- (point-max) 1) 'iedit-occurrence-overlay-name))
415 494 (setq pos (previous-single-char-property-change pos 'iedit-occurrence-overlay-name)))

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.