Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
6.9 KiB

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