Subject: bug#4896: Doc-view-mode with View-mode

From: Juri Linkov <[email-masked]>
Date: Tue, 02 Feb 2010 01:30:37 +0200

>>     (set (make-local-variable 'view-read-only) nil)
>
> This still doesn't work in all cases.  Typing `v' on a PDF file in Dired
> activates View-mode (I type RET in Dired when the intention is to *edit*
> the file, and type `v' when the intention is to *view* the file).
>
> Doc-view-mode has no chance to disable view-mode, because view-file
> (called from dired-view-file) at first visits the file with
> find-file-noselect that enables doc-view-mode, and after that
> view-file enables view-mode.
>
> View-file doesn't enable view-mode only when the property `mode-class' is
> `special'.  Actually lisp/doc-view.el already contains the necessary line,
> but it is commented out:
>
> ;; (put 'doc-view-mode 'mode-class 'special)
>
> I wonder what was the reason for commenting this out?

Stefan, do you remember why you commented out this line?

When `doc-view-mode' has this `mode-class' property, then
viewing a PDF file from Dired doesn't activates View-mode.
(And setting `view-read-only' to nil is not necessary anymore.)

Also I discovered another case: visiting a PDF file from a tar archive
activates View-mode, because `tar-extract' tries to mimic `view-file'
but ignores the `mode-class' property.  The patch below fixes this bug
for tar-mode.el by duplicating more code from `view-file'.

After feature freeze this duplicate code could be moved
from `view-file' to `view-buffer'.

=== modified file 'lisp/doc-view.el'
--- lisp/doc-view.el	2010-02-01 18:25:47 +0000
+++ lisp/doc-view.el	2010-02-01 23:01:10 +0000
@@ -1124,7 +1124,7 @@ (defun doc-view-search-previous-match (a
 
 ;;;; User interface commands and the mode
 
-;; (put 'doc-view-mode 'mode-class 'special)
+(put 'doc-view-mode 'mode-class 'special)
 
 (defun doc-view-already-converted-p ()
   "Return non-nil if the current doc was already converted."
@@ -1302,7 +1302,7 @@ (defun doc-view-mode ()
     ;; canonical view mode for PDF/PS/DVI files.  This could be
     ;; switched on automatically depending on the value of
     ;; `view-read-only'.
-    (set (make-local-variable 'view-read-only) nil)
+    ;; (set (make-local-variable 'view-read-only) nil)
     (run-mode-hooks 'doc-view-mode-hook)))
 
 ;;;###autoload

=== modified file 'lisp/tar-mode.el'
--- lisp/tar-mode.el	2010-01-13 08:35:10 +0000
+++ lisp/tar-mode.el	2010-02-01 23:01:10 +0000
@@ -852,14 +852,23 @@ (defun tar-extract (&optional other-wind
           (set (make-local-variable 'tar-superior-descriptor) descriptor)
           (setq buffer-read-only read-only-p)
           (tar-subfile-mode 1)))
-      (if view-p
-	  (view-buffer
-	   buffer (and just-created 'kill-buffer-if-not-modified))
-	(if (eq other-window-p 'display)
-	    (display-buffer buffer)
-	  (if other-window-p
-	      (switch-to-buffer-other-window buffer)
-	    (switch-to-buffer buffer)))))))
+      (cond
+       (view-p
+	;; FIXME: code duplicated from `view-file', perhaps the test for special
+	;; mode-class should be moved from `view-file' to `view-buffer'.  (Bug#4896)
+	(if (eq (with-current-buffer buffer
+		  (get major-mode 'mode-class))
+		'special)
+	    (progn
+	      (switch-to-buffer buffer)
+	      (message "Not using View mode because the major mode is special"))
+	  (view-buffer buffer (and just-created 'kill-buffer-if-not-modified))))
+       ((eq other-window-p 'display)
+	(display-buffer buffer))
+       (other-window-p
+	(switch-to-buffer-other-window buffer))
+       (t
+	(switch-to-buffer buffer))))))

 (defun tar-extract-other-window ()

-- 
Juri Linkov
http://www.jurta.org/emacs/