emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Refreshing Info nodes


From: Wojciech Meyer
Subject: Re: Refreshing Info nodes
Date: Mon, 13 Sep 2010 02:34:05 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50

Stefan Monnier <address@hidden> writes:

Thanks for it, below is my update:

>> Now there was some problem with buffer local variable
>> `revert-buffer-function'. (in doc-view-mode) I corrected it I believe,
>> and this is the final version of patch.  Could anybody review that once
>> more, please?
>
> Some nitpicks:
>
>> +  ;; This is not interactive because you shouldn't be turning this
>> +  ;; mode on and off.  You can corrupt things that way.
>> +  ;;
>> +  ;; Now it's derived mode, so therefore it is interactive.
>
> These two pieces are contradictory, please clarify.  BTW, we should
> change archive-mode to use buffer-swap-text like we did for tar-mode,
> which should address this risk of corruption.

Done. I am investigating possibility of using swap-buffer with
archive-mode. This is not done yet, so you might consider not applying
diffs to `arc-mode.el' (however I am planning to fix it ASAP too..)

BTW: Maybe we should think about merging (at least reusing bits & pieces
and making user interface more consistent) tar-mode <-> archive-mode?

>
>> -(defun bookmark-bmenu-mode ()
>> +(define-derived-mode bookmark-bmenu-mode special-mode "Bookmark Menu"
>>    "Major mode for editing a list of bookmarks.
>>  Each line describes one of the bookmarks in Emacs.
>>  Letters do not insert themselves; instead, they are commands.
>> @@ -1645,9 +1642,6 @@
>>    (kill-all-local-variables)
>>    (use-local-map bookmark-bmenu-mode-map)
>
> Both kill-all-local-variables and use-local-map can be removed (actually
> kill-all-local-variables *has* to be removed since it undoes the previous
> call to special-mode).

Done.

>
>>    (setq truncate-lines t)
>> -  (setq buffer-read-only t)
>> -  (setq major-mode 'bookmark-bmenu-mode)
>> -  (setq mode-name "Bookmark Menu")
>>    (run-mode-hooks 'bookmark-bmenu-mode-hook))
>
> Why remove (setq buffer-read-only t) ?
> And why not remove the run-mode-hooks?

Done.

>
>> === modified file 'lisp/doc-view.el'
>> --- lisp/doc-view.el 2010-07-14 15:57:54 +0000
>> +++ lisp/doc-view.el 2010-08-29 15:08:39 +0000
>> @@ -333,7 +333,6 @@
>>      (define-key map (kbd "C-c C-t")   'doc-view-open-text)
>>      ;; Reconvert the current document.  Don't just use revert-buffer
>>      ;; because that resets the scale factor, the page number, ...
>> -    (define-key map (kbd "g")         'doc-view-revert-buffer)
>
> If you remove this line, you need to remove the above comment as well
> (after making sure that the problem it mentions don't apply any more).
>

Done. However for some reasons I am not able to revert the buffer with
"g" (and not sure why, AFAIK I could do it before, investigating)
That's why I've left "g" as 'revert-buffer.

BTW:
    (let* ((prev-major-mode (if (eq major-mode 'doc-view-mode)
                                doc-view-previous-major-mode
                              major-mode)))
      (set (make-local-variable 'doc-view-previous-major-mode)
    prev-major-mode))

Here is code sensitive on previous major mode, please see comments
below.

Also, there is some problem with reverting itself:
it shows error message: `doc-view-revert-buffer: Variable binding depth
exceeds max-specpdl-size'. Did anybody notice something similar? (emacs
-Q, bzr trunk rev 101406).
        

>> +    (set (make-local-variable 'revert-buffer-function) 
>> 'doc-view-revert-buffer)
>>      (run-mode-hooks 'doc-view-mode-hook)))
>
> Here as well you should remove the run-mode-hooks.
>
>>  ;;;###autoload
>> -(defun image-mode ()
>> +(define-derived-mode image-mode special-mode "Image"
>>    "Major mode for image files.
>>  You can use \\<image-mode-map>\\[image-toggle-display]
>>  to toggle between display as an image and display as text."
>> -  (interactive)
>>    (condition-case err
>>        (progn
>>      (unless (display-images-p)
>>        (error "Display does not support images"))
>  
>>      (kill-all-local-variables)
>> -    (setq major-mode 'image-mode)
>
> IIRC define-derived-mode sets major-mode before running the body of the
> macro, so when you call `error' above, `major-mode' and `mode-name' have
> already been set and need to be reverted.

This could be accomplished by either:
- change to `derived.el', saving previous mode (this might be useful),
- change to `derived.el' by being reactive on exception (which is
valuable anyway, but there should be a way of telling to re-throw it).
- changing `image-mode' to something else and wrapping the rest into
`defun' (ad-hoc solution, which I like at least)
- having a flag that body should be executed before or after the body
generated by `define-derived-mode', or having a key, similar to
defadvice, (I wonder if EIEIO could help doing all of this..).

Ideally in case of saving previous mode we should have a stack for this
(even better, stack with functions that restore previous state, but this
might be an overkill).

I left it alone for time being, as the only drawback that user will
need to revert the mode by herself.

>
>> -(defun occur-mode ()
>> +(define-derived-mode occur-mode special-mode "Occur"
>>    "Major mode for output from \\[occur].
>>  \\<occur-mode-map>Move point to one of the items in this buffer, then use
>>  \\[occur-mode-goto-occurrence] to go to the occurrence that the item refers 
>> to.
>>  Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
>  
>>  \\{occur-mode-map}"
>> -  (interactive)
>>    (kill-all-local-variables)
>>    (use-local-map occur-mode-map)
>
> These last two should disappear as mentioned earlier.
>
>

Done.

BTW: Shall we have a special keyword for `derived-mode' that could possibly put 
together
default keyboard-map with mode (or allow user to use existing
keyboard-map), that would make developing new major modes more
consistent:

(define-derived-mode my-major-mode special-mode 
                                  :keymap 
                                  (("n" . 'my-next-page)
                                   ("C-s" . 'my-search))
                                   ...)
or

(define-derived-mode my-major-mode special-mode 
                                  :keymap 'my-major-mode-map
                                   ...)

AFAIK there is `configuration by convention' (post-fix `-map') but IMHO
it would be nicer if the keymaps could be defined in the body of the
macro. (and possibly merged with derive-mode-set-keymap). Maybe even we
can consider, generating a separate function for user init code (the
body of `define-derived-mode').

As you notice I also think that defining key-maps should be easier.
Generally maybe we should do what's been done with `easy-menu' for maps.

For convenience I am attaching set of patches each file separately, as
they are independent.

>         Stefan

Thanks,
Wojciech

=== modified file 'lisp/arc-mode.el'
--- lisp/arc-mode.el    2010-07-10 18:52:53 +0000
+++ lisp/arc-mode.el    2010-09-13 00:49:20 +0000
@@ -341,7 +341,6 @@
 (defvar archive-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map)
-    (define-key map " " 'archive-next-line)
     (define-key map "a" 'archive-alternate-display)
     ;;(define-key map "c" 'archive-copy)
     (define-key map "d" 'archive-flag-deleted)
@@ -349,15 +348,12 @@
     (define-key map "e" 'archive-extract)
     (define-key map "f" 'archive-extract)
     (define-key map "\C-m" 'archive-extract)
-    (define-key map "g" 'revert-buffer)
-    (define-key map "h" 'describe-mode)
     (define-key map "m" 'archive-mark)
     (define-key map "n" 'archive-next-line)
     (define-key map "\C-n" 'archive-next-line)
     (define-key map [down] 'archive-next-line)
     (define-key map "o" 'archive-extract-other-window)
     (define-key map "p" 'archive-previous-line)
-    (define-key map "q" 'quit-window)
     (define-key map "\C-p" 'archive-previous-line)
     (define-key map [up] 'archive-previous-line)
     (define-key map "r" 'archive-rename-entry)
@@ -632,31 +628,16 @@
                (error "Entry is not a regular member of the archive"))))
       (if (not noerror)
           (error "Line does not describe a member of the archive")))))
-;; -------------------------------------------------------------------------
-;;; Section: the mode definition
-
-;;;###autoload
-(defun archive-mode (&optional force)
-  "Major mode for viewing an archive file in a dired-like way.
-You can move around using the usual cursor motion commands.
-Letters no longer insert themselves.
-Type `e' to pull a file out of the archive and into its own buffer;
-or click mouse-2 on the file's line in the archive mode buffer.
-
-If you edit a sub-file of this archive (as with the `e' command) and
-save it, the contents of that buffer will be saved back into the
-archive.
-
-\\{archive-mode-map}"
-  ;; This is not interactive because you shouldn't be turning this
-  ;; mode on and off.  You can corrupt things that way.
+
+(defun archive-setup-mode (&optional force)
+  "Wrap all the mode setup code into separate function callable from 
+the package code."
   (if (zerop (buffer-size))
       ;; At present we cannot create archives from scratch
       (funcall (or (default-value 'major-mode) 'fundamental-mode))
     (if (and (not force) archive-files) nil
       (let* ((type (archive-find-type))
             (typename (capitalize (symbol-name type))))
-       (kill-all-local-variables)
        (make-local-variable 'archive-subtype)
        (setq archive-subtype type)
 
@@ -701,8 +682,7 @@
        (setq major-mode 'archive-mode)
        (setq mode-name (concat typename "-Archive"))
        ;; Run archive-foo-mode-hook and archive-mode-hook
-       (run-mode-hooks (archive-name "mode-hook") 'archive-mode-hook)
-       (use-local-map archive-mode-map))
+       (run-mode-hooks (archive-name "mode-hook") 'archive-mode-hook))
 
       (make-local-variable 'archive-proper-file-start)
       (make-local-variable 'archive-file-list-start)
@@ -717,6 +697,30 @@
       (archive-summarize nil)
       (setq buffer-read-only t))))
 
+;; -------------------------------------------------------------------------
+;;; Section: the mode definition
+
+;;;###autoload
+(define-derived-mode archive-mode special-mode "Archive mode"
+  "Major mode for viewing an archive file in a dired-like way.
+You can move around using the usual cursor motion commands.
+Letters no longer insert themselves.
+Type `e' to pull a file out of the archive and into its own buffer;
+or click mouse-2 on the file's line in the archive mode buffer.
+
+If you edit a sub-file of this archive (as with the `e' command) and
+save it, the contents of that buffer will be saved back into the
+archive.
+
+\\{archive-mode-map}"
+  ;; This is not interactive because you shouldn't be turning this
+  ;; mode on and off.  You can corrupt things that way.
+  ;;
+  ;; Now it's derived mode, so therefore it is interactive.
+  ;;
+  (archive-setup-mode))
+  
+
 ;; Archive mode is suitable only for specially formatted data.
 (put 'archive-mode 'mode-class 'special)
 
@@ -888,7 +892,7 @@
          (setq archive-files nil)
          (erase-buffer)
          (insert-file-contents name)
-         (archive-mode t)
+         (archive-setup-mode t)
          (goto-char archive-file-list-start)
          (archive-next-line lno))
        (archive-delete-local name)
@@ -1396,7 +1400,7 @@
     (let ((revert-buffer-function nil)
          (coding-system-for-read 'no-conversion))
       (revert-buffer t t))
-    (archive-mode)
+    (archive-setup-mode)
     (goto-char archive-file-list-start)
     (archive-next-line no)))
 

=== modified file 'lisp/bookmark.el'
--- lisp/bookmark.el    2010-07-14 19:09:28 +0000
+++ lisp/bookmark.el    2010-09-13 01:08:20 +0000
@@ -853,29 +853,22 @@
     (define-key map "\C-c\C-c" 'bookmark-send-edited-annotation)
     map)
   "Keymap for editing an annotation of a bookmark.")
-
-
-(defun bookmark-edit-annotation-mode (bookmark)
+ 
+(define-derived-mode bookmark-edit-annotation-mode nil "Edit Bookmark 
Annotation"
   "Mode for editing the annotation of bookmark BOOKMARK.
 When you have finished composing, type \\[bookmark-send-annotation].
 
 BOOKMARK is a bookmark name (a string) or a bookmark record.
 
 \\{bookmark-edit-annotation-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
+  (use-local-map bookmark-edit-annotation-mode-map)
   (make-local-variable 'bookmark-annotation-name)
-  (setq bookmark-annotation-name bookmark)
-  (use-local-map bookmark-edit-annotation-mode-map)
-  (setq major-mode 'bookmark-edit-annotation-mode
-        mode-name "Edit Bookmark Annotation")
   (insert (funcall bookmark-edit-annotation-text-func bookmark))
   (let ((annotation (bookmark-get-annotation bookmark)))
     (if (and annotation (not (string-equal annotation "")))
        (insert annotation)))
   (run-mode-hooks 'text-mode-hook))
 
-
 (defun bookmark-send-edited-annotation ()
   "Use buffer contents as annotation for a bookmark.
 Lines beginning with `#' are ignored."
@@ -901,8 +894,8 @@
   "Pop up a buffer for editing bookmark BOOKMARK's annotation.
 BOOKMARK is a bookmark name (a string) or a bookmark record."
   (pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*"))
-  (bookmark-edit-annotation-mode bookmark))
-
+  (bookmark-edit-annotation-mode)
+  (setq bookmark-annotation-name bookmark))
 
 (defun bookmark-insert-current-bookmark ()
   "Insert into the bookmark name currently being set the value of
@@ -1499,7 +1492,6 @@
 (defvar bookmark-bmenu-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map t)
-    (define-key map "q" 'quit-window)
     (define-key map "v" 'bookmark-bmenu-select)
     (define-key map "w" 'bookmark-bmenu-locate)
     (define-key map "2" 'bookmark-bmenu-2-window)
@@ -1515,11 +1507,9 @@
     (define-key map "\C-d" 'bookmark-bmenu-delete-backwards)
     (define-key map "x" 'bookmark-bmenu-execute-deletions)
     (define-key map "d" 'bookmark-bmenu-delete)
-    (define-key map " " 'next-line)
     (define-key map "n" 'next-line)
     (define-key map "p" 'previous-line)
     (define-key map "\177" 'bookmark-bmenu-backup-unmark)
-    (define-key map "?" 'describe-mode)
     (define-key map "u" 'bookmark-bmenu-unmark)
     (define-key map "m" 'bookmark-bmenu-mark)
     (define-key map "l" 'bookmark-bmenu-load)
@@ -1609,7 +1599,7 @@
 
 
 
-(defun bookmark-bmenu-mode ()
+(define-derived-mode bookmark-bmenu-mode special-mode "Bookmark Menu"
   "Major mode for editing a list of bookmarks.
 Each line describes one of the bookmarks in Emacs.
 Letters do not insert themselves; instead, they are commands.
@@ -1642,13 +1632,8 @@
   in another buffer.
 \\[bookmark-bmenu-show-all-annotations] -- show the annotations of all 
bookmarks in another buffer.
 \\[bookmark-bmenu-edit-annotation] -- edit the annotation for the current 
bookmark."
-  (kill-all-local-variables)
-  (use-local-map bookmark-bmenu-mode-map)
-  (setq truncate-lines t)
   (setq buffer-read-only t)
-  (setq major-mode 'bookmark-bmenu-mode)
-  (setq mode-name "Bookmark Menu")
-  (run-mode-hooks 'bookmark-bmenu-mode-hook))
+  (setq truncate-lines t))
 
 
 (defun bookmark-bmenu-toggle-filenames (&optional show)

=== modified file 'lisp/doc-view.el'
--- lisp/doc-view.el    2010-07-14 15:57:54 +0000
+++ lisp/doc-view.el    2010-09-13 00:13:30 +0000
@@ -331,9 +331,7 @@
     (define-key map (kbd "C-c C-c")   'doc-view-toggle-display)
     ;; Open a new buffer with doc's text contents
     (define-key map (kbd "C-c C-t")   'doc-view-open-text)
-    ;; Reconvert the current document.  Don't just use revert-buffer
-    ;; because that resets the scale factor, the page number, ...
-    (define-key map (kbd "g")         'doc-view-revert-buffer)
+    ;; Reconvert the current document.
     (define-key map (kbd "r")         'doc-view-revert-buffer)
     map)
   "Keymap used by `doc-view-mode' when displaying a doc as a set of images.")
@@ -1207,7 +1205,7 @@
     l))
 
 ;;;###autoload
-(defun doc-view-mode ()
+(define-derived-mode doc-view-mode special-mode "Doc"
   "Major mode in DocView buffers.
 
 DocView Mode is an Emacs document viewer.  It displays PDF, PS
@@ -1216,7 +1214,6 @@
 You can use \\<doc-view-mode-map>\\[doc-view-toggle-display] to
 toggle between displaying the document or editing it as text.
 \\{doc-view-mode-map}"
-  (interactive)
 
   (if (= (point-min) (point-max))
       ;; The doc is empty or doesn't exist at all, so fallback to
@@ -1229,7 +1226,6 @@
     (let* ((prev-major-mode (if (eq major-mode 'doc-view-mode)
                                doc-view-previous-major-mode
                              major-mode)))
-      (kill-all-local-variables)
       (set (make-local-variable 'doc-view-previous-major-mode) 
prev-major-mode))
 
     ;; Figure out the document type.
@@ -1307,20 +1303,17 @@
     (set (make-local-variable 'mwheel-scroll-down-function)
         'doc-view-scroll-down-or-previous-page)
     (set (make-local-variable 'cursor-type) nil)
-    (use-local-map doc-view-mode-map)
     (set (make-local-variable 'after-revert-hook) 'doc-view-reconvert-doc)
     (set (make-local-variable 'bookmark-make-record-function)
         'doc-view-bookmark-make-record)
-    (setq mode-name "DocView"
-         buffer-read-only t
-         major-mode 'doc-view-mode)
+    (setq buffer-read-only t)
     (doc-view-initiate-display)
     ;; Switch off view-mode explicitly, because doc-view-mode is the
     ;; 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)
-    (run-mode-hooks 'doc-view-mode-hook)))
+    (set (make-local-variable 'revert-buffer-function) 
'doc-view-revert-buffer)))
 
 ;;;###autoload
 (define-minor-mode doc-view-minor-mode

=== modified file 'lisp/image-mode.el'
--- lisp/image-mode.el  2010-08-29 16:17:13 +0000
+++ lisp/image-mode.el  2010-09-13 00:10:56 +0000
@@ -315,9 +315,7 @@
 (defvar image-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
-    (define-key map "q"         'quit-window)
     (define-key map "\C-c\C-c" 'image-toggle-display)
-    (define-key map (kbd "SPC")       'image-scroll-up)
     (define-key map (kbd "DEL")       'image-scroll-down)
     (define-key map [remap forward-char] 'image-forward-hscroll)
     (define-key map [remap backward-char] 'image-backward-hscroll)
@@ -347,19 +345,16 @@
 (put 'image-mode 'mode-class 'special)
 
 ;;;###autoload
-(defun image-mode ()
+(define-derived-mode image-mode special-mode "Image"
   "Major mode for image files.
 You can use \\<image-mode-map>\\[image-toggle-display]
 to toggle between display as an image and display as text."
-  (interactive)
+  
   (condition-case err
       (progn
        (unless (display-images-p)
          (error "Display does not support images"))
 
-       (kill-all-local-variables)
-       (setq major-mode 'image-mode)
-
        (if (not (image-get-display-property))
            (progn
              (image-toggle-display-image)
@@ -372,7 +367,6 @@
                image-type (plist-get (cdr (image-get-display-property)) 
:type)))
 
        (setq mode-name (if image-type (format "Image[%s]" image-type) "Image"))
-       (use-local-map image-mode-map)
 
        ;; Use our own bookmarking function for images.
        (set (make-local-variable 'bookmark-make-record-function)

=== modified file 'lisp/replace.el'
--- lisp/replace.el     2010-08-29 16:17:13 +0000
+++ lisp/replace.el     2010-09-12 22:12:21 +0000
@@ -767,8 +767,6 @@
     (define-key map "\M-p" 'occur-prev)
     (define-key map "r" 'occur-rename-buffer)
     (define-key map "c" 'clone-buffer)
-    (define-key map "g" 'revert-buffer)
-    (define-key map "q" 'quit-window)
     (define-key map "z" 'kill-this-buffer)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
     (define-key map [menu-bar] (make-sparse-keymap))
@@ -835,18 +833,13 @@
   :group 'matching)
 
 (put 'occur-mode 'mode-class 'special)
-(defun occur-mode ()
+(define-derived-mode occur-mode special-mode "Occur"
   "Major mode for output from \\[occur].
 \\<occur-mode-map>Move point to one of the items in this buffer, then use
 \\[occur-mode-goto-occurrence] to go to the occurrence that the item refers to.
 Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
 
 \\{occur-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map occur-mode-map)
-  (setq major-mode 'occur-mode)
-  (setq mode-name "Occur")
   (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)

=== modified file 'lisp/tar-mode.el'
--- lisp/tar-mode.el    2010-05-03 02:29:46 +0000
+++ lisp/tar-mode.el    2010-08-28 19:52:48 +0000
@@ -524,7 +524,6 @@
 (defvar tar-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map)
-    (define-key map " " 'tar-next-line)
     (define-key map "C" 'tar-copy)
     (define-key map "d" 'tar-flag-deleted)
     (define-key map "\^D" 'tar-flag-deleted)
@@ -532,14 +531,12 @@
     (define-key map "f" 'tar-extract)
     (define-key map "\C-m" 'tar-extract)
     (define-key map [mouse-2] 'tar-mouse-extract)
-    (define-key map "g" 'revert-buffer)
     (define-key map "h" 'describe-mode)
     (define-key map "n" 'tar-next-line)
     (define-key map "\^N" 'tar-next-line)
     (define-key map [down] 'tar-next-line)
     (define-key map "o" 'tar-extract-other-window)
     (define-key map "p" 'tar-previous-line)
-    (define-key map "q" 'quit-window)
     (define-key map "\^P" 'tar-previous-line)
     (define-key map [up] 'tar-previous-line)
     (define-key map "R" 'tar-rename-entry)
@@ -615,7 +612,7 @@
   (if (buffer-live-p tar-data-buffer) (kill-buffer tar-data-buffer)))
 
 ;;;###autoload
-(define-derived-mode tar-mode nil "Tar"
+(define-derived-mode tar-mode special-mode "Tar"
   "Major mode for viewing a tar file as a dired-like listing of its contents.
 You can move around using the usual cursor motion commands.
 Letters no longer insert themselves.


reply via email to

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