]> git.donarmstrong.com Git - lib.git/blob - emacs_el/iedit-rect.el
fix missing ) for org-mode
[lib.git] / emacs_el / iedit-rect.el
1 ;;; iedit-rect.el --- visible rectangle editing support based on Iedit.
2
3 ;; Copyright (C) 2010, 2011, 2012 Victor Ren
4
5 ;; Time-stamp: <2012-09-05 09:49:55 Victor Ren>
6 ;; Author: Victor Ren <victorhge@gmail.com>
7 ;; Keywords: occurrence region simultaneous rectangle refactoring
8 ;; Version: 0.97
9 ;; X-URL: http://www.emacswiki.org/emacs/Iedit
10 ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x
11
12 ;; This file is not part of GNU Emacs, but it is distributed under
13 ;; the same terms as GNU Emacs.
14
15 ;; GNU Emacs is free software: you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation, either version 3 of the License, or
18 ;; (at your option) any later version.
19
20 ;; GNU Emacs is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
27
28 ;;; Commentary:
29
30 ;; This package also provides rectangle support with *visible rectangle*
31 ;; highlighting, which is similar with cua-mode rectangle support. But it is
32 ;; lighter weight and uses iedit mechanisms.
33
34 ;; The code was developed and fully tested on Gnu Emacs 24.0.93, partially
35 ;; tested on Gnu Emacs 22. If you have any compatible problem, please let me
36 ;; know.
37
38 ;;; todo:
39 ;; - Add restrict function back
40
41 ;;; Code:
42
43 (eval-when-compile (require 'cl))
44 (require 'rect) ;; kill-rectangle
45 (require 'iedit-lib)
46
47 (defvar iedit-rectangle-mode nil) ;; Name of the minor mode
48
49 (make-variable-buffer-local 'iedit-rectangle-mode)
50 (or (assq 'iedit-rectangle-mode minor-mode-alist)
51     (nconc minor-mode-alist
52            (list '(iedit-rectangle-mode iedit-rectangle-mode))))
53
54
55 ;;; Default key bindings:
56 (define-key global-map [C-return] 'iedit-rectangle-mode)
57
58 (defvar iedit-rectangle nil
59   "This buffer local variable which is the rectangle geometry if
60 current mode is iedit-rect. Otherwise it is nil.
61 \(car iedit-rectangle) is the top-left corner and
62 \(cadr iedit-rectangle) is the bottom-right corner" )
63
64 (make-variable-buffer-local 'iedit-rectangle)
65
66 ;;; Define Iedit rect mode map
67 (defvar iedit-rect-keymap
68   (let ((map (make-sparse-keymap)))
69     (set-keymap-parent map iedit-occurrence-keymap-default)
70     (define-key map (kbd "M-K") 'iedit-kill-rectangle)
71     map)
72   "Keymap used within overlays in Iedit-rect mode.")
73
74 (or (assq 'iedit-rectangle-mode minor-mode-map-alist)
75     (setq minor-mode-map-alist
76           (cons (cons 'iedit-rectangle-mode iedit-lib-keymap) minor-mode-map-alist)))
77
78
79 ;; Avoid to restore Iedit-rect mode when restoring desktop
80 (add-to-list 'desktop-minor-mode-handlers
81              '(iedit-rectangle-mode . nil))
82
83 ;;;###autoload
84 (defun iedit-rectangle-mode ()
85   "Toggle Iedit-rect mode.
86
87 When Iedit-rect mode is on, a rectangle is started with visible
88 rectangle highlighting.  Rectangle editing support is based on
89 Iedit mechanism.
90
91 Commands:
92 \\{iedit-rect-keymap}"
93   (interactive)
94   (if iedit-rectangle-mode
95       (iedit-rectangle-done)
96     (iedit-barf-if-lib-active)
97     (if (iedit-region-active)
98         (let ((beg (region-beginning))
99               (end (region-end)))
100           (setq mark-active nil)
101           (run-hooks 'deactivate-mark-hook)
102           (iedit-rectangle-start beg end)))))
103
104 (defun iedit-rectangle-start (beg end)
105   "Start Iedit mode for the region as a rectangle."
106   (barf-if-buffer-read-only)
107   (setq iedit-occurrences-overlays nil)
108   (setq iedit-rectangle (list beg end))
109   (setq iedit-initial-string-local nil)
110   (setq iedit-occurrence-keymap iedit-rect-keymap)
111   (save-excursion
112     (let ((beg-col (progn (goto-char beg) (current-column)))
113           (end-col (progn (goto-char end) (current-column))))
114       (when (< end-col beg-col)
115         (rotatef beg-col end-col))
116       (goto-char beg)
117       (loop do (progn
118                  (push (iedit-make-occurrence-overlay
119                         (progn
120                           (move-to-column beg-col t)
121                           (point))
122                         (progn
123                           (move-to-column end-col t)
124                           (point)))
125                        iedit-occurrences-overlays)
126                  (forward-line 1))
127             until (> (point) end))
128       (setq iedit-occurrences-overlays (nreverse iedit-occurrences-overlays))))
129   (setq iedit-rectangle-mode (propertize
130                     (concat " Iedit-rect:" (number-to-string (length iedit-occurrences-overlays)))
131                     'face 'font-lock-warning-face))
132   (force-mode-line-update)
133   (add-hook 'kbd-macro-termination-hook 'iedit-rectangle-done nil t)
134   (add-hook 'change-major-mode-hook 'iedit-rectangle-done nil t)
135   (add-hook 'iedit-aborting-hook 'iedit-rectangle-done nil t))
136
137 (defun iedit-rectangle-done ()
138   "Exit Iedit mode.
139 Save the current occurrence string locally and globally.  Save
140 the initial string globally."
141   (when iedit-buffering
142       (iedit-stop-buffering))
143   (iedit-cleanup)
144   (setq iedit-rectangle-mode nil)
145   (force-mode-line-update)
146   (remove-hook 'kbd-macro-termination-hook 'iedit-rectangle-done t)
147   (remove-hook 'change-major-mode-hook 'iedit-rectangle-done t)
148   (remove-hook 'iedit-aborting-hook 'iedit-rectangle-done t))
149
150 (defun iedit-kill-rectangle(&optional fill)
151   "Kill the rectangle.
152 The behavior is the same as `kill-rectangle' in rect mode."
153   (interactive "*P")
154   (or (and iedit-rectangle (iedit-same-column))
155       (error "Not a rectangle"))
156   (let ((inhibit-modification-hooks t)
157         (beg (overlay-start (car iedit-occurrences-overlays)))
158         (end (overlay-end (progn (iedit-last-occurrence)
159                                  (iedit-find-current-occurrence-overlay)))))
160     (kill-rectangle beg end fill)))
161
162 (provide 'iedit-rect)
163
164 ;;; iedit-rect.el ends here
165
166 ;;  LocalWords:  iedit el MERCHANTABILITY kbd isearch todo ert Lindberg Tassilo
167 ;;  LocalWords:  eval rect defgroup defcustom boolean defvar assq alist nconc
168 ;;  LocalWords:  substring cadr keymap defconst purecopy bkm defun princ prev
169 ;;  LocalWords:  iso lefttab backtab upcase downcase concat setq autoload arg
170 ;;  LocalWords:  refactoring propertize cond goto nreverse progn rotatef eq elp
171 ;;  LocalWords:  dolist pos unmatch args ov sReplace iedit's cdr quote'ed