diff options
| author | Leo Liu | 2011-05-28 18:56:14 -0400 |
|---|---|---|
| committer | Chong Yidong | 2011-05-28 18:56:14 -0400 |
| commit | 60e565234624f6c38920d233fafabd05c69eddfe (patch) | |
| tree | 2fdcafe3173b1bde5a8c04770d0eb2d2882193e4 /lisp/replace.el | |
| parent | 4ac619f07bc6d7560a04f5aa505c6ef084975d93 (diff) | |
| download | emacs-60e565234624f6c38920d233fafabd05c69eddfe.tar.gz emacs-60e565234624f6c38920d233fafabd05c69eddfe.zip | |
New major mode: Occur Edit mode.
* lisp/replace.el (occur-menu-map, occur-edit-mode-map): New vars.
(occur-mode-map): Bind occur-edit-mode. Use occur-menu-map.
(occur-edit-mode): New major mode (Bug#8463).
(occur-after-change-function): New function.
(occur-engine): Give Occur tags a read-only property.
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 108 |
1 files changed, 86 insertions, 22 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index 31a48d48960..0578ed09b1c 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -761,22 +761,8 @@ a previously found match." | |||
| 761 | count))) | 761 | count))) |
| 762 | 762 | ||
| 763 | 763 | ||
| 764 | (defvar occur-mode-map | 764 | (defvar occur-menu-map |
| 765 | (let ((map (make-sparse-keymap))) | 765 | (let ((map (make-sparse-keymap))) |
| 766 | ;; We use this alternative name, so we can use \\[occur-mode-mouse-goto]. | ||
| 767 | (define-key map [mouse-2] 'occur-mode-mouse-goto) | ||
| 768 | (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence) | ||
| 769 | (define-key map "\C-m" 'occur-mode-goto-occurrence) | ||
| 770 | (define-key map "o" 'occur-mode-goto-occurrence-other-window) | ||
| 771 | (define-key map "\C-o" 'occur-mode-display-occurrence) | ||
| 772 | (define-key map "\M-n" 'occur-next) | ||
| 773 | (define-key map "\M-p" 'occur-prev) | ||
| 774 | (define-key map "r" 'occur-rename-buffer) | ||
| 775 | (define-key map "c" 'clone-buffer) | ||
| 776 | (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) | ||
| 777 | (define-key map [menu-bar] (make-sparse-keymap)) | ||
| 778 | (define-key map [menu-bar occur] | ||
| 779 | (cons (purecopy "Occur") map)) | ||
| 780 | (define-key map [next-error-follow-minor-mode] | 766 | (define-key map [next-error-follow-minor-mode] |
| 781 | `(menu-item ,(purecopy "Auto Occurrence Display") | 767 | `(menu-item ,(purecopy "Auto Occurrence Display") |
| 782 | next-error-follow-minor-mode | 768 | next-error-follow-minor-mode |
| @@ -817,6 +803,24 @@ a previously found match." | |||
| 817 | `(menu-item ,(purecopy "Move to Previous Match") occur-prev | 803 | `(menu-item ,(purecopy "Move to Previous Match") occur-prev |
| 818 | :help ,(purecopy "Move to the Nth (default 1) previous match in an Occur mode buffer"))) | 804 | :help ,(purecopy "Move to the Nth (default 1) previous match in an Occur mode buffer"))) |
| 819 | map) | 805 | map) |
| 806 | "Menu keymap for `occur-mode'.") | ||
| 807 | |||
| 808 | (defvar occur-mode-map | ||
| 809 | (let ((map (make-sparse-keymap))) | ||
| 810 | ;; We use this alternative name, so we can use \\[occur-mode-mouse-goto]. | ||
| 811 | (define-key map [mouse-2] 'occur-mode-mouse-goto) | ||
| 812 | (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence) | ||
| 813 | (define-key map "\C-x\C-q" 'occur-edit-mode) | ||
| 814 | (define-key map "\C-m" 'occur-mode-goto-occurrence) | ||
| 815 | (define-key map "o" 'occur-mode-goto-occurrence-other-window) | ||
| 816 | (define-key map "\C-o" 'occur-mode-display-occurrence) | ||
| 817 | (define-key map "\M-n" 'occur-next) | ||
| 818 | (define-key map "\M-p" 'occur-prev) | ||
| 819 | (define-key map "r" 'occur-rename-buffer) | ||
| 820 | (define-key map "c" 'clone-buffer) | ||
| 821 | (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) | ||
| 822 | (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map)) | ||
| 823 | map) | ||
| 820 | "Keymap for `occur-mode'.") | 824 | "Keymap for `occur-mode'.") |
| 821 | 825 | ||
| 822 | (defvar occur-revert-arguments nil | 826 | (defvar occur-revert-arguments nil |
| @@ -853,6 +857,63 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it. | |||
| 853 | (add-hook 'change-major-mode-hook 'font-lock-defontify nil t) | 857 | (add-hook 'change-major-mode-hook 'font-lock-defontify nil t) |
| 854 | (setq next-error-function 'occur-next-error)) | 858 | (setq next-error-function 'occur-next-error)) |
| 855 | 859 | ||
| 860 | |||
| 861 | ;;; Occur Edit mode | ||
| 862 | |||
| 863 | (defvar occur-edit-mode-map | ||
| 864 | (let ((map (make-sparse-keymap))) | ||
| 865 | (set-keymap-parent map text-mode-map) | ||
| 866 | (define-key map [mouse-2] 'occur-mode-mouse-goto) | ||
| 867 | (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence) | ||
| 868 | (define-key map "\C-x\C-q" 'occur-mode) | ||
| 869 | (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) | ||
| 870 | (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map)) | ||
| 871 | map) | ||
| 872 | "Keymap for `occur-edit-mode'.") | ||
| 873 | |||
| 874 | (define-derived-mode occur-edit-mode occur-mode "Occur-Edit" | ||
| 875 | "Major mode for editing *Occur* buffers. | ||
| 876 | In this mode, changes to the *Occur* buffer are also applied to | ||
| 877 | the originating buffer. | ||
| 878 | |||
| 879 | To return to ordinary Occur mode, use \\[occur-mode]." | ||
| 880 | (setq buffer-read-only nil) | ||
| 881 | (add-hook 'after-change-functions 'occur-after-change-function nil t)) | ||
| 882 | |||
| 883 | (defun occur-after-change-function (beg end length) | ||
| 884 | (save-excursion | ||
| 885 | (goto-char beg) | ||
| 886 | (let* ((m (get-text-property (line-beginning-position) 'occur-target)) | ||
| 887 | (buf (marker-buffer m)) | ||
| 888 | (col (current-column))) | ||
| 889 | (when (= length 0) | ||
| 890 | ;; Apply occur-target property to inserted (e.g. yanked) text. | ||
| 891 | (put-text-property beg end 'occur-target m) | ||
| 892 | ;; Did we insert a newline? Occur Edit mode can't create new | ||
| 893 | ;; Occur entries; just discard everything after the newline. | ||
| 894 | (save-excursion | ||
| 895 | (and (search-forward "\n" end t) | ||
| 896 | (delete-region (1- (point)) end)))) | ||
| 897 | (let ((line (- (line-number-at-pos) | ||
| 898 | (line-number-at-pos (window-start)))) | ||
| 899 | (readonly (with-current-buffer buf buffer-read-only)) | ||
| 900 | (win (or (get-buffer-window buf) | ||
| 901 | (display-buffer buf t))) | ||
| 902 | (text (save-excursion | ||
| 903 | (forward-line 0) | ||
| 904 | (search-forward ":" nil t) | ||
| 905 | (setq col (- col (current-column))) | ||
| 906 | (buffer-substring-no-properties (point) (line-end-position))))) | ||
| 907 | (with-selected-window win | ||
| 908 | (goto-char m) | ||
| 909 | (recenter line) | ||
| 910 | (if readonly | ||
| 911 | (message "Buffer `%s' is read only." buf) | ||
| 912 | (delete-region (line-beginning-position) (line-end-position)) | ||
| 913 | (insert text)) | ||
| 914 | (move-to-column col)))))) | ||
| 915 | |||
| 916 | |||
| 856 | (defun occur-revert-function (_ignore1 _ignore2) | 917 | (defun occur-revert-function (_ignore1 _ignore2) |
| 857 | "Handle `revert-buffer' for Occur mode buffers." | 918 | "Handle `revert-buffer' for Occur mode buffers." |
| 858 | (apply 'occur-1 (append occur-revert-arguments (list (buffer-name))))) | 919 | (apply 'occur-1 (append occur-revert-arguments (list (buffer-name))))) |
| @@ -1280,6 +1341,7 @@ See also `multi-occur'." | |||
| 1280 | `(font-lock-face prefix-face)) | 1341 | `(font-lock-face prefix-face)) |
| 1281 | `(occur-prefix t mouse-face (highlight) | 1342 | `(occur-prefix t mouse-face (highlight) |
| 1282 | occur-target ,marker follow-link t | 1343 | occur-target ,marker follow-link t |
| 1344 | read-only t | ||
| 1283 | help-echo "mouse-2: go to this occurrence")))) | 1345 | help-echo "mouse-2: go to this occurrence")))) |
| 1284 | (match-str | 1346 | (match-str |
| 1285 | ;; We don't put `mouse-face' on the newline, | 1347 | ;; We don't put `mouse-face' on the newline, |
| @@ -1339,13 +1401,15 @@ See also `multi-occur'." | |||
| 1339 | (goto-char headerpt) | 1401 | (goto-char headerpt) |
| 1340 | (let ((beg (point)) | 1402 | (let ((beg (point)) |
| 1341 | end) | 1403 | end) |
| 1342 | (insert (format "%d match%s%s in buffer: %s\n" | 1404 | (insert (propertize |
| 1343 | matches (if (= matches 1) "" "es") | 1405 | (format "%d match%s%s in buffer: %s\n" |
| 1344 | ;; Don't display regexp for multi-buffer. | 1406 | matches (if (= matches 1) "" "es") |
| 1345 | (if (> (length buffers) 1) | 1407 | ;; Don't display regexp for multi-buffer. |
| 1346 | "" (format " for \"%s\"" | 1408 | (if (> (length buffers) 1) |
| 1347 | (query-replace-descr regexp))) | 1409 | "" (format " for \"%s\"" |
| 1348 | (buffer-name buf))) | 1410 | (query-replace-descr regexp))) |
| 1411 | (buffer-name buf)) | ||
| 1412 | 'read-only t)) | ||
| 1349 | (setq end (point)) | 1413 | (setq end (point)) |
| 1350 | (add-text-properties beg end | 1414 | (add-text-properties beg end |
| 1351 | (append | 1415 | (append |