GNU bug report logs - #8463
24.0.50; [PATCH] Direct Edit in *Occur* Buffer

Previous Next

Package: emacs;

Reported by: Leo <sdl.web <at> gmail.com>

Date: Sun, 10 Apr 2011 08:16:02 UTC

Severity: wishlist

Tags: patch

Found in version 24.0.50

Done: Chong Yidong <cyd <at> stupidchicken.com>

Bug is archived. No further changes may be made.

Full log


Message #47 received at 8463 <at> debbugs.gnu.org (full text, mbox):

From: Leo <sdl.web <at> gmail.com>
To: Glenn Morris <rgm <at> gnu.org>
Cc: Chong Yidong <cyd <at> stupidchicken.com>, 8463 <at> debbugs.gnu.org,
	Stefan Monnier <monnier <at> iro.umontreal.ca>,
	"Andrew W. Nosenko" <andrew.w.nosenko <at> gmail.com>
Subject: Re: bug#8463: 24.0.50; [PATCH] Direct Edit in *Occur* Buffer
Date: Thu, 09 Jun 2011 17:42:47 +0800
[Message part 1 (text/plain, inline)]
I think maybe we should assign C-c C-c to occur-edit-mode instead.

   1. After C-x C-q, I can no longer kill entire lines in the occur buffer.
   Trying to do so reports "Text is read-only".

The text properties are now added when entering occur-edit-mode.

   2. After C-x C-q, If I delete some text in the occur buffer, then use
   "undo", when I reach the point at which there is no more to undo, I get:
   "Wrong type argument: markerp, nil" rather than "No further undo information".

   Debugger entered--Lisp error: (wrong-type-argument markerp nil)
     marker-buffer(nil)
     occur-after-change-function(1 40 39)
     primitive-undo(1 ((nil font-lock-face underline 1 . 40) (t 0 . 0)))
     undo-more(1)
     undo(nil)
     call-interactively(undo nil nil)

Fixed.

   3. After C-x C-q, M-x revert-buffer in the occur buffer triggers an error

occur-revert-arguments is killed after any major-mode change. In the
patch this has been made permanent-local.

Comments welcome. Thanks.

[occur-edit.diff (text/x-diff, inline)]
=== modified file 'lisp/replace.el'
--- lisp/replace.el	2011-05-28 22:56:14 +0000
+++ lisp/replace.el	2011-06-09 09:28:09 +0000
@@ -826,6 +826,8 @@
 (defvar occur-revert-arguments nil
   "Arguments to pass to `occur-1' to revert an Occur mode buffer.
 See `occur-revert-function'.")
+(make-variable-buffer-local 'occur-revert-arguments)
+(put 'occur-revert-arguments 'permanent-local t)
 
 (defcustom occur-mode-hook '(turn-on-font-lock)
   "Hook run when entering Occur mode."
@@ -853,8 +855,6 @@
 
 \\{occur-mode-map}"
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
-  (make-local-variable 'occur-revert-arguments)
-  (add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
   (setq next-error-function 'occur-next-error))
 
 
@@ -865,7 +865,7 @@
     (set-keymap-parent map text-mode-map)
     (define-key map [mouse-2] 'occur-mode-mouse-goto)
     (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence)
-    (define-key map "\C-x\C-q" 'occur-mode)
+    (define-key map "\C-x\C-q" 'occur-edit-finish)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
     (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map))
     map)
@@ -878,40 +878,59 @@
 
 To return to ordinary Occur mode, use \\[occur-mode]."
   (setq buffer-read-only nil)
+  (put 'occur-noneditable 'read-only t)
+  (put 'occur-noneditable 'face 'shadow)
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (point-min))
+      (while (re-search-forward "^[ \t0-9]+:\\|\n" nil t)
+	(with-silent-modifications
+	  (put-text-property (match-beginning 0) (match-end 0)
+			     'category 'occur-noneditable)))))
   (add-hook 'after-change-functions 'occur-after-change-function nil t))
 
+(defun occur-edit-finish ()
+  (interactive)
+  (put 'occur-noneditable 'read-only nil)
+  (put 'occur-noneditable 'face nil)
+  (occur-mode))
+
 (defun occur-after-change-function (beg end length)
-  (save-excursion
-    (goto-char beg)
-    (let* ((m (get-text-property (line-beginning-position) 'occur-target))
-	   (buf (marker-buffer m))
-	   (col (current-column)))
-      (when (= length 0)
-	;; Apply occur-target property to inserted (e.g. yanked) text.
-	(put-text-property beg end 'occur-target m)
-	;; Did we insert a newline?  Occur Edit mode can't create new
-	;; Occur entries; just discard everything after the newline.
+  (let ((m (save-excursion
+	     (goto-char beg)
+	     (get-text-property (line-beginning-position) 'occur-target))))
+    (when (and (markerp m) (buffer-live-p (marker-buffer m)))
+      (when (zerop length)
 	(save-excursion
+	  ;; Apply occur-target property to inserted (e.g. yanked) text.
+	  (put-text-property beg end 'occur-target m)
+	  ;; Did we insert a newline?  Occur Edit mode can't create new
+	  ;; Occur entries; just discard everything after the newline.
+	  (goto-char beg)
 	  (and (search-forward "\n" end t)
 	       (delete-region (1- (point)) end))))
-      (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)))))
-	(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))))))
+      (save-excursion
+	(let* ((buf (marker-buffer m))
+	       (col (current-column))
+	       (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)))))
+	  (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)
@@ -1341,7 +1360,6 @@
 				      `(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,
@@ -1401,15 +1419,13 @@
 		(goto-char headerpt)
 		(let ((beg (point))
 		      end)
-		  (insert (propertize
-			   (format "%d match%s%s in buffer: %s\n"
-				   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))
+		  (insert (format "%d match%s%s in buffer: %s\n"
+				  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)))
 		  (setq end (point))
 		  (add-text-properties beg end
 				       (append


This bug report was last modified 13 years and 329 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.