bug#8463: 24.0.50; [PATCH] Direct Edit in *Occur* Buffer

From: Leo Subject: bug#8463: 24.0.50; [PATCH] Direct Edit in *Occur* Buffer Date: Sun, 10 Apr 2011 16:14:53 +0800

I have extended the occur feature in Emacs to allow direct editing in the *Occur* buffer by propagating the changes to the original buffers. With the attached preliminary patch, one can press `C-x C-q' or `C-c C-c' to enter occur-edit-mode and start editing. Pressing `C-x C-q' or `C-c C-c' again finishes the edit. Comments are highly welcomed. Thanks in advance. Leo

=== modified file 'lisp/replace.el' --- lisp/replace.el 2011-04-08 03:05:58 +0000 +++ lisp/replace.el 2011-04-10 08:02:15 +0000 @@ -761,7 +761,8 @@ (let ((map (make-sparse-keymap))) ;; We use this alternative name, so we can use \\[occur-mode-mouse-goto]. (define-key map [mouse-2] 'occur-mode-mouse-goto) - (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence) + (define-key map "\C-c\C-c" 'occur-edit-mode) + (define-key map "\C-x\C-q" 'occur-edit-mode) (define-key map "\C-m" 'occur-mode-goto-occurrence) (define-key map "o" 'occur-mode-goto-occurrence-other-window) (define-key map "\C-o" 'occur-mode-display-occurrence) @@ -815,6 +816,18 @@ map) "Keymap for `occur-mode'.") +(defvar occur-edit-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-2] 'occur-mode-mouse-goto) + (define-key map "\C-c\C-c" 'occur-edit-mode-finish) + (define-key map "\C-x\C-q" 'occur-edit-mode-finish) + (define-key map "\C-m" 'occur-mode-goto-occurrence) + (define-key map "\C-o" 'occur-mode-display-occurrence) + (define-key map "\M-n" 'occur-next) + (define-key map "\M-p" 'occur-prev) + (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) + map)) + (defvar occur-revert-arguments nil "Arguments to pass to `occur-1' to revert an Occur mode buffer. See `occur-revert-function'.") @@ -849,6 +862,59 @@ (add-hook 'change-major-mode-hook 'font-lock-defontify nil t) (setq next-error-function 'occur-next-error)) +(defun occur-edit-mode () + (interactive) + (setq buffer-read-only nil) + (use-local-map occur-edit-mode-map) + (setq major-mode 'occur-edit-mode + mode-name "Occur-Edit") + (add-hook 'after-change-functions 'occur-after-change-function nil t) + (force-mode-line-update)) + +(defvar occur-edit-modified-buffers nil) +(make-variable-buffer-local 'occur-edit-modified-buffers) + +(defun occur-edit-mode-finish () + (interactive) + (mapc (lambda (buf) + (and (buffer-file-name buf) + (with-current-buffer buf + (save-buffer)))) + occur-edit-modified-buffers) + (setq buffer-read-only t) + (kill-local-variable 'occur-edit-modified-buffers) + (remove-hook 'after-change-functions 'occur-after-change-function t) + (set-buffer-modified-p nil) + (use-local-map occur-mode-map) + (setq major-mode 'occur-mode + mode-name "Occur")) + +(defun occur-after-change-function (beg end length) + (let* ((m (get-text-property (point) 'occur-target)) + (buf (marker-buffer m)) + (col (current-column))) + (when (and (markerp m) (buffer-live-p buf)) + (let ((line (- (line-number-at-pos) + (line-number-at-pos (window-start)))) + (readonly (with-current-buffer buf buffer-read-only)) + (win (or (get-buffer-window buf) + (display-buffer buf t))) + (text (save-excursion + (forward-line 0) + (search-forward ":" nil t) + (setq col (- col (current-column))) + (buffer-substring-no-properties (point) (line-end-position))))) + (and (not readonly) + (add-to-list 'occur-edit-modified-buffers buf)) + (with-selected-window win + (goto-char m) + (recenter line) + (if readonly + (message "Buffer `%s' is read only." buf) + (delete-region (line-beginning-position) (line-end-position)) + (insert text)) + (move-to-column col)))))) + (defun occur-revert-function (ignore1 ignore2) "Handle `revert-buffer' for Occur mode buffers." (apply 'occur-1 (append occur-revert-arguments (list (buffer-name))))) @@ -1273,6 +1339,7 @@ `(font-lock-face prefix-face)) `(occur-prefix t mouse-face (highlight) occur-target ,marker follow-link t + read-only t help-echo "mouse-2: go to this occurrence")))) (match-str ;; We don't put `mouse-face' on the newline, @@ -1333,13 +1400,15 @@ (goto-char headerpt) (let ((beg (point)) end) - (insert (format "%d match%s%s in buffer: %s

" - matches (if (= matches 1) "" "es") - ;; Don't display regexp for multi-buffer. - (if (> (length buffers) 1) - "" (format " for \"%s\"" - (query-replace-descr regexp))) - (buffer-name buf))) + (insert (propertize + (format "%d match%s%s in buffer: %s

" + matches (if (= matches 1) "" "es") + ;; Don't display regexp for multi-buffer. + (if (> (length buffers) 1) + "" (format " for \"%s\"" + (query-replace-descr regexp))) + (buffer-name buf)) + 'read-only t)) (setq end (point)) (add-text-properties beg end (append

reply via email to



[Prev in Thread] Current Thread [Next in Thread]