summaryrefslogtreecommitdiff
path: root/iedit-rect.el
diff options
context:
space:
mode:
Diffstat (limited to 'iedit-rect.el')
-rw-r--r--iedit-rect.el188
1 files changed, 188 insertions, 0 deletions
diff --git a/iedit-rect.el b/iedit-rect.el
new file mode 100644
index 0000000..f12a632
--- /dev/null
+++ b/iedit-rect.el
@@ -0,0 +1,188 @@
+;;; iedit-rect.el --- visible rectangle editing support based on Iedit.
+
+;; Copyright (C) 2010, 2011, 2012 Victor Ren
+
+;; Time-stamp: <2016-09-28 00:03:47 Victor Ren>
+;; Author: Victor Ren <victorhge@gmail.com>
+;; Keywords: occurrence region simultaneous rectangle refactoring
+;; Version: 0.9.9
+;; X-URL: http://www.emacswiki.org/emacs/Iedit
+;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x
+
+;; This file is not part of GNU Emacs, but it is distributed under
+;; the same terms as GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package also provides rectangle support with *visible rectangle*
+;; highlighting, which is similar with cua-mode rectangle support. But it is
+;; lighter weight and uses iedit mechanisms.
+
+;; The code was developed and fully tested on Gnu Emacs 24.0.93, partially
+;; tested on Gnu Emacs 22. If you have any compatible problem, please let me
+;; know.
+
+;;; todo:
+;; - Add restrict function back
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'rect) ;; kill-rectangle
+(require 'iedit-lib)
+
+(defvar iedit-rectangle-mode nil) ;; Name of the minor mode
+
+(make-variable-buffer-local 'iedit-rectangle-mode)
+(or (assq 'iedit-rectangle-mode minor-mode-alist)
+ (nconc minor-mode-alist
+ (list '(iedit-rectangle-mode iedit-rectangle-mode))))
+
+
+;;; Default key bindings:
+(when (null (where-is-internal 'iedit-rectangle-mode))
+ (let ((key-def (lookup-key ctl-x-r-map "\r")))
+ (if key-def
+ (display-warning 'iedit (format "Iedit rect default key %S is occupied by %s."
+ (key-description [C-x r RET])
+ key-def)
+ :warning)
+ (define-key ctl-x-r-map "\r" 'iedit-rectangle-mode)
+ (message "Iedit-rect default key binding is %s" (key-description [C-x r RET])))))
+
+(defvar iedit-rectangle nil
+ "This buffer local variable which is the rectangle geometry if
+current mode is iedit-rect. Otherwise it is nil.
+\(car iedit-rectangle) is the top-left corner and
+\(cadr iedit-rectangle) is the bottom-right corner" )
+
+(make-variable-buffer-local 'iedit-rectangle)
+
+;;; Define Iedit rect mode map
+(defvar iedit-rect-keymap
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map iedit-occurrence-keymap-default)
+ (define-key map (kbd "M-K") 'iedit-kill-rectangle)
+ map)
+ "Keymap used within overlays in Iedit-rect mode.")
+
+(or (assq 'iedit-rectangle-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'iedit-rectangle-mode iedit-lib-keymap) minor-mode-map-alist)))
+
+
+;; Avoid to restore Iedit-rect mode when restoring desktop
+(add-to-list 'desktop-minor-mode-handlers
+ '(iedit-rectangle-mode . nil))
+
+;;;###autoload
+(defun iedit-rectangle-mode (&optional beg end)
+ "Toggle Iedit-rect mode.
+
+When Iedit-rect mode is on, a rectangle is started with visible
+rectangle highlighting. Rectangle editing support is based on
+Iedit mechanism.
+
+Commands:
+\\{iedit-rect-keymap}"
+ (interactive (when (iedit-region-active)
+ (list (region-beginning)
+ (region-end))))
+
+ ;; enforce skip modification once, errors may happen to cause this to be
+ ;; unset.
+ (setq iedit-skip-modification-once t)
+ (if iedit-rectangle-mode
+ (iedit-rectangle-done)
+ (iedit-barf-if-lib-active)
+ (if (and beg end)
+ (progn (setq mark-active nil)
+ (run-hooks 'deactivate-mark-hook)
+ (iedit-rectangle-start beg end))
+ (error "no region available."))))
+
+(defun iedit-rectangle-start (beg end)
+ "Start Iedit mode for the region as a rectangle."
+ (barf-if-buffer-read-only)
+ (setq beg (copy-marker beg))
+ (setq end (copy-marker end t))
+ (setq iedit-occurrences-overlays nil)
+ (setq iedit-initial-string-local nil)
+ (setq iedit-occurrence-keymap iedit-rect-keymap)
+ (save-excursion
+ (let ((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)
+ (while
+ (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)
+ (and (< (point) end) (forward-line 1))))))
+ (setq iedit-rectangle (list beg end))
+ (setq iedit-rectangle-mode
+ (propertize
+ (concat " Iedit-rect:"
+ (number-to-string (length iedit-occurrences-overlays)))
+ 'face
+ 'font-lock-warning-face))
+ (force-mode-line-update)
+ (add-hook 'before-revert-hook 'iedit-rectangle-done nil t)
+ (add-hook 'kbd-macro-termination-hook 'iedit-rectangle-done nil t)
+ (add-hook 'change-major-mode-hook 'iedit-rectangle-done nil t)
+ (add-hook 'iedit-aborting-hook 'iedit-rectangle-done nil t))
+
+(defun iedit-rectangle-done ()
+ "Exit Iedit mode.
+Save the current occurrence string locally and globally. Save
+the initial string globally."
+ (when iedit-buffering
+ (iedit-stop-buffering))
+ (iedit-cleanup)
+ (setq iedit-rectangle-mode nil)
+ (force-mode-line-update)
+ (remove-hook 'before-revert-hook 'iedit-rectangle-done t)
+ (remove-hook 'kbd-macro-termination-hook 'iedit-rectangle-done t)
+ (remove-hook 'change-major-mode-hook 'iedit-rectangle-done t)
+ (remove-hook 'iedit-aborting-hook 'iedit-rectangle-done t))
+
+(defun iedit-kill-rectangle(&optional fill)
+ "Kill the rectangle.
+The behavior is the same as `kill-rectangle' in rect mode."
+ (interactive "*P")
+ (or (and iedit-rectangle (iedit-same-column))
+ (error "Not a rectangle"))
+ (let ((inhibit-modification-hooks t))
+ (kill-rectangle (marker-position (car iedit-rectangle))
+ (marker-position (cadr iedit-rectangle)) fill)))
+
+(provide 'iedit-rect)
+
+;;; iedit-rect.el ends here
+
+;; LocalWords: iedit el MERCHANTABILITY kbd isearch todo ert Lindberg Tassilo
+;; LocalWords: eval rect defgroup defcustom boolean defvar assq alist nconc
+;; LocalWords: substring cadr keymap defconst purecopy bkm defun princ prev
+;; LocalWords: iso lefttab backtab upcase downcase concat setq autoload arg
+;; LocalWords: refactoring propertize cond goto nreverse progn rotatef eq elp
+;; LocalWords: dolist pos unmatch args ov sReplace iedit's cdr quote'ed