* Patch to remove minor modes in tutorial @ 2006-06-24 14:09 Lennart Borgman 2006-06-25 15:34 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-06-24 14:09 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 231 bytes --] Some while ago I complained that the tutorial did not work if some minor modes where enabled. Attached is a patch for that. (I am not sure if I have sent this before. I asked for help installing them, but I did not get that.) [-- Attachment #2: patch-for-tutorial.diff --] [-- Type: text/plain, Size: 3884 bytes --] Index: lisp/help-fns.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v retrieving revision 1.89 diff -u -r1.89 help-fns.el --- lisp/help-fns.el 11 May 2006 11:10:45 -0000 1.89 +++ lisp/help-fns.el 16 Jun 2006 22:07:02 -0000 @@ -98,7 +98,86 @@ (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) - (set-buffer-modified-p nil)))) + (set-buffer-modified-p nil))) + + ;; Check if minor modes may disturb + (let (minor-modes-on minor-modes unknown) + (dolist (m minor-mode-list) + (let ((fmode (or (get m :minor-mode-function) m))) + (when (and (boundp m) (symbol-value m) + (fboundp fmode) + (condition-case err + (progn + (unless + (equal '(keymap) + (symbol-value + (read (concat (symbol-name m) "-map")))) + t)) + (error nil))) + (add-to-list 'minor-modes m)))) + (dolist (m minor-mode-alist) + (add-to-list 'minor-modes (car m))) + (dolist (m minor-modes) + (when (symbol-value m) + (add-to-list 'minor-modes-on m))) + + ;; Default minor modes + (dolist (m '(auto-compression-mode + blink-cursor-mode + encoded-kbd-mode + file-name-shadow-mode + font-lock-mode + global-font-lock-mode + line-number-mode + menu-bar-mode + mouse-wheel-mode + tool-bar-mode + tooltip-mode + unify-8859-on-encoding-mode + utf-translate-cjk-mode)) + (setq minor-modes-on (delete m minor-modes-on))) + + ;; Special + (when cua-mode + (add-to-list 'minor-modes-on 'cua-mode)) + + (when minor-modes-on + (setq minor-modes-on (sort minor-modes-on 'string<)) + (let (remove-minor + (modes-on (copy-seq minor-modes-on)) + ) + (with-temp-buffer + (insert "\nYou are using some minor modes (") + (dolist (m modes-on) + (insert (format "%s" (car modes-on))) + (setq modes-on (cdr modes-on)) + (if (= 1 (length modes-on)) + (insert " and ") + (when modes-on (insert ", ")))) + (insert + ") which can possibly override global key bindings." + " The behavior of Emacs with these modes may" + " not match what the tutorial teaches.\n\n" + "Do you want to disable these modes when you are in the tutorial?" + "(y-or-n)" + ) + (fill-region (point-min) (point-max)) + (let ((use-dialog-box nil)) + (setq remove-minor + (y-or-n-p (format "%s " (buffer-substring + (point-min) + (- (point-max) 8))))))) + (if remove-minor + (progn + (make-local-variable 'emulation-mode-map-alists) + (setq emulation-mode-map-alists nil) + (dolist (m minor-modes-on) + (make-local-variable m) + (set m nil)) + (message "Removed those bindings for the tutorial only.")) + (message + "Please note that the tutorial may not work with this choice.") + ))))) \f ;; Functions @@ -325,6 +404,8 @@ "a Lisp macro") ((eq (car-safe def) 'autoload) (setq file-name (nth 1 def)) + (let ((loc (locate-library file-name))) + (when loc (setq file-name loc))) (format "%s autoloaded %s" (if (commandp def) "an interactive" "an") (if (eq (nth 4 def) 'keymap) "keymap" [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-24 14:09 Patch to remove minor modes in tutorial Lennart Borgman @ 2006-06-25 15:34 ` Richard Stallman 2006-06-25 21:27 ` Lennart Borgman 0 siblings, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-06-25 15:34 UTC (permalink / raw) Cc: emacs-devel + ;; Check if minor modes may disturb That is not an accurate description of what the new code does. It only describes a _part_ of what the code does. It ought to describe the _overall action_. + (condition-case err + (progn + (unless + (equal '(keymap) + (symbol-value + (read (concat (symbol-name m) "-map")))) + t)) + (error nil))) What is that code supposed to do? And why? + ;; Default minor modes + (dolist (m '(auto-compression-mode That comment makes no sense to me. What was the reason for choosing which modes to put in this list? + (insert + ") which can possibly override global key bindings." + " The behavior of Emacs with these modes may" + " not match what the tutorial teaches.\n\n" + "Do you want to disable these modes when you are in the tutorial?" + "(y-or-n)" + ) Why ask? Why not just do it? + (make-local-variable 'emulation-mode-map-alists) + (setq emulation-mode-map-alists nil) + (dolist (m minor-modes-on) + (make-local-variable m) + (set m nil)) Nowadays there are minor modes that can't be turned off this way. You need to call the function. @@ -325,6 +404,8 @@ "a Lisp macro") ((eq (car-safe def) 'autoload) (setq file-name (nth 1 def)) + (let ((loc (locate-library file-name))) + (when loc (setq file-name loc))) (format "%s autoloaded %s" (if (commandp def) "an interactive" "an") What is that for? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-25 15:34 ` Richard Stallman @ 2006-06-25 21:27 ` Lennart Borgman 2006-06-26 11:33 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-06-25 21:27 UTC (permalink / raw) Cc: emacs-devel Richard Stallman wrote: > + ;; Check if minor modes may disturb > > That is not an accurate description of what the new code does. > It only describes a _part_ of what the code does. > It ought to describe the _overall action_. > Thanks. I will enhance the description. > + (condition-case err > + (progn > + (unless > + (equal '(keymap) > + (symbol-value > + (read (concat (symbol-name m) "-map")))) > + t)) > + (error nil))) > > What is that code supposed to do? And why? > Some minor modes have no keybindings so they can not disturb the tutorial (recentf-mode for example). Well, at least I hope they can not. I think this is very important! > + ;; Default minor modes > + (dolist (m '(auto-compression-mode > > That comment makes no sense to me. What was the reason > for choosing which modes to put in this list? > I will change that. The modes I am referring to are those that are on when starting Emacs with -Q. > + (insert > + ") which can possibly override global key bindings." > + " The behavior of Emacs with these modes may" > + " not match what the tutorial teaches.\n\n" > + "Do you want to disable these modes when you are in the tutorial?" > + "(y-or-n)" > + ) > > Why ask? Why not just do it? > To make the user aware of that Emacs will work differently in the tutorial buffer than in other buffer (if the user answers Y). > + (make-local-variable 'emulation-mode-map-alists) > + (setq emulation-mode-map-alists nil) > + (dolist (m minor-modes-on) > + (make-local-variable m) > + (set m nil)) > > Nowadays there are minor modes that can't be turned off this way. > You need to call the function. > I have changed that. > > @@ -325,6 +404,8 @@ > "a Lisp macro") > ((eq (car-safe def) 'autoload) > (setq file-name (nth 1 def)) > + (let ((loc (locate-library file-name))) > + (when loc (setq file-name loc))) > (format "%s autoloaded %s" > (if (commandp def) "an interactive" "an") > > What is that for? > I did not think of that patch. I noticed that in some cases file-name here is not a file name at all but the library name (or was it the file name without the path??). This part of the patch may not be the correct cure for those cases though and unfortunately I do not remember which autoloaded function I saw this for. I should have made a note of course, but I thought I would have had time to finish this earlier. ------------------------ Here is a new patch: Index: help-fns.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v retrieving revision 1.89 diff -u -r1.89 help-fns.el --- help-fns.el 11 May 2006 11:10:45 -0000 1.89 +++ help-fns.el 25 Jun 2006 21:16:22 -0000 @@ -98,7 +98,98 @@ (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) - (set-buffer-modified-p nil)))) + (set-buffer-modified-p nil))) + + ;; Check if there are minor modes that may disturb the tutorial. If + ;; so show them to the user and ask if they should be disabled in + ;; the tutorial buffer. + (let (minor-modes-on minor-modes unknown) + (dolist (m minor-mode-list) + (let ((fmode (or (get m :minor-mode-function) m))) + (when (and (boundp m) (symbol-value m) + (fboundp fmode) + ;; Some minor modes have no bindings in the keymaps + ;; so ignore them: + (condition-case err + (progn + (unless + (equal '(keymap) + (symbol-value + (read (concat (symbol-name m) "-map")))) + t)) + (error nil))) + (add-to-list 'minor-modes m)))) + (dolist (m minor-mode-alist) + (add-to-list 'minor-modes (car m))) + (dolist (m minor-modes) + (when (symbol-value m) + (add-to-list 'minor-modes-on m))) + + ;; Minor modes that are on by default (ie when starting with + ;; "emacs -Q"): + (dolist (m '(auto-compression-mode + blink-cursor-mode + encoded-kbd-mode + file-name-shadow-mode + font-lock-mode + global-font-lock-mode + line-number-mode + menu-bar-mode + mouse-wheel-mode + tool-bar-mode + tooltip-mode + unify-8859-on-encoding-mode + utf-translate-cjk-mode)) + (setq minor-modes-on (delete m minor-modes-on))) + + ;; Special + (when cua-mode + (add-to-list 'minor-modes-on 'cua-mode)) + + (when minor-modes-on + (setq minor-modes-on (sort minor-modes-on 'string<)) + (let (remove-minor + (modes-on (copy-seq minor-modes-on)) + ) + ;; Ask the user if the possibly disturbing minor modes should + ;; be disabled. This is to avoid confusing the user with the + ;; different behaviour in the tutorial buffer when those modes + ;; are disabled: + (with-temp-buffer + (insert "\nYou are using some minor modes (") + (dolist (m modes-on) + (insert (format "%s" (car modes-on))) + (setq modes-on (cdr modes-on)) + (if (= 1 (length modes-on)) + (insert " and ") + (when modes-on (insert ", ")))) + (insert + ") which can possibly override global key bindings." + " The behavior of Emacs with these modes may" + " not match what the tutorial teaches.\n\n" + "Do you want to disable these modes when you are in the tutorial?" + "(y-or-n)" + ) + (fill-region (point-min) (point-max)) + (let ((use-dialog-box nil)) + (setq remove-minor + (y-or-n-p (format "%s " (buffer-substring + (point-min) + (- (point-max) 8))))))) + (if remove-minor + (progn + (make-local-variable 'emulation-mode-map-alists) + (setq emulation-mode-map-alists nil) + (dolist (m minor-modes-on) + (make-local-variable m) + ;; (set m nil) Better call the minor mode function + ;; according to RMS: + (funcall m 0) + ) + (message "Removed those bindings for the tutorial only.")) + (message + "Please note that the tutorial may not work with this choice.") + ))))) \f ;; Functions @@ -325,6 +416,8 @@ "a Lisp macro") ((eq (car-safe def) 'autoload) (setq file-name (nth 1 def)) + (let ((loc (locate-library file-name))) + (when loc (setq file-name loc))) (format "%s autoloaded %s" (if (commandp def) "an interactive" "an") (if (eq (nth 4 def) 'keymap) "keymap" ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-25 21:27 ` Lennart Borgman @ 2006-06-26 11:33 ` Richard Stallman 2006-06-26 13:48 ` Lennart Borgman 0 siblings, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-06-26 11:33 UTC (permalink / raw) Cc: emacs-devel Some minor modes have no keybindings so they can not disturb the tutorial (recentf-mode for example). Well, at least I hope they can not. I think this is very important! I think it is safer to turn them all off, aside from a specific list of exceptions. > Why ask? Why not just do it? > To make the user aware of that Emacs will work differently in the tutorial buffer than in other buffer (if the user answers Y). I agree it is useful to do that, but I think that asking a question will be confusing in a different way, since it will suggest that it is reasonable to answer N. Displaying a message which ends in "Type SPACE to proceed" is a better way to make sure the user notices the message. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-26 11:33 ` Richard Stallman @ 2006-06-26 13:48 ` Lennart Borgman 2006-06-26 16:31 ` Kevin Rodgers 2006-06-27 16:14 ` Richard Stallman 0 siblings, 2 replies; 29+ messages in thread From: Lennart Borgman @ 2006-06-26 13:48 UTC (permalink / raw) Cc: emacs-devel Richard Stallman wrote: > Some minor modes have no keybindings so they can not disturb the > tutorial (recentf-mode for example). Well, at least I hope they can not. > I think this is very important! > > I think it is safer to turn them all off, aside from a specific > list of exceptions. > Then I would be glad if those who knows about minor modes that will not disturb the turorial would mail the names of them to me. > > Why ask? Why not just do it? > > > To make the user aware of that Emacs will work differently in the > tutorial buffer than in other buffer (if the user answers Y). > > I agree it is useful to do that, but I think that asking a question > will be confusing in a different way, since it will suggest that it is > reasonable to answer N. Displaying a message which ends in "Type > SPACE to proceed" is a better way to make sure the user notices the > message. > Yes, that is better. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-26 13:48 ` Lennart Borgman @ 2006-06-26 16:31 ` Kevin Rodgers 2006-06-26 16:45 ` Lennart Borgman 2006-06-27 16:14 ` Richard Stallman 1 sibling, 1 reply; 29+ messages in thread From: Kevin Rodgers @ 2006-06-26 16:31 UTC (permalink / raw) Lennart Borgman wrote: > Richard Stallman wrote: >> Some minor modes have no keybindings so they can not disturb the >> tutorial (recentf-mode for example). Well, at least I hope they >> can not. I think this is very important! >> >> I think it is safer to turn them all off, aside from a specific >> list of exceptions. >> > Then I would be glad if those who knows about minor modes that will not > disturb the turorial would mail the names of them to me. C-h v minor-mode-map-alist -- Kevin ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-26 16:31 ` Kevin Rodgers @ 2006-06-26 16:45 ` Lennart Borgman 2006-06-27 15:44 ` Kevin Rodgers 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-06-26 16:45 UTC (permalink / raw) Cc: emacs-devel Kevin Rodgers wrote: > Lennart Borgman wrote: >> Richard Stallman wrote: >>> Some minor modes have no keybindings so they can not disturb the >>> tutorial (recentf-mode for example). Well, at least I hope they >>> can not. I think this is very important! >>> >>> I think it is safer to turn them all off, aside from a specific >>> list of exceptions. >>> >> Then I would be glad if those who knows about minor modes that will >> not disturb the turorial would mail the names of them to me. > > C-h v minor-mode-map-alist > Thanks, but how can that help? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-26 16:45 ` Lennart Borgman @ 2006-06-27 15:44 ` Kevin Rodgers 2006-06-27 16:41 ` Lennart Borgman 2006-06-28 17:25 ` Richard Stallman 0 siblings, 2 replies; 29+ messages in thread From: Kevin Rodgers @ 2006-06-27 15:44 UTC (permalink / raw) Lennart Borgman wrote: > Kevin Rodgers wrote: >> Lennart Borgman wrote: >>> Richard Stallman wrote: >>>> Some minor modes have no keybindings so they can not disturb the >>>> tutorial (recentf-mode for example). Well, at least I hope they >>>> can not. I think this is very important! >>>> >>>> I think it is safer to turn them all off, aside from a specific >>>> list of exceptions. >>>> >>> Then I would be glad if those who knows about minor modes that will >>> not disturb the turorial would mail the names of them to me. >> >> C-h v minor-mode-map-alist >> > Thanks, but how can that help? A minor mode that doesn't have an entry in minor-mode-map-alist has no keybindings (assuming it is not autoloaded -- but if it has not been loaded yet, it's definitely not turned on and has no effect). -- Kevin ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-27 15:44 ` Kevin Rodgers @ 2006-06-27 16:41 ` Lennart Borgman 2006-06-28 17:25 ` Richard Stallman 1 sibling, 0 replies; 29+ messages in thread From: Lennart Borgman @ 2006-06-27 16:41 UTC (permalink / raw) Cc: emacs-devel Kevin Rodgers wrote: > Lennart Borgman wrote: >> Kevin Rodgers wrote: >>> Lennart Borgman wrote: >>>> Richard Stallman wrote: >>>>> Some minor modes have no keybindings so they can not disturb >>>>> the tutorial (recentf-mode for example). Well, at least I hope >>>>> they can not. I think this is very important! >>>>> >>>>> I think it is safer to turn them all off, aside from a specific >>>>> list of exceptions. >>>>> >>>> Then I would be glad if those who knows about minor modes that will >>>> not disturb the turorial would mail the names of them to me. >>> >>> C-h v minor-mode-map-alist >>> >> Thanks, but how can that help? > > A minor mode that doesn't have an entry in minor-mode-map-alist has > no keybindings (assuming it is not autoloaded -- but if it has not > been loaded yet, it's definitely not turned on and has no effect). > Ah, I see the idea. But a little bit more have to be checked, there is also emulation-mode-map-alists (and minor-mode-overriding-map-alist but that does not apply here). ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-27 15:44 ` Kevin Rodgers 2006-06-27 16:41 ` Lennart Borgman @ 2006-06-28 17:25 ` Richard Stallman 2006-06-29 8:41 ` Kim F. Storm 1 sibling, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-06-28 17:25 UTC (permalink / raw) Cc: emacs-devel A minor mode that doesn't have an entry in minor-mode-map-alist has no keybindings (assuming it is not autoloaded -- but if it has not been loaded yet, it's definitely not turned on and has no effect). It is conceivable that a minor mode has other effects that would interfere with the tutorial. For instance Abbrev mode. At the same time, it is possible that a minor mode alters only keys that the tutorial does not talk about, in which case it does not interfere with the tutorial. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-28 17:25 ` Richard Stallman @ 2006-06-29 8:41 ` Kim F. Storm 2006-06-29 12:07 ` Mathias Dahl 2006-06-29 17:57 ` Richard Stallman 0 siblings, 2 replies; 29+ messages in thread From: Kim F. Storm @ 2006-06-29 8:41 UTC (permalink / raw) Cc: Kevin Rodgers, emacs-devel Richard Stallman <rms@gnu.org> writes: > A minor mode that doesn't have an entry in minor-mode-map-alist has > no keybindings (assuming it is not autoloaded -- but if it has not > been loaded yet, it's definitely not turned on and has no effect). > > It is conceivable that a minor mode has other effects that would interfere > with the tutorial. For instance Abbrev mode. > > At the same time, it is possible that a minor mode alters only keys > that the tutorial does not talk about, in which case it does not > interfere with the tutorial. In general, there is a problem with the tutorial and minor-modes: Suppose you get a .emacs from someone, which changes some key bindings. Then you run the tutorial with those minor modes enabled. This may cause the examples/instructions in the tutorial to fail in mysterious ways. That's no good. Now, suppose you run the tutorial with the minor modes temporarily disabled. The tutorial will work just fine, and you will learn the basic commands etc. But when you exit the tutorial, the minor modes are back -- and the stuff that worked in the tutorial no longer works the way the tutorial taught you... That's no good either! Maybe it be better to simply issue a warning at the start of the tutorial if "affecting" minor modes are enabled -- something like this: NOTE: This instance of Emacs has local customizations which may cause some instructions in the tutorial to fail. If that happens, review the local customizations in the file ~/.emacs. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-29 8:41 ` Kim F. Storm @ 2006-06-29 12:07 ` Mathias Dahl 2006-06-29 12:27 ` David Kastrup 2006-06-29 17:57 ` Richard Stallman 1 sibling, 1 reply; 29+ messages in thread From: Mathias Dahl @ 2006-06-29 12:07 UTC (permalink / raw) Cc: Kevin Rodgers, rms, emacs-devel > In general, there is a problem with the tutorial and minor-modes: > ... > Maybe it be better to simply issue a warning at the start of the > tutorial if "affecting" minor modes are enabled -- something like > this: > > NOTE: This instance of Emacs has local customizations which may > cause some instructions in the tutorial to fail. If that happens, > review the local customizations in the file ~/.emacs. I like this idea. It seems we can never protect the user from all problems in this area so the best thing is to inform him about that. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-29 12:07 ` Mathias Dahl @ 2006-06-29 12:27 ` David Kastrup 2006-06-30 11:06 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: David Kastrup @ 2006-06-29 12:27 UTC (permalink / raw) Cc: Kevin Rodgers, emacs-devel, rms, Kim F. Storm "Mathias Dahl" <mathias.dahl@gmail.com> writes: >> In general, there is a problem with the tutorial and minor-modes: > >> ... > >> Maybe it be better to simply issue a warning at the start of the >> tutorial if "affecting" minor modes are enabled -- something like >> this: >> >> NOTE: This instance of Emacs has local customizations which may >> cause some instructions in the tutorial to fail. If that happens, >> review the local customizations in the file ~/.emacs. > > I like this idea. It seems we can never protect the user from all > problems in this area so the best thing is to inform him about that. We could recommend to start a session with emacs -q if one suspects stuff in the tutorial to fail because of customizations. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-29 12:27 ` David Kastrup @ 2006-06-30 11:06 ` Richard Stallman 0 siblings, 0 replies; 29+ messages in thread From: Richard Stallman @ 2006-06-30 11:06 UTC (permalink / raw) Cc: ihs_4664, storm, emacs-devel, mathias.dahl We could recommend to start a session with emacs -q if one suspects stuff in the tutorial to fail because of customizations. We could, but Kim is right in point out that this isn't really useful. The tutorial exists for using Emacs, not vice versa. Making the tutorial "work right" in teaching standard Emacs won't enable the user to use his non-standard Emacs. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-29 8:41 ` Kim F. Storm 2006-06-29 12:07 ` Mathias Dahl @ 2006-06-29 17:57 ` Richard Stallman 2006-07-01 0:38 ` Lennart Borgman 1 sibling, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-06-29 17:57 UTC (permalink / raw) Cc: ihs_4664, emacs-devel Suppose you get a .emacs from someone, which changes some key bindings. It is a bad thing to start off a new user with a .emacs file that changes key bindings. Regardless of what documentation the user learns from, it will be wrong; but it's worse than that. Users should decide for themselves whether to change key bindings. Maybe it be better to simply issue a warning at the start of the tutorial if "affecting" minor modes are enabled -- something like this: NOTE: This instance of Emacs has local customizations which may cause some instructions in the tutorial to fail. If that happens, review the local customizations in the file ~/.emacs. You have convinced me. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-29 17:57 ` Richard Stallman @ 2006-07-01 0:38 ` Lennart Borgman 2006-07-01 23:55 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-07-01 0:38 UTC (permalink / raw) Cc: ihs_4664, emacs-devel, Kim F. Storm Richard Stallman wrote: > Suppose you get a .emacs from someone, which changes some key bindings. > > It is a bad thing to start off a new user with a .emacs file that > changes key bindings. Regardless of what documentation the user > learns from, it will be wrong; but it's worse than that. Users should > decide for themselves whether to change key bindings. > > Maybe it be better to simply issue a warning at the start of the > tutorial if "affecting" minor modes are enabled -- something like > this: > > NOTE: This instance of Emacs has local customizations which may > cause some instructions in the tutorial to fail. If that happens, > review the local customizations in the file ~/.emacs. > > You have convinced me. > Here is a new version of help-with-tutorial for testing. This new version behaves like this: - It checks the actual keybindings and tries to find those in minor modes. - It asks the user if the disturbing key bindings should be removed. - It inserts a warning in the tutorial text. Eh, in English. (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") (let ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) file filename (point-after-message 1)) (setq filename (get-language-info lang 'tutorial)) (setq file (expand-file-name (concat "~/" filename))) (delete-other-windows) (if (get-file-buffer file) (switch-to-buffer (get-file-buffer file)) (switch-to-buffer (create-file-buffer file)) (setq buffer-file-name file) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (setq buffer-file-name nil) (hack-local-variables) ;; Check if there are key bindings or minor modes that may disturb ;; the tutorial. If so show them to the user and ask if they should ;; be disabled in the tutorial buffer. (let (minor-modes-added minor-modes minor-modes-disturbing other-disturbed-keys unknown (tutorial-keys '( (save-buffers-kill-emacs [(control ?x)(control ?c)]) ;; * SUMMARY (scroll-up [(control ?v)]) (scroll-down [(meta ?v)]) (recenter [(control ?l)]) ;; * BASIC CURSOR CONTROL (forward-char [(control ?f)]) (backward-char [(control ?b)]) (forward-word [(meta ?f)]) (backward-word [(meta ?b)]) (next-line [(control ?n)]) (previous-line [(control ?p)]) (move-beginning-of-line [(control ?a)]) (move-end-of-line [(control ?e)]) (backward-sentence [(meta ?a)]) (forward-sentence [(meta ?e)]) (beginning-of-buffer [(meta ?<)]) (end-of-buffer [(meta ?>)]) (universal-argument [(control ?u)]) ;; * WHEN EMACS IS HUNG (keyboard-quit [(control ?g)]) ;; * DISABLED COMMANDS (downcase-region [(control ?x)(control ?l)]) ;; * WINDOWS (delete-other-windows [(control ?x) ?1]) ;; C-u 0 C-l ;; Type CONTROL-h k CONTROL-f. ;; * INSERTING AND DELETING ;; C-u 8 * to insert ********. (delete-backward-char [backspace]) (delete-char [(control ?d)]) (backward-kill-word [(meta backspace)]) (kill-word [(meta ?d)]) (kill-line [(control ?k)]) (kill-sentence [(meta ?k)]) ;; You can also kill any part of the text with one uniform method. Move (set-mark-command [(control ?@)]) (set-mark-command [(control ? )]) (kill-region [(control ?w)]) (yank [(control ?y)]) (yank-pop [(meta ?y)]) ;; * UNDO (advertised-undo [(control ?x) ?u]) (advertised-undo [(control ?x) ?u]) ;; * FILES (find-file [(control ?x)(control ?f)]) (save-buffer [(control ?x)(control ?s)]) ;; * BUFFERS (list-buffers [(control ?x)(control ?b)]) (switch-to-buffer [(control ?x) ?b]) (save-some-buffers [(control ?x) ?s]) ;; * EXTENDING THE COMMAND SET ;; C-x Character eXtend. Followed by one character. (execute-extended-command [(meta ?x)]) ;; C-x C-f Find file ;; C-x C-s Save file ;; C-x s Save some buffers ;; C-x C-b List buffers ;; C-x b Switch buffer ;; C-x C-c Quit Emacs ;; C-x 1 Delete all but one window ;; C-x u Undo ;; * MODE LINE (describe-mode [(control ?h) ?m]) (set-fill-column [(control ?x) ?f]) (fill-paragraph [(meta ?q)]) ;; * SEARCHING (isearch-forward [(control ?s)]) (isearch-backward [(control ?r)]) ;; * MULTIPLE WINDOWS (split-window-vertically [(control ?x) ?2]) (scroll-other-window [(control meta ?v)]) ;; (list "<ESC> C-v" 'scroll-other-window [escape (control-v)]) (other-window [(control ?x) ?o]) (find-file-other-window [(control ?x) ?4 (control ?f)]) ;; * RECURSIVE EDITING LEVELS ;;(list "<ESC> <ESC> <ESC>" 'keyboard-escape-quit [escape escape escape]) ;; * GETTING MORE HELP ;; The most basic HELP feature is C-h c (describe-key-briefly [(control ?h) ?c]) (describe-key [(control ?h) ?k]) ;; * MORE FEATURES ;; F10 ;; * CONCLUSION (iconify-or-deiconify-frame [(control ?z)]) ) ) failed-keys still-failed-keys ) (dolist (m minor-mode-list) (let ((fmode (or (get m :minor-mode-function) m))) (when (and (boundp m) (symbol-value m) (fboundp fmode) ;; Some minor modes have no bindings in the keymaps ;; so ignore them: (condition-case err (progn (unless (equal '(keymap) (symbol-value (read (concat (symbol-name m) "-map")))) t)) (error nil))) (add-to-list 'minor-modes m)))) (dolist (m minor-mode-alist) (add-to-list 'minor-modes (car m))) (dolist (m minor-modes) (when (symbol-value m) (add-to-list 'minor-modes-added m))) ;; Minor modes that are on by default (ie when starting with ;; "emacs -Q"): (dolist (m '(auto-compression-mode blink-cursor-mode encoded-kbd-mode file-name-shadow-mode font-lock-mode global-font-lock-mode line-number-mode menu-bar-mode mouse-wheel-mode tool-bar-mode tooltip-mode unify-8859-on-encoding-mode utf-translate-cjk-mode)) (setq minor-modes-added (delete m minor-modes-added))) ;; What default key bindings used in the tutorial are ;; disturbed? (let ((initial-failings)) (with-temp-buffer (fundamental-mode) (dolist (tk tutorial-keys) (let* ((b (cadr tk)) (f (key-binding b)) (cp-tk (copy-sequence tk))) (unless (eq (car tk) f) (add-to-list 'failed-keys tk) (setq cp-tk (cons f cp-tk)) (add-to-list 'initial-failings cp-tk))))) ;; Which minor modes are disturbing the key bindings above? (dolist (m minor-modes-added) (let ((m-failings)) (with-temp-buffer (fundamental-mode) (make-local-variable m) (funcall m 0) (dolist (tk tutorial-keys) (let* ((b (cadr tk)) (f (key-binding b)) (cp-tk (copy-sequence tk))) (unless (eq (car tk) f) (setq cp-tk (cons f cp-tk)) (add-to-list 'm-failings cp-tk))))) (unless (equal m-failings initial-failings) (add-to-list 'minor-modes-disturbing m)))) ;; Does it help removing all these keys and those in ;; emulation-mode-map-alist? (with-temp-buffer (fundamental-mode) (make-local-variable 'emulation-mode-map-alists) (setq emulation-mode-map-alists nil) (dolist (m minor-modes-disturbing) (make-local-variable m) (funcall m 0)) (dolist (tk tutorial-keys) (let* ((b (cadr tk)) (f (key-binding b))) (unless (eq (car tk) f) (add-to-list 'still-failed-keys tk)))))) ;; Those are in emulation-mode-map-alists (when cua-mode (add-to-list 'minor-modes-disturbing 'cua-mode)) (when viper-mode (add-to-list 'minor-modes-disturbing 'viper-mode)) (when (or minor-modes-disturbing still-failed-keys) (setq minor-modes-disturbing (sort minor-modes-disturbing 'string<)) (let (remove-minor (modes-disturbing (copy-seq minor-modes-disturbing)) ) ;; Ask the user if the possibly disturbing minor modes should ;; be disabled. This is to avoid confusing the user with the ;; different behaviour in the tutorial buffer when those modes ;; are disabled: (with-temp-buffer (insert "\nYou are using some minor modes (") (dolist (m modes-disturbing) (insert (format "%s" (car modes-disturbing))) (setq modes-disturbing (cdr modes-disturbing)) (if (= 1 (length modes-disturbing)) (insert " and ") (when modes-disturbing (insert ", ")))) (insert ") which are overriding some default key bindings." " The behavior of Emacs with these modes may" " not match what the tutorial teaches.\n\n" "Do you want to disable these modes when you are in the tutorial? ") (when still-failed-keys (insert "(Unfortunately in your case some key bindings" " will still be overriden." " You get more information about this later.)\n\n")) (insert "(y-or-n)" ) (fill-region (point-min) (point-max)) (let ((use-dialog-box nil)) (setq remove-minor (y-or-n-p (format "%s " (buffer-substring (point-min) (- (point-max) 8))))))) (if remove-minor (progn (make-local-variable 'emulation-mode-map-alists) (setq emulation-mode-map-alists nil) (setq minor-modes-disturbing (delete 'cua-mode minor-modes-disturbing)) (setq minor-modes-disturbing (delete 'viper-mode minor-modes-disturbing)) (dolist (m minor-modes-disturbing) (make-local-variable m) ;; (set m nil) Better call the minor mode function ;; according to RMS: (funcall m 0) ) (message "Disabled those minor modes for the tutorial only.")) (message "Please note that the tutorial may not work with this choice.") ) (when (or still-failed-keys (not remove-minor)) (forward-line) (let ((start (point))) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However when you run the tutorial now the following key bindings have been changed from default:\n\n") (let ((frm " %-14s %-26s %s\n")) (insert (format frm "KEY SEQUENCE" "DEFAULT BINDING" "CURRENT BINDING")) (dolist (tk tutorial-keys) (let* ((d (car tk)) (k (cadr tk)) (f (key-binding k))) (unless (eq (car tk) f) (insert (format frm (key-description k) d f)))))) (insert "\n") (put-text-property start (point) 'face (list :background "yellow"))) (setq point-after-message (point)) (goto-char (point-min)) (set-buffer-modified-p nil))))) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (message "")(sit-for 0) ;; Shrinks mini-buffer window (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6 ;;(/ (count-lines (point-min) point-after-message) 2) ))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-01 0:38 ` Lennart Borgman @ 2006-07-01 23:55 ` Richard Stallman 2006-07-02 8:54 ` Lennart Borgman 0 siblings, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-07-01 23:55 UTC (permalink / raw) Cc: ihs_4664, storm, emacs-devel - It asks the user if the disturbing key bindings should be removed. As Kim pointed out, it should not ask. And it probably should not turn off the modes, either. It should just display a warning. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-01 23:55 ` Richard Stallman @ 2006-07-02 8:54 ` Lennart Borgman 2006-07-02 22:30 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-07-02 8:54 UTC (permalink / raw) Cc: ihs_4664, emacs-devel, storm Richard Stallman wrote: > - It asks the user if the disturbing key bindings should be removed. > > As Kim pointed out, it should not ask. And it probably should not > turn off the modes, either. It should just display a warning. > Here is a new version where the question is still there but it is easy to turn off to test wether it feels right with the question or not. Just look for ask-user in the code. I have also tried to take care of remapped functions. (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") (let ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) file filename (point-after-message 1)) (setq filename (get-language-info lang 'tutorial)) (setq file (expand-file-name (concat "~/" filename))) (delete-other-windows) (if (get-file-buffer file) (switch-to-buffer (get-file-buffer file)) (switch-to-buffer (create-file-buffer file)) (setq buffer-file-name file) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (setq buffer-file-name nil) (hack-local-variables) ;; Check if there are key bindings or minor modes that may disturb ;; the tutorial. If so show them to the user and ask if they should ;; be disabled in the tutorial buffer. (let (minor-modes-added minor-modes minor-modes-disturbing other-disturbed-keys unknown (tutorial-keys '( (save-buffers-kill-emacs [(control ?x)(control ?c)]) ;; * SUMMARY (scroll-up [(control ?v)]) (scroll-down [(meta ?v)]) (recenter [(control ?l)]) ;; * BASIC CURSOR CONTROL (forward-char [(control ?f)]) (backward-char [(control ?b)]) (forward-word [(meta ?f)]) (backward-word [(meta ?b)]) (next-line [(control ?n)]) (previous-line [(control ?p)]) (move-beginning-of-line [(control ?a)]) (move-end-of-line [(control ?e)]) (backward-sentence [(meta ?a)]) (forward-sentence [(meta ?e)]) (beginning-of-buffer [(meta ?<)]) (end-of-buffer [(meta ?>)]) (universal-argument [(control ?u)]) ;; * WHEN EMACS IS HUNG (keyboard-quit [(control ?g)]) ;; * DISABLED COMMANDS (downcase-region [(control ?x)(control ?l)]) ;; * WINDOWS (delete-other-windows [(control ?x) ?1]) ;; C-u 0 C-l ;; Type CONTROL-h k CONTROL-f. ;; * INSERTING AND DELETING ;; C-u 8 * to insert ********. (delete-backward-char [backspace]) (delete-char [(control ?d)]) (backward-kill-word [(meta backspace)]) (kill-word [(meta ?d)]) (kill-line [(control ?k)]) (kill-sentence [(meta ?k)]) ;; You can also kill any part of the text with one uniform method. Move (set-mark-command [(control ?@)]) (set-mark-command [(control ? )]) (kill-region [(control ?w)]) (yank [(control ?y)]) (yank-pop [(meta ?y)]) ;; * UNDO (advertised-undo [(control ?x) ?u]) (advertised-undo [(control ?x) ?u]) ;; * FILES (find-file [(control ?x)(control ?f)]) (save-buffer [(control ?x)(control ?s)]) ;; * BUFFERS (list-buffers [(control ?x)(control ?b)]) (switch-to-buffer [(control ?x) ?b]) (save-some-buffers [(control ?x) ?s]) ;; * EXTENDING THE COMMAND SET ;; C-x Character eXtend. Followed by one character. (execute-extended-command [(meta ?x)]) ;; C-x C-f Find file ;; C-x C-s Save file ;; C-x s Save some buffers ;; C-x C-b List buffers ;; C-x b Switch buffer ;; C-x C-c Quit Emacs ;; C-x 1 Delete all but one window ;; C-x u Undo ;; * MODE LINE (describe-mode [(control ?h) ?m]) (set-fill-column [(control ?x) ?f]) (fill-paragraph [(meta ?q)]) ;; * SEARCHING (isearch-forward [(control ?s)]) (isearch-backward [(control ?r)]) ;; * MULTIPLE WINDOWS (split-window-vertically [(control ?x) ?2]) (scroll-other-window [(control meta ?v)]) ;; (list "<ESC> C-v" 'scroll-other-window [escape (control-v)]) (other-window [(control ?x) ?o]) (find-file-other-window [(control ?x) ?4 (control ?f)]) ;; * RECURSIVE EDITING LEVELS ;;(list "<ESC> <ESC> <ESC>" 'keyboard-escape-quit [escape escape escape]) ;; * GETTING MORE HELP ;; The most basic HELP feature is C-h c (describe-key-briefly [(control ?h) ?c]) (describe-key [(control ?h) ?k]) ;; * MORE FEATURES ;; F10 ;; * CONCLUSION (iconify-or-deiconify-frame [(control ?z)]) ) ) failed-keys still-failed-keys ) (dolist (m minor-mode-list) (let ((fmode (or (get m :minor-mode-function) m))) (when (and (boundp m) (symbol-value m) (fboundp fmode) ;; Some minor modes have no bindings in the keymaps ;; so ignore them: (condition-case err (progn (unless (equal '(keymap) (symbol-value (read (concat (symbol-name m) "-map")))) t)) (error nil))) (add-to-list 'minor-modes m)))) (dolist (m minor-mode-alist) (add-to-list 'minor-modes (car m))) (dolist (m minor-modes) (when (symbol-value m) (add-to-list 'minor-modes-added m))) ;; Minor modes that are on by default (ie when starting with ;; "emacs -Q"): (dolist (m '(auto-compression-mode blink-cursor-mode encoded-kbd-mode file-name-shadow-mode font-lock-mode global-font-lock-mode line-number-mode menu-bar-mode mouse-wheel-mode tool-bar-mode tooltip-mode unify-8859-on-encoding-mode utf-translate-cjk-mode)) (setq minor-modes-added (delete m minor-modes-added))) ;; What default key bindings used in the tutorial are ;; disturbed? (let ((initial-failing-keys)) (with-temp-buffer (fundamental-mode) (dolist (tk tutorial-keys) (let* ((key (cadr tk)) (def-fun (car tk)) (rem-fun (command-remapping def-fun)) (key-fun (key-binding key)) (cp-tk (copy-sequence tk))) (unless (or (eq def-fun key-fun) (eq rem-fun key-fun)) (add-to-list 'failed-keys tk) (add-to-list 'initial-failing-keys cp-tk))))) ;; Which minor modes are disturbing the key bindings above? (dolist (m minor-modes-added) (let ((m-failing-keys)) (with-temp-buffer (fundamental-mode) (make-local-variable m) (funcall m 0) (dolist (tk tutorial-keys) (let* ((key (cadr tk)) (def-fun (car tk)) (rem-fun (command-remapping def-fun)) (key-fun (key-binding key)) (cp-tk (copy-sequence tk))) (unless (or (eq def-fun key-fun) (eq rem-fun key-fun)) ;;(setq cp-tk (cons key-fun cp-tk)) (add-to-list 'm-failing-keys cp-tk))))) (unless (equal m-failing-keys initial-failing-keys) (add-to-list 'minor-modes-disturbing m)))) ;; Does it help removing all these keys and those in ;; emulation-mode-map-alist? (with-temp-buffer (fundamental-mode) (make-local-variable 'emulation-mode-map-alists) (setq emulation-mode-map-alists nil) (dolist (m minor-modes-disturbing) (make-local-variable m) (funcall m 0)) (dolist (tk tutorial-keys) (let* ((key (cadr tk)) (def-fun (car tk)) (rem-fun (command-remapping def-fun)) (key-fun (key-binding key))) (unless (or (eq def-fun key-fun) (eq rem-fun key-fun)) (add-to-list 'still-failed-keys tk))))) ;; Those are in emulation-mode-map-alists (when cua-mode (add-to-list 'minor-modes-disturbing 'cua-mode)) (when viper-mode (add-to-list 'minor-modes-disturbing 'viper-mode)) (when (or minor-modes-disturbing still-failed-keys) (setq minor-modes-disturbing (sort minor-modes-disturbing 'string<)) (let (remove-minor (ask-user t) (modes-disturbing (copy-seq minor-modes-disturbing)) ) (when ask-user ;; Ask the user if the possibly disturbing minor modes should ;; be disabled. This is to avoid confusing the user with the ;; different behaviour in the tutorial buffer when those modes ;; are disabled: (with-temp-buffer (insert "\nYou are using some minor modes (") (dolist (m modes-disturbing) (insert (format "%s" (car modes-disturbing))) (setq modes-disturbing (cdr modes-disturbing)) (if (= 1 (length modes-disturbing)) (insert " and ") (when modes-disturbing (insert ", ")))) (insert ") which are overriding some default key bindings." " The behavior of Emacs with these modes may" " not match what the tutorial teaches.\n\n" "Do you want to disable these modes when you are in the tutorial? ") (when still-failed-keys (insert "(Unfortunately in your case some key bindings" " will still be overriden." " You get more information about this later.)\n\n")) (insert "(y-or-n)" ) (fill-region (point-min) (point-max)) (let ((use-dialog-box nil)) (setq remove-minor (y-or-n-p (format "%s " (buffer-substring (point-min) (- (point-max) 8)))))))) (message "") ;; Shrinks mini-buffer window (if remove-minor (progn (make-local-variable 'emulation-mode-map-alists) (setq emulation-mode-map-alists nil) (setq minor-modes-disturbing (delete 'cua-mode minor-modes-disturbing)) (setq minor-modes-disturbing (delete 'viper-mode minor-modes-disturbing)) (dolist (m minor-modes-disturbing) (make-local-variable m) ;; (set m nil) Better call the minor mode function ;; according to RMS: (funcall m 0) ) (message "Disabled those minor modes for the tutorial only.")) (when ask-user (message "Please note that the tutorial may not work with this choice.")) ) (when (or still-failed-keys (not remove-minor)) (forward-line) (let ((start (point))) (cond (remove-minor (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. Even though you agreed to turn off minor modes with key bindings conflicting with the tutorial there are unfortunately still some conflicting key bindings left. Those are probably set in your initialization files (~/.emacs etc). The folloing key bindings have still values that are changed from Emacs default:\n\n" )) ((not remove-minor) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However it was found that when you started the tutorial the following key bindings had been changed from Emacs default:\n\n" )) (t (insert " INTERNAL ERROR! There was an internal error when starting the tutorial.\n\n" )) ) (let ((frm " %-14s %-26s %-18s %s\n") (keys (if remove-minor still-failed-keys initial-failing-keys))) (insert (format frm "KEY SEQUENCE" "DEFAULT BINDING" "USE NOW" "CURRENT BINDING")) (dolist (tk keys) (let* ((def-fun (car tk)) (key (cadr tk)) (rem-fun (command-remapping def-fun)) (use-key "") (key-txt (key-description key)) (key-fun (key-binding key))) (unless (eq def-fun key-fun) (if rem-fun (progn (if (eq (key-binding key) rem-fun) (setq use-key "Use same") (let ((where (where-is-internal rem-fun))) (when where (setq use-key (key-description (car where))))))) (let ((where (where-is-internal def-fun))) (when where (setq use-key (key-description (car where)))))) (insert (format frm key-txt def-fun use-key (format "%s: %s" key-txt key-fun))))))) (insert " Please understand that it is quite ok to change key bindings in Emacs, but the tutorial may not work when you do that.\n\n" ) (put-text-property start (point) 'face ;;'font-lock-warning-face (list :background "yellow" :foreground "#c00") ))) (setq point-after-message (point)) (goto-char (point-min)) (set-buffer-modified-p nil))))) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-02 8:54 ` Lennart Borgman @ 2006-07-02 22:30 ` Richard Stallman 2006-07-07 0:01 ` Lennart Borgman 0 siblings, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-07-02 22:30 UTC (permalink / raw) Cc: emacs-devel Please delete the ask-user code, and also the remove-minor code. I am convinced that we don't want to do either of those things. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-02 22:30 ` Richard Stallman @ 2006-07-07 0:01 ` Lennart Borgman 2006-07-07 19:31 ` Richard Stallman ` (2 more replies) 0 siblings, 3 replies; 29+ messages in thread From: Lennart Borgman @ 2006-07-07 0:01 UTC (permalink / raw) Cc: emacs-devel Richard Stallman wrote: > Please delete the ask-user code, and also the remove-minor code. I am > convinced that we don't want to do either of those things. > Here is a new version of help-with-tutorial then. I have added some information instead that could be useful: (defun help-describe-nonstandard-key(value) (let ((maps (current-active-maps t))) (with-output-to-temp-buffer (help-buffer) (help-setup-xref (list #'help-describe-nonstandard-key value) (interactive-p)) (with-current-buffer (help-buffer) (insert "Default key binding has been changed:\n\n") (let ((inhibit-read-only t)) (cond ((eq (car value) 'cua-mode) (insert "You are using `cua-mode'." " In this mode the C-c prefix is rebound so" " that it copies the region if it is active." " If the region is not active then C-c will" " work as it normally does in Emacs.")) ((eq (car value) 'current-binding) (let ((cb (nth 1 value)) (db (nth 2 value)) (key (nth 3 value)) (where (nth 4 value)) map mapsym) (while maps (let* ((m (car maps)) (mb (lookup-key m key t))) (setq maps (cdr maps)) (when (eq mb cb) (setq map m) (setq maps nil)))) (when map (if (eq map global-map) (setq mapsym 'global-map) (mapatoms (lambda (s) (when (and (boundp s) (keymapp (symbol-value s))) (unless (eq s 'map) (when (equal map (symbol-value s)) (when (member map (current-active-maps)) (setq mapsym s))))))))) (insert "Emacs default binding for the key " (key-description key) " is the function `") (insert (format "%s" db)) (insert "'. This key has however been rebound to the function `") (insert (format "%s" cb)) (insert "'.") (when mapsym (insert " This binding is in the keymap variable `") (insert (format "%s" mapsym)) (insert "'.")) (when where (insert "\n\nYou can use the key " where " to get the function `" (format "%s" db) "'.")) )))) (fill-region (point-min)(point)) (print-help-return-message))))) (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") (let ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) file filename (point-after-message 1)) (setq filename (get-language-info lang 'tutorial)) (setq file (expand-file-name (concat "~/" filename))) (delete-other-windows) (if (get-file-buffer file) (switch-to-buffer (get-file-buffer file)) (switch-to-buffer (create-file-buffer file)) (setq buffer-file-name file) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (setq buffer-file-name nil) (hack-local-variables) ;; Check if there are key bindings that may disturb the ;; tutorial. If so tell the user. (let (initial-bad-keys) (with-temp-buffer (insert-file (locate-library "bindings.el")) (let (expr key def-fun def-fun-txt rem-fun key-fun where remark ) (while (condition-case err (setq expr (read (current-buffer))) (error nil)) (cond ((and (eq (nth 0 expr) 'define-key) (eq (nth 1 expr) 'global-map)) (setq key (nth 2 expr)) (setq def-fun (nth 3 expr))) ((eq (nth 0 expr) 'global-set-key) (setq key (nth 1 expr)) (setq def-fun (nth 2 expr))) (t (setq key nil))) (when key (assert (eq (nth 0 def-fun) 'quote)) (setq def-fun (nth 1 def-fun)) (setq def-fun-txt (format "%s" def-fun)) (setq rem-fun (command-remapping def-fun)) (setq key-fun (key-binding key)) (setq where (where-is-internal (if rem-fun rem-fun def-fun))) (if where (setq where (key-description (car where))) (setq where "")) (setq remark nil) (unless (cond ( (eq key-fun def-fun) t) ( (eq key-fun (command-remapping def-fun)) (setq remark (list "Remapped" nil)) t) ;; cua-mode special: ( (and cua-mode (eq def-fun 'mode-specific-command-prefix) (equal key-fun '(keymap (timeout . copy-region-as-kill)))) (setq remark (list "cua-mode replacement" 'cua-mode)) (setq def-fun-txt "\"C-c prefix\"") (setq where "Same key") nil) ;; The strange handling of C-delete and ;; C-backspace: ( (when normal-erase-is-backspace (or (and (equal key [C-delete]) (equal key-fun 'kill-word)) (and (equal key [C-backspace]) (equal key-fun 'backward-kill-word)))) t) ( t (setq remark (list "More info" 'current-binding key-fun def-fun key where)) nil)) (add-to-list 'initial-bad-keys (list def-fun key def-fun-txt where remark))))))) (when initial-bad-keys (forward-line) (let ((start (point)) fun-buttons remark-buttons) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However when you started the tutorial the following key bindings had been changed from Emacs default:\n\n" ) (let ((frm " %-9s %-25s %-11s %s\n") (keys initial-bad-keys)) (insert (format frm "KEY" "DEFAULT BINDING" "IS NOW ON" "REMARK")) (dolist (tk keys) (let* ((def-fun (nth 0 tk)) (key (nth 1 tk)) (def-fun-txt (nth 2 tk)) (where (nth 3 tk)) (remark (nth 4 tk)) (rem-fun (command-remapping def-fun)) (key-txt (key-description key)) (key-fun (key-binding key))) (unless (eq def-fun key-fun) (insert (format " %-9s " key-txt)) (let ((beg (point)) end len) (insert def-fun-txt) (setq end (point)) (setq len (- 25 (length def-fun-txt))) (when (>= 0 len) (setq len 1)) (insert (make-string len ? )) (add-to-list 'fun-buttons (list beg end def-fun)) (insert (format " %-11s " where)) (setq beg (point)) (insert (format "%s" (car remark))) (setq end (point)) (add-to-list 'remark-buttons (list beg end (cdr remark))) (insert "\n") ))))) (insert " Please understand that it is ok to change key bindings, but the tutorial may not work correctly. (See also " ) (setq link-beg (point)) (insert "Key Binding Conventions") (setq link-end (point)) (insert ".)\n\n") (put-text-property start (point) 'face ;;'font-lock-warning-face (list :background "yellow" :foreground "#c00") ) (dolist (b remark-buttons) (let ((beg (nth 0 b)) (end (nth 1 b)) (remark (nth 2 b))) (make-text-button beg end 'action (lambda(b) (interactive) (let ((value (button-get b 'value))) (help-describe-nonstandard-key value))) 'value remark 'follow-link t 'face '(:inherit link :background "yellow")))) (dolist (b fun-buttons) (let ((beg (nth 0 b)) (end (nth 1 b)) (fun (nth 2 b))) (make-text-button beg end 'value fun 'action (lambda(button) (interactive) (describe-function (button-get button 'value))) 'follow-link t 'face '(:inherit link :background "yellow")))) (make-text-button link-beg link-end 'action (lambda(button) (interactive) (info "(elisp) Key Binding Conventions")) 'follow-link t 'face '(:inherit link :background "yellow"))))) (setq point-after-message (point)) (goto-char (point-min)) (set-buffer-modified-p nil)) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil))) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-07 0:01 ` Lennart Borgman @ 2006-07-07 19:31 ` Richard Stallman 2006-07-08 3:14 ` Giorgos Keramidas 2006-07-08 20:57 ` Richard Stallman 2 siblings, 0 replies; 29+ messages in thread From: Richard Stallman @ 2006-07-07 19:31 UTC (permalink / raw) Cc: emacs-devel Could you send the change log entry for this change? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-07 0:01 ` Lennart Borgman 2006-07-07 19:31 ` Richard Stallman @ 2006-07-08 3:14 ` Giorgos Keramidas 2006-07-08 20:57 ` Richard Stallman 2 siblings, 0 replies; 29+ messages in thread From: Giorgos Keramidas @ 2006-07-08 3:14 UTC (permalink / raw) Cc: emacs-devel Lennart Borgman <lennart.borgman.073@student.lu.se> wrote: > > Here is a new version of help-with-tutorial then. I have added some > information instead that could be useful: > > (defun help-describe-nonstandard-key(value) > ... > (when map > (if (eq map global-map) > (setq mapsym 'global-map) > (mapatoms (lambda (s) > (when (and (boundp s) > (keymapp (symbol-value s))) > (unless (eq s 'map) > (when (equal map (symbol-value s)) > (when (member map (current-active-maps)) > (setq mapsym s))))))))) Phew! That was a long patch :) Only a minor detail I noticed while trying to read it all: Isn't (when condition (when condition2 expr)) the same as: (when (and condition condition2) expr) The nested (unless c (when c1 (when c2))) stuff is also probably equivalent to: (when (and (not (eq s 'map)) (equal map (symbol-value s)) (member map (current-active-maps))) (setq mapsym s)) Then, there are also two (when c (when c2 ...)) expressions, where we can save yet another nesting level: (when (and (boundp s) (keymapp (symbol-value s)) (not (eq s 'map)) (equal map (symbol-value s)) (member map (current-active-maps))) (setq mapsym s)) unless I'm reading this in a very bogus manner :) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-07 0:01 ` Lennart Borgman 2006-07-07 19:31 ` Richard Stallman 2006-07-08 3:14 ` Giorgos Keramidas @ 2006-07-08 20:57 ` Richard Stallman 2006-07-09 8:44 ` Lennart Borgman 2006-07-17 16:12 ` Lennart Borgman 2 siblings, 2 replies; 29+ messages in thread From: Richard Stallman @ 2006-07-08 20:57 UTC (permalink / raw) Cc: emacs-devel ((eq (car value) 'cua-mode) (insert "You are using `cua-mode'." "You have enabled CUA mode" would be clearer. " If the region is not active then C-c will" " work as it normally does in Emacs.")) Please stick to present tense except when present tense is incorrect. Please understand that it is ok to change key bindings, but the tutorial may not work correctly. (See also " ) Change that to It is legitimate to change key bindings, but changed bindings do not correspond to what the tutorial says. (See also " ) This code (let (initial-bad-keys) (with-temp-buffer (insert-file (locate-library "bindings.el")) (let (expr key def-fun def-fun-txt rem-fun key-fun where remark ) (while (condition-case err (setq expr (read (current-buffer))) (error nil)) (cond ((and (eq (nth 0 expr) 'define-key) (eq (nth 1 expr) 'global-map)) (setq key (nth 2 expr)) (setq def-fun (nth 3 expr))) ((eq (nth 0 expr) 'global-set-key) (setq key (nth 1 expr)) (setq def-fun (nth 2 expr))) (t (setq key nil))) (when key (assert (eq (nth 0 def-fun) 'quote)) (setq def-fun (nth 1 def-fun)) (setq def-fun-txt (format "%s" def-fun)) (setq rem-fun (command-remapping def-fun)) (setq key-fun (key-binding key)) (setq where (where-is-internal (if rem-fun rem-fun def-fun))) (if where (setq where (key-description (car where))) (setq where "")) (setq remark nil) (unless (cond ( (eq key-fun def-fun) ... is awfully complex, and most of the job it does is irrelevant. The tutorial describes a small set of keys, perhaps 40. I think this code should not concern itself with keys that the tutorial does not teach. It should simply have a list of those keys and their standard bindings. That way it would not need to read bindings.el. (Not all the default bindings are in bindings.el, so this code won't get them all.) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-08 20:57 ` Richard Stallman @ 2006-07-09 8:44 ` Lennart Borgman 2006-07-17 16:12 ` Lennart Borgman 1 sibling, 0 replies; 29+ messages in thread From: Lennart Borgman @ 2006-07-09 8:44 UTC (permalink / raw) Cc: emacs-devel Richard Stallman wrote: > ((eq (car value) 'cua-mode) > (insert "You are using `cua-mode'." > > "You have enabled CUA mode" would be clearer. > > " If the region is not active then C-c will" > " work as it normally does in Emacs.")) > > Please stick to present tense except when present tense is incorrect. > > Please understand that it is ok to change key bindings, but the > tutorial may not work correctly. (See also " ) > > Change that to > > It is legitimate to change key bindings, but changed bindings > do not correspond to what the tutorial says. (See also " ) > > > This code > > (let (initial-bad-keys) > (with-temp-buffer > ... > (unless > (cond ( (eq key-fun def-fun) > ... > > is awfully complex, and most of the job it does is irrelevant. The > tutorial describes a small set of keys, perhaps 40. I think this code > should not concern itself with keys that the tutorial does not teach. > > It should simply have a list of those keys and their standard > bindings. That way it would not need to read bindings.el. > > (Not all the default bindings are in bindings.el, so this code won't > get them all.) > I will fix these issues in a couple of days. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-08 20:57 ` Richard Stallman 2006-07-09 8:44 ` Lennart Borgman @ 2006-07-17 16:12 ` Lennart Borgman 2006-07-17 17:32 ` Lennart Borgman 1 sibling, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-07-17 16:12 UTC (permalink / raw) Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1109 bytes --] Richard Stallman wrote: > "You have enabled CUA mode" would be clearer. > > > Done. > Change that to > > It is legitimate to change key bindings, but changed bindings > do not correspond to what the tutorial says. (See also " ) > Done. > It should simply have a list of those keys and their standard > bindings. That way it would not need to read bindings.el. > I changed it to that (again). I send the changes both as a standalone file and a patch this time. I have added this: - The tutorial buffer is no longer associated with a file. I believe that is better. - The tutorial can easily be restarted. A check is made for changes. - The tutorial window is searched for. - If any of the key bindings mentioned in the tutorial is changed then a list with those changes are shown in a special area in the beginning of the tutorial buffer. - This area is read-only and have a yellow background. - I have tried to explain what has happened to the key bindings. There are links to the explanations. - I have taken special care of cua-mode (and a little bit of viper-mode too). [-- Attachment #2: help-tutorial5.el --] [-- Type: text/plain, Size: 21492 bytes --] (defun help--describe-nonstandard-key(value) (let ((maps (current-active-maps t))) (with-output-to-temp-buffer (help-buffer) (help-setup-xref (list #'help-describe-nonstandard-key value) (interactive-p)) (with-current-buffer (help-buffer) (insert "Emacs default key binding has been changed in your setup:\n\n") (let ((inhibit-read-only t)) (cond ((eq (car value) 'cua-mode) (insert "You have enabled `cua-mode'. When `cua-mode' is enabled, you can use C-z, C-x, C-c, and C-v to undo, cut, copy, and paste in addition to the normal Emacs bindings. The C-x and C-c keys only do cut and copy when the region is active, so in most cases, they do not conflict with the normal function of these prefix keys. If you really need to perform a command which starts with one of the prefix keys even when the region is active, you have three options: - press the prefix key twice very quickly (within 0.2 seconds), - press the prefix key and the following key within 0.2 seconds, or - use the SHIFT key with the prefix key, i.e. C-S-x or C-S-c.")) ((eq (car value) 'current-binding) (let ((cb (nth 1 value)) (db (nth 2 value)) (key (nth 3 value)) (where (nth 4 value)) map mapsym) ;; Try to find the map where the binding occurs (while maps (let* ((m (car maps)) (mb (lookup-key m key t))) (setq maps (cdr maps)) (when (eq mb cb) (setq map m) (setq maps nil)))) (when map (if (eq map global-map) (setq mapsym 'global-map) (mapatoms (lambda (s) (when (and (boundp s) (keymapp (symbol-value s))) (unless (eq s 'map) (when (equal map (symbol-value s)) (when (member map (current-active-maps)) (setq mapsym s))))))))) (insert "Emacs default binding for the key " (key-description key) " is the function `") (insert (format "%s" db)) (insert "'. " "This key has however been rebound to the function `") (insert (format "%s" cb)) (insert "'.") (when mapsym (insert " This binding is in the keymap variable `") (insert (format "%s" mapsym)) (insert "'.")) (if (string= where "") (unless (keymapp db) (insert "\n\nYou can use M-x " (format "%s" db) " RET instead.")) (insert "\n\nWith you current key bindings" " you can use the key " where " to get the function `" (format "%s" db) "'.")) )))) (fill-region (point-min)(point)) (print-help-return-message))))) ;;;###autoload (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") (let* ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) (filename (get-language-info lang 'tutorial)) (tut-buf-name (concat "TUTORIAL (" lang ")")) (old-tut-buf (get-buffer tut-buf-name)) (old-tut-win (when old-tut-buf (get-buffer-window old-tut-buf t))) (old-tut-is-ok (when old-tut-buf (not (buffer-modified-p old-tut-buf)))) (point-after-message 1)) (when old-tut-win (raise-frame (window-frame (select-window (get-buffer-window old-tut-buf t))))) (when (and old-tut-buf (not old-tut-is-ok)) (setq old-tut-is-ok (not (y-or-n-p "You have changed the Tutorial buffer. Revert it? ")))) (delete-other-windows) (if old-tut-is-ok (switch-to-buffer (get-buffer tut-buf-name)) (switch-to-buffer (get-buffer-create tut-buf-name)) (let ((inhibit-read-only t)) (erase-buffer)) (message "Preparing tutorial ...")(sit-for 0) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (hack-local-variables) ;; Check if there are key bindings that may disturb the ;; tutorial. If so tell the user. (let* (changed-keys (suspend-emacs (if window-system 'iconify-or-deiconify-frame 'suspend-emacs)) (default-keys '( ;; These are not mentioned but are basic: (ESC-prefix [27]) (Control-X-prefix [?\C-x]) (mode-specific-command-prefix [?\C-c]) (save-buffers-kill-emacs [?\C-x ?\C-c]) ;; * SUMMARY (scroll-up [?\C-v]) (scroll-down [?\M-v]) (recenter [?\C-l]) ;; * BASIC CURSOR CONTROL (forward-char [?\C-f]) (backward-char [?\C-b]) (forward-word [?\M-f]) (backward-word [?\M-b]) (next-line [?\C-n]) (previous-line [?\C-p]) (move-beginning-of-line [?\C-a]) (move-end-of-line [?\C-e]) (backward-sentence [?\M-a]) (forward-sentence [?\M-e]) (beginning-of-buffer [?\M-<]) (end-of-buffer [?\M->]) (universal-argument [?\C-u]) ;; * WHEN EMACS IS HUNG (keyboard-quit [?\C-g]) ;; * DISABLED COMMANDS (downcase-region [?\C-x ?\C-l]) ;; * WINDOWS (delete-other-windows [?\C-x ?1]) ;; C-u 0 C-l ;; Type CONTROL-h k CONTROL-f. ;; * INSERTING AND DELETING ;; C-u 8 * to insert ********. (delete-backward-char [backspace]) (delete-char [?\C-d]) (backward-kill-word [(meta backspace)]) (kill-word [?\M-d]) (kill-line [?\C-k]) (kill-sentence [?\M-k]) (set-mark-command [?\C-@]) (set-mark-command [?\C- ]) (kill-region [?\C-w]) (yank [?\C-y]) (yank-pop [?\M-y]) ;; * UNDO (advertised-undo [?\C-x ?u]) (advertised-undo [?\C-x ?u]) ;; * FILES (find-file [?\C-x ?\C-f]) (save-buffer [?\C-x ?\C-s]) ;; * BUFFERS (list-buffers [?\C-x ?\C-b]) (switch-to-buffer [?\C-x ?b]) (save-some-buffers [?\C-x ?s]) ;; * EXTENDING THE COMMAND SET ;; C-x Character eXtend. Followed by one character. (execute-extended-command [?\M-x]) ;; C-x C-f Find file ;; C-x C-s Save file ;; C-x s Save some buffers ;; C-x C-b List buffers ;; C-x b Switch buffer ;; C-x C-c Quit Emacs ;; C-x 1 Delete all but one window ;; C-x u Undo ;; * MODE LINE (describe-mode [?\C-h ?m]) (set-fill-column [?\C-x ?f]) (fill-paragraph [?\M-q]) ;; * SEARCHING (isearch-forward [?\C-s]) (isearch-backward [?\C-r]) ;; * MULTIPLE WINDOWS (split-window-vertically [?\C-x ?2]) (scroll-other-window [?\C-\M-v]) (other-window [?\C-x ?o]) (find-file-other-window [?\C-x ?4 ?\C-f]) ;; * RECURSIVE EDITING LEVELS (keyboard-escape-quit [27 27 27]) ;; * GETTING MORE HELP ;; The most basic HELP feature is C-h c (describe-key-briefly [?\C-h ?c]) (describe-key [?\C-h ?k]) ;; * MORE FEATURES ;; F10 ;; * CONCLUSION (iconify-or-deiconify-frame [?\C-z]) )) (sort-keys (lambda(left right) (let ((x (append (cadr left) nil)) (y (append (cadr right) nil))) (while (and x y (equal (car x) (car y))) (setq x (cdr x)) (setq y (cdr y))) (let ((cx (car x)) (cy (car y))) (cond ((and (listp cx) (listp cy)) (> (length cx)(length cy))) ((listp cx) nil) ((listp cy) t) ((and (symbolp cx) (symbolp cy)) (string< (symbol-name cy) (symbol-name cx))) ((symbolp cx) nil) ((symbolp cy) t) (t (> (car x)(car y)))))))) (tab-map (let ((map (make-sparse-keymap))) (define-key map [tab] 'forward-button) (define-key map [(shift tab)] 'backward-button) (define-key map [(meta tab)] 'backward-button) map))) (setq default-keys (sort default-keys sort-keys)) (let (expr key def-fun def-fun-txt rem-fun key-fun where remark ) (dolist (kdf default-keys) (setq key (nth 1 kdf)) (setq def-fun (nth 0 kdf)) (setq def-fun-txt (format "%s" def-fun)) (setq rem-fun (command-remapping def-fun)) (setq key-fun (key-binding key)) (setq where (where-is-internal (if rem-fun rem-fun def-fun))) (if where (progn (setq where (key-description (car where))) (when (and (< 10 (length where)) (string= (substring where 0 (length "<menu-bar>")) "<menu-bar>")) (setq where "The menus"))) (setq where "")) (setq remark nil) (unless (cond ( (eq key-fun def-fun) t) ( (eq key-fun (command-remapping def-fun)) (setq remark (list "Remapped" nil)) t) ;; cua-mode specials: ( (and cua-mode (or (and (equal key [?\C-v]) (eq key-fun 'cua-paste)) (and (equal key [?\C-z]) (eq key-fun 'undo)))) (setq remark (list "cua-mode, more info" 'cua-mode)) nil) ( (and cua-mode (or (and (eq def-fun 'ESC-prefix) (equal key-fun `(keymap (118 . cua-repeat-replace-region)))) (and (eq def-fun 'mode-specific-command-prefix) (equal key-fun '(keymap (timeout . copy-region-as-kill)))) (and (eq def-fun 'Control-X-prefix) (equal key-fun '(keymap (timeout . kill-region)))))) (setq remark (list "cua-mode replacement" 'cua-mode)) (cond ((eq def-fun 'mode-specific-command-prefix) (setq def-fun-txt "\"C-c prefix\"")) ((eq def-fun 'Control-X-prefix) (setq def-fun-txt "\"C-x prefix\"")) ((eq def-fun 'ESC-prefix) (setq def-fun-txt "\"ESC prefix\""))) (setq where "Same key") nil) ;; viper-mode specials: ( (and viper-mode (eq viper-current-state 'vi-state) (or (and (eq def-fun 'isearch-forward) (eq key-fun 'viper-isearch-forward)) (and (eq def-fun 'isearch-backward) (eq key-fun 'viper-isearch-backward)))) t) ;; The strange handling of C-delete and ;; C-backspace: ( (when normal-erase-is-backspace (or (and (equal key [C-delete]) (equal key-fun 'kill-word)) (and (equal key [C-backspace]) (equal key-fun 'backward-kill-word)))) t) ( t (setq remark (list "more info" 'current-binding key-fun def-fun key where)) nil)) (add-to-list 'changed-keys (list key def-fun def-fun-txt where remark))))) (message "")(sit-for 0) (when changed-keys (forward-line) (let ((start (point)) end) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However when you started the tutorial the following key bindings used in the tutorial had been changed from Emacs default:\n\n" ) (let ((frm " %-9s %-27s %-11s %s\n")) (insert (format frm "KEY" "DEFAULT BINDING" "IS NOW ON" "REMARK"))) (dolist (tk changed-keys) (let* ((def-fun (nth 1 tk)) (key (nth 0 tk)) (def-fun-txt (nth 2 tk)) (where (nth 3 tk)) (remark (nth 4 tk)) (rem-fun (command-remapping def-fun)) (key-txt (key-description key)) (key-fun (key-binding key)) tot-len) (unless (eq def-fun key-fun) (insert " " key-txt " ") (setq tot-len (length key-txt)) (when (> 9 tot-len) (insert (make-string (- 9 tot-len) ? )) (setq tot-len 9)) (insert-button def-fun-txt 'value def-fun 'action (lambda(button) (interactive) (describe-function (button-get button 'value))) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (setq tot-len (+ tot-len (length def-fun-txt))) (when (> 36 tot-len) (insert (make-string (- 36 tot-len) ? ))) (when (listp where) (setq where "list")) (insert (format " %-11s " where)) (insert-button (car remark) 'action (lambda(b) (interactive) (let ((value (button-get b 'value))) (help--describe-nonstandard-key value))) 'value (cdr remark) 'follow-link t 'face '(:inherit link :background "yellow")) (insert "\n")))) (when (and (boundp 'viper-mode) viper-mode) (cond ((eq viper-current-state 'emacs-state) (insert " You have enabled viper mode, but in the tutorial buffer viper mode is currently turned off.")) (t (insert " You have enabled viper mode. Some Emacs default key bindings will be unavailable. This is dependent on the state Viper is in."))) (insert "\n If you want to learn viper keys please see the ") (insert-button "viper manual" 'action (lambda(button) (interactive) (info-other-window "(viper)") (message "Type C-x 0 to close the new window")) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (insert ".\n")) (insert " It is legitimate to change key bindings, but changed bindings do not correspond to what the tutorial says. (See also " ) (insert-button "Key Binding Conventions" 'action (lambda(button) (interactive) (info-other-window "(elisp) Key Binding Conventions") (message "Type C-x 0 to close the new window")) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (insert ".)\n\n") (setq end (point)) (put-text-property start end 'face ;;'font-lock-warning-face (list :background "yellow" :foreground "#c00")) (put-text-property start end 'local-map tab-map) (let ((inhibit-read-only t)) (put-text-property start end 'read-only t))))) (setq point-after-message (point)) (goto-char (point-min)) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) [-- Attachment #3: help-fns.diff --] [-- Type: text/plain, Size: 27187 bytes --] Index: help-fns.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v retrieving revision 1.90 diff -u -r1.90 help-fns.el --- help-fns.el 12 Jul 2006 15:58:10 -0000 1.90 +++ help-fns.el 17 Jul 2006 15:31:08 -0000 @@ -36,6 +36,83 @@ (require 'help-mode) +(defun help--describe-nonstandard-key(value) + (let ((maps (current-active-maps t))) + (with-output-to-temp-buffer (help-buffer) + (help-setup-xref (list #'help-describe-nonstandard-key value) + (interactive-p)) + (with-current-buffer (help-buffer) + (insert "Emacs default key binding has been changed in your setup:\n\n") + (let ((inhibit-read-only t)) + (cond + ((eq (car value) 'cua-mode) + (insert + "You have enabled `cua-mode'. + +When `cua-mode' is enabled, you can use C-z, C-x, C-c, and C-v to +undo, cut, copy, and paste in addition to the normal Emacs +bindings. The C-x and C-c keys only do cut and copy when the +region is active, so in most cases, they do not conflict with the +normal function of these prefix keys. + +If you really need to perform a command which starts with one of +the prefix keys even when the region is active, you have three +options: +- press the prefix key twice very quickly (within 0.2 seconds), +- press the prefix key and the following key within 0.2 seconds, or +- use the SHIFT key with the prefix key, i.e. C-S-x or C-S-c.")) + ((eq (car value) 'current-binding) + (let ((cb (nth 1 value)) + (db (nth 2 value)) + (key (nth 3 value)) + (where (nth 4 value)) + map + mapsym) + ;; Try to find the map where the binding occurs + (while maps + (let* ((m (car maps)) + (mb (lookup-key m key t))) + (setq maps (cdr maps)) + (when (eq mb cb) + (setq map m) + (setq maps nil)))) + (when map + (if (eq map global-map) + (setq mapsym 'global-map) + (mapatoms (lambda (s) + (when (and (boundp s) + (keymapp (symbol-value s))) + (unless (eq s 'map) + (when (equal map (symbol-value s)) + (when (member map (current-active-maps)) + (setq mapsym s))))))))) + (insert "Emacs default binding for the key " + (key-description key) + " is the function `") + (insert (format "%s" db)) + (insert "'. " + "This key has however been rebound to the function `") + (insert (format "%s" cb)) + (insert "'.") + (when mapsym + (insert " This binding is in the keymap variable `") + (insert (format "%s" mapsym)) + (insert "'.")) + (if (string= where "") + (unless (keymapp db) + (insert "\n\nYou can use M-x " + (format "%s" db) + " RET instead.")) + (insert "\n\nWith you current key bindings" + " you can use the key " + where + " to get the function `" + (format "%s" db) + "'.")) + )))) + (fill-region (point-min)(point)) + (print-help-return-message))))) + ;;;###autoload (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. @@ -44,58 +121,449 @@ If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") - (let ((lang (if arg - (let ((minibuffer-setup-hook minibuffer-setup-hook)) - (add-hook 'minibuffer-setup-hook - 'minibuffer-completion-help) - (read-language-name 'tutorial "Language: " "English")) - (if (get-language-info current-language-environment 'tutorial) - current-language-environment - "English"))) - file filename) - (setq filename (get-language-info lang 'tutorial)) - (setq file (expand-file-name (concat "~/" filename))) + (let* ((lang (if arg + (let ((minibuffer-setup-hook minibuffer-setup-hook)) + (add-hook 'minibuffer-setup-hook + 'minibuffer-completion-help) + (read-language-name 'tutorial "Language: " "English")) + (if (get-language-info current-language-environment 'tutorial) + current-language-environment + "English"))) + (filename (get-language-info lang 'tutorial)) + (tut-buf-name (concat "TUTORIAL (" lang ")")) + (old-tut-buf (get-buffer tut-buf-name)) + (old-tut-win (when old-tut-buf (get-buffer-window old-tut-buf t))) + (old-tut-is-ok (when old-tut-buf + (not (buffer-modified-p old-tut-buf)))) + (point-after-message 1)) + (when old-tut-win + (raise-frame + (window-frame + (select-window (get-buffer-window old-tut-buf t))))) + (when (and old-tut-buf + (not old-tut-is-ok)) + (setq old-tut-is-ok + (not (y-or-n-p + "You have changed the Tutorial buffer. Revert it? ")))) (delete-other-windows) - (if (get-file-buffer file) - (switch-to-buffer (get-file-buffer file)) - (switch-to-buffer (create-file-buffer file)) - (setq buffer-file-name file) + (if old-tut-is-ok + (switch-to-buffer (get-buffer tut-buf-name)) + (switch-to-buffer (get-buffer-create tut-buf-name)) + (let ((inhibit-read-only t)) + (erase-buffer)) + (message "Preparing tutorial ...")(sit-for 0) + (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (hack-local-variables) + + + ;; Check if there are key bindings that may disturb the + ;; tutorial. If so tell the user. + (let* (changed-keys + (suspend-emacs (if window-system + 'iconify-or-deiconify-frame + 'suspend-emacs)) + (default-keys + '( + ;; These are not mentioned but are basic: + (ESC-prefix [27]) + (Control-X-prefix [?\C-x]) + (mode-specific-command-prefix [?\C-c]) + + (save-buffers-kill-emacs [?\C-x ?\C-c]) + + + ;; * SUMMARY + (scroll-up [?\C-v]) + (scroll-down [?\M-v]) + (recenter [?\C-l]) + + + ;; * BASIC CURSOR CONTROL + (forward-char [?\C-f]) + (backward-char [?\C-b]) + + (forward-word [?\M-f]) + (backward-word [?\M-b]) + + (next-line [?\C-n]) + (previous-line [?\C-p]) + + (move-beginning-of-line [?\C-a]) + (move-end-of-line [?\C-e]) + + (backward-sentence [?\M-a]) + (forward-sentence [?\M-e]) + + + (beginning-of-buffer [?\M-<]) + (end-of-buffer [?\M->]) + + (universal-argument [?\C-u]) + + + ;; * WHEN EMACS IS HUNG + (keyboard-quit [?\C-g]) + + + ;; * DISABLED COMMANDS + (downcase-region [?\C-x ?\C-l]) + + + ;; * WINDOWS + (delete-other-windows [?\C-x ?1]) + ;; C-u 0 C-l + ;; Type CONTROL-h k CONTROL-f. + + + ;; * INSERTING AND DELETING + ;; C-u 8 * to insert ********. + + (delete-backward-char [backspace]) + (delete-char [?\C-d]) + + (backward-kill-word [(meta backspace)]) + (kill-word [?\M-d]) + + (kill-line [?\C-k]) + (kill-sentence [?\M-k]) + + (set-mark-command [?\C-@]) + (set-mark-command [?\C- ]) + (kill-region [?\C-w]) + (yank [?\C-y]) + (yank-pop [?\M-y]) + + + ;; * UNDO + (advertised-undo [?\C-x ?u]) + (advertised-undo [?\C-x ?u]) + + + ;; * FILES + (find-file [?\C-x ?\C-f]) + (save-buffer [?\C-x ?\C-s]) + + + ;; * BUFFERS + (list-buffers [?\C-x ?\C-b]) + (switch-to-buffer [?\C-x ?b]) + (save-some-buffers [?\C-x ?s]) + + + ;; * EXTENDING THE COMMAND SET + ;; C-x Character eXtend. Followed by one character. + (execute-extended-command [?\M-x]) + + ;; C-x C-f Find file + ;; C-x C-s Save file + ;; C-x s Save some buffers + ;; C-x C-b List buffers + ;; C-x b Switch buffer + ;; C-x C-c Quit Emacs + ;; C-x 1 Delete all but one window + ;; C-x u Undo + + + ;; * MODE LINE + (describe-mode [?\C-h ?m]) + + (set-fill-column [?\C-x ?f]) + (fill-paragraph [?\M-q]) + + + ;; * SEARCHING + (isearch-forward [?\C-s]) + (isearch-backward [?\C-r]) + + + ;; * MULTIPLE WINDOWS + (split-window-vertically [?\C-x ?2]) + (scroll-other-window [?\C-\M-v]) + (other-window [?\C-x ?o]) + (find-file-other-window [?\C-x ?4 ?\C-f]) + + + ;; * RECURSIVE EDITING LEVELS + (keyboard-escape-quit [27 27 27]) + + + ;; * GETTING MORE HELP + ;; The most basic HELP feature is C-h c + (describe-key-briefly [?\C-h ?c]) + (describe-key [?\C-h ?k]) + + + ;; * MORE FEATURES + ;; F10 + + + ;; * CONCLUSION + (iconify-or-deiconify-frame [?\C-z]) + )) + (sort-keys + (lambda(left right) + (let ((x (append (cadr left) nil)) + (y (append (cadr right) nil))) + (while (and x y + (equal (car x) (car y))) + (setq x (cdr x)) + (setq y (cdr y))) + (let ((cx (car x)) + (cy (car y))) + (cond ((and (listp cx) + (listp cy)) + (> (length cx)(length cy))) + ((listp cx) + nil) + ((listp cy) + t) + ((and (symbolp cx) + (symbolp cy)) + (string< (symbol-name cy) + (symbol-name cx))) + ((symbolp cx) + nil) + ((symbolp cy) + t) + (t + (> (car x)(car y)))))))) + (tab-map (let ((map (make-sparse-keymap))) + (define-key map [tab] 'forward-button) + (define-key map [(shift tab)] 'backward-button) + (define-key map [(meta tab)] 'backward-button) + map))) + (setq default-keys (sort default-keys sort-keys)) + + (let (expr + key + def-fun + def-fun-txt + rem-fun + key-fun + where + remark + ) + (dolist (kdf default-keys) + (setq key (nth 1 kdf)) + (setq def-fun (nth 0 kdf)) + (setq def-fun-txt (format "%s" def-fun)) + (setq rem-fun (command-remapping def-fun)) + (setq key-fun (key-binding key)) + (setq where (where-is-internal (if rem-fun rem-fun def-fun))) + (if where + (progn + (setq where (key-description (car where))) + (when (and (< 10 (length where)) + (string= (substring where 0 (length "<menu-bar>")) + "<menu-bar>")) + (setq where "The menus"))) + (setq where "")) + (setq remark nil) + (unless + (cond ( (eq key-fun def-fun) + t) + ( (eq key-fun (command-remapping def-fun)) + (setq remark (list "Remapped" nil)) + t) + ;; cua-mode specials: + ( (and cua-mode + (or (and + (equal key [?\C-v]) + (eq key-fun 'cua-paste)) + (and + (equal key [?\C-z]) + (eq key-fun 'undo)))) + (setq remark (list "cua-mode, more info" 'cua-mode)) + nil) + ( (and cua-mode + (or + (and (eq def-fun 'ESC-prefix) + (equal key-fun + `(keymap + (118 . cua-repeat-replace-region)))) + (and (eq def-fun 'mode-specific-command-prefix) + (equal key-fun + '(keymap + (timeout . copy-region-as-kill)))) + (and (eq def-fun 'Control-X-prefix) + (equal key-fun + '(keymap (timeout . kill-region)))))) + (setq remark (list "cua-mode replacement" 'cua-mode)) + (cond + ((eq def-fun 'mode-specific-command-prefix) + (setq def-fun-txt "\"C-c prefix\"")) + ((eq def-fun 'Control-X-prefix) + (setq def-fun-txt "\"C-x prefix\"")) + ((eq def-fun 'ESC-prefix) + (setq def-fun-txt "\"ESC prefix\""))) + (setq where "Same key") + nil) + ;; viper-mode specials: + ( (and viper-mode + (eq viper-current-state 'vi-state) + (or (and (eq def-fun 'isearch-forward) + (eq key-fun 'viper-isearch-forward)) + (and (eq def-fun 'isearch-backward) + (eq key-fun 'viper-isearch-backward)))) + t) + ;; The strange handling of C-delete and + ;; C-backspace: + ( (when normal-erase-is-backspace + (or (and (equal key [C-delete]) + (equal key-fun 'kill-word)) + (and (equal key [C-backspace]) + (equal key-fun 'backward-kill-word)))) + t) + ( t + (setq remark + (list "more info" 'current-binding + key-fun def-fun key where)) + nil)) + (add-to-list 'changed-keys + (list key def-fun def-fun-txt where remark))))) + + (message "")(sit-for 0) + (when changed-keys + (forward-line) + (let ((start (point)) + end) + (insert " + NOTICE: One of the main purposes of the tutorial is that You should + be able to learn some important Emacs default key bindings. However + when you started the tutorial the following key bindings used in the + tutorial had been changed from Emacs default:\n\n" ) + (let ((frm " %-9s %-27s %-11s %s\n")) + (insert (format frm "KEY" "DEFAULT BINDING" "IS NOW ON" "REMARK"))) + (dolist (tk changed-keys) + (let* ((def-fun (nth 1 tk)) + (key (nth 0 tk)) + (def-fun-txt (nth 2 tk)) + (where (nth 3 tk)) + (remark (nth 4 tk)) + (rem-fun (command-remapping def-fun)) + (key-txt (key-description key)) + (key-fun (key-binding key)) + tot-len) + (unless (eq def-fun key-fun) + (insert " " key-txt " ") + (setq tot-len (length key-txt)) + (when (> 9 tot-len) + (insert (make-string (- 9 tot-len) ? )) + (setq tot-len 9)) + (insert-button def-fun-txt + 'value def-fun + 'action + (lambda(button) (interactive) + (describe-function + (button-get button 'value))) + 'follow-link t + 'read-only t + 'face '(:inherit link + :background "yellow")) + (setq tot-len (+ tot-len (length def-fun-txt))) + (when (> 36 tot-len) + (insert (make-string (- 36 tot-len) ? ))) + (when (listp where) + (setq where "list")) + (insert (format " %-11s " where)) + (insert-button (car remark) + 'action + (lambda(b) (interactive) + (let ((value (button-get b 'value))) + (help--describe-nonstandard-key value))) + 'value (cdr remark) + 'follow-link t + 'face '(:inherit link + :background "yellow")) + (insert "\n")))) + + (when (and (boundp 'viper-mode) + viper-mode) + (cond + ((eq viper-current-state 'emacs-state) + (insert " + You have enabled viper mode, but in the tutorial buffer viper + mode is currently turned off.")) + (t + (insert " + You have enabled viper mode. Some Emacs default key bindings + will be unavailable. This is dependent on the state Viper is + in."))) + (insert "\n If you want to learn viper keys please see the ") + (insert-button "viper manual" + 'action + (lambda(button) (interactive) + (info-other-window "(viper)") + (message "Type C-x 0 to close the new window")) + 'follow-link t + 'read-only t + 'face '(:inherit link + :background "yellow")) + (insert ".\n")) + + (insert " + It is legitimate to change key bindings, but changed bindings do not + correspond to what the tutorial says. (See also " ) + (insert-button "Key Binding Conventions" + 'action + (lambda(button) (interactive) + (info-other-window + "(elisp) Key Binding Conventions") + (message "Type C-x 0 to close the new window")) + 'follow-link t + 'read-only t + 'face '(:inherit link + :background "yellow")) + (insert ".)\n\n") + (setq end (point)) + (put-text-property start end + 'face + ;;'font-lock-warning-face + (list :background "yellow" + :foreground "#c00")) + (put-text-property start end 'local-map tab-map) + (let ((inhibit-read-only t)) + (put-text-property start end 'read-only t))))) + + (setq point-after-message (point)) + + (goto-char (point-min)) + (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion - (forward-line 1) - (looking-at "\\[")) - (delete-region (point) (progn (forward-line 1) (point)))) - ((looking-at "<<Blank lines inserted.*>>") - (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) - (t - (looking-at "<<") - (replace-match "[") - (search-forward ">>") - (replace-match "]"))) + (forward-line 1) + (looking-at "\\[")) + (delete-region (point) (progn (forward-line 1) (point)))) + ((looking-at "<<Blank lines inserted.*>>") + (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) + (t + (looking-at "<<") + (replace-match "[") + (search-forward ">>") + (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) - (count-lines (point-min) (point)) - 6))) - (if (< n 8) - (progn - ;; For a short gap, we don't need the [...] line, - ;; so delete it. - (delete-region (point) (progn (end-of-line) (point))) - (newline n)) - ;; Some people get confused by the large gap. - (newline (/ n 2)) - - ;; Skip the [...] line (don't delete it). - (forward-line 1) - (newline (- n (/ n 2))))) + (count-lines (point-min) (point)) + 6))) + (if (< n 8) + (progn + ;; For a short gap, we don't need the [...] line, + ;; so delete it. + (delete-region (point) (progn (end-of-line) (point))) + (newline n)) + ;; Some people get confused by the large gap. + (newline (/ n 2)) + + ;; Skip the [...] line (don't delete it). + (forward-line 1) + (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) @@ -252,8 +720,8 @@ "\\)" "\\(?:es\\|s\\|th\\)?" ; for ARGth, ARGs "\\(?:-[a-z0-9-]+\\)?" ; for ARG-xxx, ARG-n - "\\(?:-[{([<`\"].*?\\)?"; for ARG-{x}, (x), <x>, [x], `x' - "\\>") ; end of word + "\\(?:-[{([<`\"].*?\\)?" ; for ARG-{x}, (x), <x>, [x], `x' + "\\>") ; end of word (help-default-arg-highlight arg) doc t t 1))))) @@ -419,23 +887,23 @@ ;; If definition is a keymap, skip arglist note. (unless (keymapp def) (let* ((use (cond - (usage (setq doc (cdr usage)) (car usage)) - ((listp arglist) - (format "%S" (help-make-usage function arglist))) - ((stringp arglist) arglist) - ;; Maybe the arglist is in the docstring of the alias. - ((let ((fun function)) - (while (and (symbolp fun) - (setq fun (symbol-function fun)) - (not (setq usage (help-split-fundoc - (documentation fun) - function))))) - usage) - (car usage)) - ((or (stringp def) - (vectorp def)) - (format "\nMacro: %s" (format-kbd-macro def))) - (t "[Missing arglist. Please make a bug report.]"))) + (usage (setq doc (cdr usage)) (car usage)) + ((listp arglist) + (format "%S" (help-make-usage function arglist))) + ((stringp arglist) arglist) + ;; Maybe the arglist is in the docstring of the alias. + ((let ((fun function)) + (while (and (symbolp fun) + (setq fun (symbol-function fun)) + (not (setq usage (help-split-fundoc + (documentation fun) + function))))) + usage) + (car usage)) + ((or (stringp def) + (vectorp def)) + (format "\nMacro: %s" (format-kbd-macro def))) + (t "[Missing arglist. Please make a bug report.]"))) (high (help-highlight-arguments use doc))) (let ((fill-begin (point))) (insert (car high) "\n") @@ -628,8 +1096,8 @@ ;; Mention if it's an alias (let* ((alias (condition-case nil - (indirect-variable variable) - (error variable))) + (indirect-variable variable) + (error variable))) (obsolete (get variable 'byte-obsolete-variable)) (safe-var (get variable 'safe-local-variable)) (doc (or (documentation-property variable 'variable-documentation) [-- Attachment #4: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-17 16:12 ` Lennart Borgman @ 2006-07-17 17:32 ` Lennart Borgman 2006-07-24 14:42 ` Richard Stallman 0 siblings, 1 reply; 29+ messages in thread From: Lennart Borgman @ 2006-07-17 17:32 UTC (permalink / raw) Cc: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 237 bytes --] Lennart Borgman wrote: > I send the changes both as a standalone file and a patch this time. I > have added this: There was a small problem with variables. Sending the standalone file again only since this message will be quite big. [-- Attachment #2: help-tutorial5.el --] [-- Type: text/plain, Size: 21542 bytes --] (defun help--describe-nonstandard-key(value) (let ((maps (current-active-maps t))) (with-output-to-temp-buffer (help-buffer) (help-setup-xref (list #'help-describe-nonstandard-key value) (interactive-p)) (with-current-buffer (help-buffer) (insert "Emacs default key binding has been changed in your setup:\n\n") (let ((inhibit-read-only t)) (cond ((eq (car value) 'cua-mode) (insert "You have enabled `cua-mode'. When `cua-mode' is enabled, you can use C-z, C-x, C-c, and C-v to undo, cut, copy, and paste in addition to the normal Emacs bindings. The C-x and C-c keys only do cut and copy when the region is active, so in most cases, they do not conflict with the normal function of these prefix keys. If you really need to perform a command which starts with one of the prefix keys even when the region is active, you have three options: - press the prefix key twice very quickly (within 0.2 seconds), - press the prefix key and the following key within 0.2 seconds, or - use the SHIFT key with the prefix key, i.e. C-S-x or C-S-c.")) ((eq (car value) 'current-binding) (let ((cb (nth 1 value)) (db (nth 2 value)) (key (nth 3 value)) (where (nth 4 value)) map mapsym) ;; Try to find the map where the binding occurs (while maps (let* ((m (car maps)) (mb (lookup-key m key t))) (setq maps (cdr maps)) (when (eq mb cb) (setq map m) (setq maps nil)))) (when map (if (eq map global-map) (setq mapsym 'global-map) (mapatoms (lambda (s) (when (and (boundp s) (keymapp (symbol-value s))) (unless (eq s 'map) (when (equal map (symbol-value s)) (when (member map (current-active-maps)) (setq mapsym s))))))))) (insert "Emacs default binding for the key " (key-description key) " is the function `") (insert (format "%s" db)) (insert "'. " "This key has however been rebound to the function `") (insert (format "%s" cb)) (insert "'.") (when mapsym (insert " This binding is in the keymap variable `") (insert (format "%s" mapsym)) (insert "'.")) (if (string= where "") (unless (keymapp db) (insert "\n\nYou can use M-x " (format "%s" db) " RET instead.")) (insert "\n\nWith you current key bindings" " you can use the key " where " to get the function `" (format "%s" db) "'.")) )))) (fill-region (point-min)(point)) (print-help-return-message))))) ;;;###autoload (defun help-with-tutorial (&optional arg) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language." (interactive "P") (let* ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) (filename (get-language-info lang 'tutorial)) (tut-buf-name (concat "TUTORIAL (" lang ")")) (old-tut-buf (get-buffer tut-buf-name)) (old-tut-win (when old-tut-buf (get-buffer-window old-tut-buf t))) (old-tut-is-ok (when old-tut-buf (not (buffer-modified-p old-tut-buf)))) (point-after-message 1)) (when old-tut-win (raise-frame (window-frame (select-window (get-buffer-window old-tut-buf t))))) (when (and old-tut-buf (not old-tut-is-ok)) (setq old-tut-is-ok (not (y-or-n-p "You have changed the Tutorial buffer. Revert it? ")))) (delete-other-windows) (if old-tut-is-ok (switch-to-buffer (get-buffer tut-buf-name)) (switch-to-buffer (get-buffer-create tut-buf-name)) (let ((inhibit-read-only t)) (erase-buffer)) (message "Preparing tutorial ...")(sit-for 0) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (hack-local-variables) ;; Check if there are key bindings that may disturb the ;; tutorial. If so tell the user. (let* (changed-keys (suspend-emacs (if window-system 'iconify-or-deiconify-frame 'suspend-emacs)) (default-keys '( ;; These are not mentioned but are basic: (ESC-prefix [27]) (Control-X-prefix [?\C-x]) (mode-specific-command-prefix [?\C-c]) (save-buffers-kill-emacs [?\C-x ?\C-c]) ;; * SUMMARY (scroll-up [?\C-v]) (scroll-down [?\M-v]) (recenter [?\C-l]) ;; * BASIC CURSOR CONTROL (forward-char [?\C-f]) (backward-char [?\C-b]) (forward-word [?\M-f]) (backward-word [?\M-b]) (next-line [?\C-n]) (previous-line [?\C-p]) (move-beginning-of-line [?\C-a]) (move-end-of-line [?\C-e]) (backward-sentence [?\M-a]) (forward-sentence [?\M-e]) (beginning-of-buffer [?\M-<]) (end-of-buffer [?\M->]) (universal-argument [?\C-u]) ;; * WHEN EMACS IS HUNG (keyboard-quit [?\C-g]) ;; * DISABLED COMMANDS (downcase-region [?\C-x ?\C-l]) ;; * WINDOWS (delete-other-windows [?\C-x ?1]) ;; C-u 0 C-l ;; Type CONTROL-h k CONTROL-f. ;; * INSERTING AND DELETING ;; C-u 8 * to insert ********. (delete-backward-char [backspace]) (delete-char [?\C-d]) (backward-kill-word [(meta backspace)]) (kill-word [?\M-d]) (kill-line [?\C-k]) (kill-sentence [?\M-k]) (set-mark-command [?\C-@]) (set-mark-command [?\C- ]) (kill-region [?\C-w]) (yank [?\C-y]) (yank-pop [?\M-y]) ;; * UNDO (advertised-undo [?\C-x ?u]) (advertised-undo [?\C-x ?u]) ;; * FILES (find-file [?\C-x ?\C-f]) (save-buffer [?\C-x ?\C-s]) ;; * BUFFERS (list-buffers [?\C-x ?\C-b]) (switch-to-buffer [?\C-x ?b]) (save-some-buffers [?\C-x ?s]) ;; * EXTENDING THE COMMAND SET ;; C-x Character eXtend. Followed by one character. (execute-extended-command [?\M-x]) ;; C-x C-f Find file ;; C-x C-s Save file ;; C-x s Save some buffers ;; C-x C-b List buffers ;; C-x b Switch buffer ;; C-x C-c Quit Emacs ;; C-x 1 Delete all but one window ;; C-x u Undo ;; * MODE LINE (describe-mode [?\C-h ?m]) (set-fill-column [?\C-x ?f]) (fill-paragraph [?\M-q]) ;; * SEARCHING (isearch-forward [?\C-s]) (isearch-backward [?\C-r]) ;; * MULTIPLE WINDOWS (split-window-vertically [?\C-x ?2]) (scroll-other-window [?\C-\M-v]) (other-window [?\C-x ?o]) (find-file-other-window [?\C-x ?4 ?\C-f]) ;; * RECURSIVE EDITING LEVELS (keyboard-escape-quit [27 27 27]) ;; * GETTING MORE HELP ;; The most basic HELP feature is C-h c (describe-key-briefly [?\C-h ?c]) (describe-key [?\C-h ?k]) ;; * MORE FEATURES ;; F10 ;; * CONCLUSION (iconify-or-deiconify-frame [?\C-z]) )) (sort-keys (lambda(left right) (let ((x (append (cadr left) nil)) (y (append (cadr right) nil))) (while (and x y (equal (car x) (car y))) (setq x (cdr x)) (setq y (cdr y))) (let ((cx (car x)) (cy (car y))) (cond ((and (listp cx) (listp cy)) (> (length cx)(length cy))) ((listp cx) nil) ((listp cy) t) ((and (symbolp cx) (symbolp cy)) (string< (symbol-name cy) (symbol-name cx))) ((symbolp cx) nil) ((symbolp cy) t) (t (> (car x)(car y)))))))) (tab-map (let ((map (make-sparse-keymap))) (define-key map [tab] 'forward-button) (define-key map [(shift tab)] 'backward-button) (define-key map [(meta tab)] 'backward-button) map))) (setq default-keys (sort default-keys sort-keys)) (let (expr key def-fun def-fun-txt rem-fun key-fun where remark ) (dolist (kdf default-keys) (setq key (nth 1 kdf)) (setq def-fun (nth 0 kdf)) (setq def-fun-txt (format "%s" def-fun)) (setq rem-fun (command-remapping def-fun)) (setq key-fun (key-binding key)) (setq where (where-is-internal (if rem-fun rem-fun def-fun))) (if where (progn (setq where (key-description (car where))) (when (and (< 10 (length where)) (string= (substring where 0 (length "<menu-bar>")) "<menu-bar>")) (setq where "The menus"))) (setq where "")) (setq remark nil) (unless (cond ( (eq key-fun def-fun) t) ( (eq key-fun (command-remapping def-fun)) (setq remark (list "Remapped" nil)) t) ;; cua-mode specials: ( (and cua-mode (or (and (equal key [?\C-v]) (eq key-fun 'cua-paste)) (and (equal key [?\C-z]) (eq key-fun 'undo)))) (setq remark (list "cua-mode, more info" 'cua-mode)) nil) ( (and cua-mode (or (and (eq def-fun 'ESC-prefix) (equal key-fun `(keymap (118 . cua-repeat-replace-region)))) (and (eq def-fun 'mode-specific-command-prefix) (equal key-fun '(keymap (timeout . copy-region-as-kill)))) (and (eq def-fun 'Control-X-prefix) (equal key-fun '(keymap (timeout . kill-region)))))) (setq remark (list "cua-mode replacement" 'cua-mode)) (cond ((eq def-fun 'mode-specific-command-prefix) (setq def-fun-txt "\"C-c prefix\"")) ((eq def-fun 'Control-X-prefix) (setq def-fun-txt "\"C-x prefix\"")) ((eq def-fun 'ESC-prefix) (setq def-fun-txt "\"ESC prefix\""))) (setq where "Same key") nil) ;; viper-mode specials: ( (and (boundp 'viper-mode) viper-mode (eq viper-current-state 'vi-state) (or (and (eq def-fun 'isearch-forward) (eq key-fun 'viper-isearch-forward)) (and (eq def-fun 'isearch-backward) (eq key-fun 'viper-isearch-backward)))) t) ;; The strange handling of C-delete and ;; C-backspace: ( (when normal-erase-is-backspace (or (and (equal key [C-delete]) (equal key-fun 'kill-word)) (and (equal key [C-backspace]) (equal key-fun 'backward-kill-word)))) t) ( t (setq remark (list "more info" 'current-binding key-fun def-fun key where)) nil)) (add-to-list 'changed-keys (list key def-fun def-fun-txt where remark))))) (message "")(sit-for 0) (when changed-keys (forward-line) (let ((start (point)) end) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However when you started the tutorial the following key bindings used in the tutorial had been changed from Emacs default:\n\n" ) (let ((frm " %-9s %-27s %-11s %s\n")) (insert (format frm "KEY" "DEFAULT BINDING" "IS NOW ON" "REMARK"))) (dolist (tk changed-keys) (let* ((def-fun (nth 1 tk)) (key (nth 0 tk)) (def-fun-txt (nth 2 tk)) (where (nth 3 tk)) (remark (nth 4 tk)) (rem-fun (command-remapping def-fun)) (key-txt (key-description key)) (key-fun (key-binding key)) tot-len) (unless (eq def-fun key-fun) (insert " " key-txt " ") (setq tot-len (length key-txt)) (when (> 9 tot-len) (insert (make-string (- 9 tot-len) ? )) (setq tot-len 9)) (insert-button def-fun-txt 'value def-fun 'action (lambda(button) (interactive) (describe-function (button-get button 'value))) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (setq tot-len (+ tot-len (length def-fun-txt))) (when (> 36 tot-len) (insert (make-string (- 36 tot-len) ? ))) (when (listp where) (setq where "list")) (insert (format " %-11s " where)) (insert-button (car remark) 'action (lambda(b) (interactive) (let ((value (button-get b 'value))) (help--describe-nonstandard-key value))) 'value (cdr remark) 'follow-link t 'face '(:inherit link :background "yellow")) (insert "\n")))) (when (and (boundp 'viper-mode) viper-mode) (cond ((eq viper-current-state 'emacs-state) (insert " You have enabled viper mode, but in the tutorial buffer viper mode is currently turned off.")) (t (insert " You have enabled viper mode. Some Emacs default key bindings will be unavailable. This is dependent on the state Viper is in."))) (insert "\n If you want to learn viper keys please see the ") (insert-button "viper manual" 'action (lambda(button) (interactive) (info-other-window "(viper)") (message "Type C-x 0 to close the new window")) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (insert ".\n")) (insert " It is legitimate to change key bindings, but changed bindings do not correspond to what the tutorial says. (See also " ) (insert-button "Key Binding Conventions" 'action (lambda(button) (interactive) (info-other-window "(elisp) Key Binding Conventions") (message "Type C-x 0 to close the new window")) 'follow-link t 'read-only t 'face '(:inherit link :background "yellow")) (insert ".)\n\n") (setq end (point)) (put-text-property start end 'face ;;'font-lock-warning-face (list :background "yellow" :foreground "#c00")) (put-text-property start end 'local-map tab-map) (let ((inhibit-read-only t)) (put-text-property start end 'read-only t))))) (setq point-after-message (point)) (goto-char (point-min)) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-17 17:32 ` Lennart Borgman @ 2006-07-24 14:42 ` Richard Stallman 2006-07-30 20:38 ` Lennart Borgman 0 siblings, 1 reply; 29+ messages in thread From: Richard Stallman @ 2006-07-24 14:42 UTC (permalink / raw) Cc: lennart.borgman.073, emacs-devel (default-keys '( ;; These are not mentioned but are basic: (ESC-prefix [27]) (Control-X-prefix [?\C-x]) (mode-specific-command-prefix [?\C-c]) Please put that constant list into a variable instead of embedding it inside the function. (sort-keys (lambda(left right) (let ((x (append (cadr left) nil)) (y (append (cadr right) nil))) (while (and x y (equal (car x) (car y))) (setq x (cdr x)) (setq y (cdr y))) Please give this a defun and give it a doc string that explains precisely what it tests. (insert-button (car remark) 'action (lambda(b) (interactive) (let ((value (button-get b 'value))) (help--describe-nonstandard-key value))) 'value (cdr remark) 'follow-link t 'face '(:inherit link :background "yellow")) What is the purpose of presenting that button? What does it do when the user clicks on it? Comments have to say such things. In general, your code has hardly any comments. Please add comments enough to make it _clear_. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-07-24 14:42 ` Richard Stallman @ 2006-07-30 20:38 ` Lennart Borgman 0 siblings, 0 replies; 29+ messages in thread From: Lennart Borgman @ 2006-07-30 20:38 UTC (permalink / raw) Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1974 bytes --] Richard Stallman wrote: > (default-keys > '( > ;; These are not mentioned but are basic: > (ESC-prefix [27]) > (Control-X-prefix [?\C-x]) > (mode-specific-command-prefix [?\C-c]) > > > Please put that constant list into a variable > instead of embedding it inside the function. > Done. > (sort-keys > (lambda(left right) > (let ((x (append (cadr left) nil)) > (y (append (cadr right) nil))) > (while (and x y > (equal (car x) (car y))) > (setq x (cdr x)) > (setq y (cdr y))) > > Please give this a defun and give it a doc string that explains > precisely what it tests. > Done. > (insert-button (car remark) > 'action > (lambda(b) (interactive) > (let ((value (button-get b 'value))) > (help--describe-nonstandard-key value))) > 'value (cdr remark) > 'follow-link t > 'face '(:inherit link > :background "yellow")) > > What is the purpose of presenting that button? > What does it do when the user clicks on it? > Comments have to say such things. > Done now - I hope the comments tell what is needed now. > In general, your code has hardly any comments. Please add comments enough > to make it _clear_. > Done. I have attached the new version. However I noticed a strange thing when testing this on w32 from 2006-07-02. If I start with "emacs -Q", then load the attached file and evaluate it with eval-buffer, then the old `help-with-tutorial' from help-fns.el may still be bound to C-h t. (I actually used F1 t.) I check this with "F1 k F1 t". If I now call eval-buffer again and "F1 k F1 t" the new definition of help-with-tutorial from the attached file will be shown. [-- Attachment #2: help-tutorial6.el --] [-- Type: text/plain, Size: 27413 bytes --] (defun help--describe-nonstandard-key(value) "Give more information about a changed key binding. This is used in `help-with-tutorial'. The information includes the key sequence that no longer has a default binding, the default binding and the current binding. It also tells in what keymap the new binding has been done and how to access the function in the default binding from the keyboard. For cua-mode key bindings that try to combine CUA key bindings with default Emacs bindings information about this is shown." (let ((maps (current-active-maps t))) (with-output-to-temp-buffer (help-buffer) (help-setup-xref (list #'help-describe-nonstandard-key value) (interactive-p)) (with-current-buffer (help-buffer) (insert "Emacs default key binding has been changed in your setup:\n\n") (let ((inhibit-read-only t)) (cond ((eq (car value) 'cua-mode) (insert "You have enabled `cua-mode'. When `cua-mode' is enabled, you can use C-z, C-x, C-c, and C-v to undo, cut, copy, and paste in addition to the normal Emacs bindings. The C-x and C-c keys only do cut and copy when the region is active, so in most cases, they do not conflict with the normal function of these prefix keys. If you really need to perform a command which starts with one of the prefix keys even when the region is active, you have three options: - press the prefix key twice very quickly (within 0.2 seconds), - press the prefix key and the following key within 0.2 seconds, or - use the SHIFT key with the prefix key, i.e. C-S-x or C-S-c.")) ((eq (car value) 'current-binding) (let ((cb (nth 1 value)) (db (nth 2 value)) (key (nth 3 value)) (where (nth 4 value)) map mapsym) ;; Try to find the map where the binding occurs (while maps (let* ((m (car maps)) (mb (lookup-key m key t))) (setq maps (cdr maps)) (when (eq mb cb) (setq map m) (setq maps nil)))) (when map (if (eq map global-map) (setq mapsym 'global-map) (mapatoms (lambda (s) (when (and (boundp s) (keymapp (symbol-value s))) (unless (eq s 'map) (when (equal map (symbol-value s)) (when (member map (current-active-maps)) (setq mapsym s))))))))) (insert "Emacs default binding for the key " (key-description key) " is the function `") (insert (format "%s" db)) (insert "'. " "This key has however been rebound to the function `") (insert (format "%s" cb)) (insert "'.") (when mapsym (insert " This binding is in the keymap variable `") (insert (format "%s" mapsym)) (insert "'.")) (if (string= where "") (unless (keymapp db) (insert "\n\nYou can use M-x " (format "%s" db) " RET instead.")) (insert "\n\nWith you current key bindings" " you can use the key " where " to get the function `" (format "%s" db) "'.")) )))) (fill-region (point-min)(point)) (print-help-return-message))))) (defvar help-tutorial-default-keys '( ;; These are not mentioned but are basic: (ESC-prefix [27]) (Control-X-prefix [?\C-x]) (mode-specific-command-prefix [?\C-c]) (save-buffers-kill-emacs [?\C-x ?\C-c]) ;; * SUMMARY (scroll-up [?\C-v]) (scroll-down [?\M-v]) (recenter [?\C-l]) ;; * BASIC CURSOR CONTROL (forward-char [?\C-f]) (backward-char [?\C-b]) (forward-word [?\M-f]) (backward-word [?\M-b]) (next-line [?\C-n]) (previous-line [?\C-p]) (move-beginning-of-line [?\C-a]) (move-end-of-line [?\C-e]) (backward-sentence [?\M-a]) (forward-sentence [?\M-e]) (beginning-of-buffer [?\M-<]) (end-of-buffer [?\M->]) (universal-argument [?\C-u]) ;; * WHEN EMACS IS HUNG (keyboard-quit [?\C-g]) ;; * DISABLED COMMANDS (downcase-region [?\C-x ?\C-l]) ;; * WINDOWS (delete-other-windows [?\C-x ?1]) ;; C-u 0 C-l ;; Type CONTROL-h k CONTROL-f. ;; * INSERTING AND DELETING ;; C-u 8 * to insert ********. (delete-backward-char [backspace]) (delete-char [?\C-d]) (backward-kill-word [(meta backspace)]) (kill-word [?\M-d]) (kill-line [?\C-k]) (kill-sentence [?\M-k]) (set-mark-command [?\C-@]) (set-mark-command [?\C- ]) (kill-region [?\C-w]) (yank [?\C-y]) (yank-pop [?\M-y]) ;; * UNDO (advertised-undo [?\C-x ?u]) (advertised-undo [?\C-x ?u]) ;; * FILES (find-file [?\C-x ?\C-f]) (save-buffer [?\C-x ?\C-s]) ;; * BUFFERS (list-buffers [?\C-x ?\C-b]) (switch-to-buffer [?\C-x ?b]) (save-some-buffers [?\C-x ?s]) ;; * EXTENDING THE COMMAND SET ;; C-x Character eXtend. Followed by one character. (execute-extended-command [?\M-x]) ;; C-x C-f Find file ;; C-x C-s Save file ;; C-x s Save some buffers ;; C-x C-b List buffers ;; C-x b Switch buffer ;; C-x C-c Quit Emacs ;; C-x 1 Delete all but one window ;; C-x u Undo ;; * MODE LINE (describe-mode [?\C-h ?m]) (set-fill-column [?\C-x ?f]) (fill-paragraph [?\M-q]) ;; * SEARCHING (isearch-forward [?\C-s]) (isearch-backward [?\C-r]) ;; * MULTIPLE WINDOWS (split-window-vertically [?\C-x ?2]) (scroll-other-window [?\C-\M-v]) (other-window [?\C-x ?o]) (find-file-other-window [?\C-x ?4 ?\C-f]) ;; * RECURSIVE EDITING LEVELS (keyboard-escape-quit [27 27 27]) ;; * GETTING MORE HELP ;; The most basic HELP feature is C-h c (describe-key-briefly [?\C-h ?c]) (describe-key [?\C-h ?k]) ;; * MORE FEATURES ;; F10 ;; * CONCLUSION (iconify-or-deiconify-frame [?\C-z]) ) "Default Emacs key bindings that are used in the tutorial") (defun help-tutorial-sort-keys (left right) "Sort predicate for use with `help-tutorial-default-keys'. This is a predicate function to `sort'. The sorting is for presentation purpose only and is done on the key sequence." (let ((x (append (cadr left) nil)) (y (append (cadr right) nil))) ;; Skip the front part of the key sequences if they are equal: (while (and x y (equal (car x) (car y))) (setq x (cdr x)) (setq y (cdr y))) ;; Try to make a comparition that is useful for presentation (this ;; could be made nicer perhaps): (let ((cx (car x)) (cy (car y))) (cond ((and (listp cx) (listp cy)) (> (length cx)(length cy))) ((listp cx) nil) ((listp cy) t) ((and (symbolp cx) (symbolp cy)) (string< (symbol-name cy) (symbol-name cx))) ((symbolp cx) nil) ((symbolp cy) t) (t (> (car x)(car y))))))) ;;;###autoload (defun help-with-tutorial (&optional arg dont-ask-for-revert) "Select the Emacs learn-by-doing tutorial. If there is a tutorial version written in the language of the selected language environment, that version is used. If there's no tutorial in that language, `TUTORIAL' is selected. With ARG, you are asked to choose which language. If DONT-ASK-FOR-REVERT is non-nil the buffer is reverted without any question when restarting the tutorial." (interactive "P") (let* ((lang (if arg (let ((minibuffer-setup-hook minibuffer-setup-hook)) (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help) (read-language-name 'tutorial "Language: " "English")) (if (get-language-info current-language-environment 'tutorial) current-language-environment "English"))) (filename (get-language-info lang 'tutorial)) ;; Choose a buffer name including the language so that ;; several languages can be tested simultaneously: (tut-buf-name (concat "TUTORIAL (" lang ")")) (old-tut-buf (get-buffer tut-buf-name)) (old-tut-win (when old-tut-buf (get-buffer-window old-tut-buf t))) (old-tut-is-ok (when old-tut-buf (not (buffer-modified-p old-tut-buf)))) (point-after-message 1)) ;; Try to display the tutorial buffer before asking to revert it. ;; If the tutorial buffer is shown in some window make sure it is ;; selected and displayed: (if old-tut-win (raise-frame (window-frame (select-window (get-buffer-window old-tut-buf t)))) ;; Is there an old tutorial buffer? Then display it: (when old-tut-buf (switch-to-buffer old-tut-buf))) ;; If the tutorial buffer has been changed then ask if it should ;; be reverted: (when (and old-tut-buf (not old-tut-is-ok)) (setq old-tut-is-ok (if dont-ask-for-revert nil (not (y-or-n-p "You have changed the Tutorial buffer. Revert it? "))))) ;; Use whole frame for tutorial (delete-other-windows) ;; (Re)build the tutorial buffer if it is not ok (unless old-tut-is-ok (switch-to-buffer (get-buffer-create tut-buf-name)) (let ((inhibit-read-only t)) (erase-buffer)) (message "Preparing tutorial ...")(sit-for 0) (setq default-directory (expand-file-name "~/")) (setq buffer-auto-save-file-name nil) (insert-file-contents (expand-file-name filename data-directory)) (hack-local-variables) ;; Check if there are key bindings that may disturb the ;; tutorial. If so tell the user. (let* (changed-keys (default-keys (sort help-tutorial-default-keys 'help-tutorial-sort-keys)) ;; On window system suspend Emacs is replaced in the ;; default keymap so honor this here. (Is this true for ;; all window-system? It is at least done in mac-win.el, ;; w32-win.el and x-win.el.) (suspend-emacs (if window-system 'iconify-or-deiconify-frame 'suspend-emacs)) ;; Make key bindings for moving between link fields in ;; the list of changed key bindings. (tab-map (let ((map (make-sparse-keymap))) (define-key map [tab] 'forward-button) (define-key map [(shift tab)] 'backward-button) (define-key map [(meta tab)] 'backward-button) map))) (let (expr key def-fun def-fun-txt rem-fun key-fun where remark ) ;; Check if the default Emacs key bindings that are used in ;; the tutorial have been changed.: (dolist (kdf default-keys) (setq key (nth 1 kdf)) (setq def-fun (nth 0 kdf)) (setq def-fun-txt (format "%s" def-fun)) (setq rem-fun (command-remapping def-fun)) (setq key-fun (key-binding key)) (setq where (where-is-internal (if rem-fun rem-fun def-fun))) (if where (progn (setq where (key-description (car where))) (when (and (< 10 (length where)) (string= (substring where 0 (length "<menu-bar>")) "<menu-bar>")) (setq where "The menus"))) (setq where "")) (setq remark nil) (unless (cond ( (eq key-fun def-fun) t) ( (eq key-fun (command-remapping def-fun)) (setq remark (list "Remapped" nil)) t) ;; cua-mode specials: ( (and cua-mode (or (and (equal key [?\C-v]) (eq key-fun 'cua-paste)) (and (equal key [?\C-z]) (eq key-fun 'undo)))) (setq remark (list "cua-mode, more info" 'cua-mode)) nil) ( (and cua-mode (or (and (eq def-fun 'ESC-prefix) (equal key-fun `(keymap (118 . cua-repeat-replace-region)))) (and (eq def-fun 'mode-specific-command-prefix) (equal key-fun '(keymap (timeout . copy-region-as-kill)))) (and (eq def-fun 'Control-X-prefix) (equal key-fun '(keymap (timeout . kill-region)))))) (setq remark (list "cua-mode replacement" 'cua-mode)) (cond ((eq def-fun 'mode-specific-command-prefix) (setq def-fun-txt "\"C-c prefix\"")) ((eq def-fun 'Control-X-prefix) (setq def-fun-txt "\"C-x prefix\"")) ((eq def-fun 'ESC-prefix) (setq def-fun-txt "\"ESC prefix\""))) (setq where "Same key") nil) ;; viper-mode specials: ( (and (boundp 'viper-mode) viper-mode (eq viper-current-state 'vi-state) (or (and (eq def-fun 'isearch-forward) (eq key-fun 'viper-isearch-forward)) (and (eq def-fun 'isearch-backward) (eq key-fun 'viper-isearch-backward)))) t) ;; The strange handling of C-delete and ;; C-backspace: ( (when normal-erase-is-backspace (or (and (equal key [C-delete]) (equal key-fun 'kill-word)) (and (equal key [C-backspace]) (equal key-fun 'backward-kill-word)))) t) ( t (setq remark (list "more info" 'current-binding key-fun def-fun key where)) nil)) (add-to-list 'changed-keys (list key def-fun def-fun-txt where remark))))) ;; Clear message: (unless dont-ask-for-revert (message "")(sit-for 0)) ;; If some Emacs default key bindings have been changed then ;; display the changes in the tutorial buffer with some ;; explanatory links: (when (or changed-keys (and (boundp 'viper-mode) viper-mode)) ;; Need the custom button face for viper buttons: (when (and (boundp 'viper-mode) viper-mode) (require 'cus-edit)) (forward-line) (let ((start (point)) end) (insert " NOTICE: One of the main purposes of the tutorial is that You should be able to learn some important Emacs default key bindings. However when you started the tutorial the following key bindings used in the tutorial had been changed from Emacs default:\n\n" ) (when changed-keys (let ((frm " %-9s %-27s %-11s %s\n")) (insert (format frm "KEY" "DEFAULT BINDING" "IS NOW ON" "REMARK"))) (dolist (tk changed-keys) (let* ((def-fun (nth 1 tk)) (key (nth 0 tk)) (def-fun-txt (nth 2 tk)) (where (nth 3 tk)) (remark (nth 4 tk)) (rem-fun (command-remapping def-fun)) (key-txt (key-description key)) (key-fun (key-binding key)) tot-len) (unless (eq def-fun key-fun) ;; Insert key binding description: (insert " " key-txt " ") (setq tot-len (length key-txt)) (when (> 9 tot-len) (insert (make-string (- 9 tot-len) ? )) (setq tot-len 9)) ;; Insert a link describing the old binding: (insert-button def-fun-txt 'value def-fun 'action (lambda(button) (interactive) (describe-function (button-get button 'value))) 'follow-link t 'face '(:inherit link :background "yellow")) (setq tot-len (+ tot-len (length def-fun-txt))) (when (> 36 tot-len) (insert (make-string (- 36 tot-len) ? ))) (when (listp where) (setq where "list")) ;; Tell where the old binding is now: (insert (format " %-11s " where)) ;; Insert a link with more information, for example ;; current binding and keymap or information about ;; cua-mode replacements: (insert-button (car remark) 'action (lambda(b) (interactive) (let ((value (button-get b 'value))) (help--describe-nonstandard-key value))) 'value (cdr remark) 'follow-link t 'face '(:inherit link :background "yellow")) (insert "\n"))))) ;; Viper turns itself off in the tutorial buffer by ;; default. Explain this and add some more information ;; about it: (when (and (boundp 'viper-mode) viper-mode) (insert "\n INFORMATION ABOUT VIPER\n") (cond ((eq viper-current-state 'emacs-state) (insert " You have enabled Viper mode, but in the tutorial buffer Viper mode is currently turned off. You can however turn it on if you want to. This may enable you to see what key bindings that Viper conflicts with:\n ") (insert-button " Turn on Viper here! " 'action (lambda(b) (interactive) (let ((arg (button-get b 'value))) (viper-mode) (set-buffer-modified-p t) (help-with-tutorial arg t))) 'value arg 'follow-link t 'face 'custom-button 'mouse-face 'custom-button-mouse ) ;;(insert ")") ) (t (insert " You have enabled Viper mode in the tutorial buffer. Some of the changed key bindings above depends on the Viper state. When you started the tutorial the Viper state was ") (cond ((eq viper-current-state 'vi-state) (insert "vi.")) (t (insert "some insert state."))) (insert "\n ") (insert-button " Turn off Viper here! " 'action (lambda(b) (interactive) (let ((arg (button-get b 'value))) (kill-buffer (current-buffer)) (help-with-tutorial arg t))) 'value arg 'follow-link t 'face 'custom-button 'mouse-face 'custom-button-mouse) (insert " ") (cond ((eq viper-current-state 'vi-state) (insert-button " Restart tutorial in Viper insert state! " 'action (lambda(b) (interactive) (let ((arg (button-get b 'value))) (viper-insert nil) (set-buffer-modified-p t) (help-with-tutorial arg t))) 'value arg 'follow-link t 'face 'custom-button 'mouse-face 'custom-button-mouse)) ((not (eq viper-current-state 'vi-state)) (insert-button " Restart tutorial in Viper vi state! " 'action (lambda(b) (interactive) (let ((arg (button-get b 'value)) (cmd (cond ((eq viper-current-state 'vi-state) 'viper-ESC) ((eq viper-current-state 'insert-state) 'viper-exit-insert-state) ((eq viper-current-state 'replace-state) 'viper-replace-state-exit-cmd) (t 'viper-change-state-to-vi) ))) (call-interactively cmd) (set-buffer-modified-p t) (help-with-tutorial arg t))) 'value arg 'follow-link t 'face 'custom-button 'mouse-face 'custom-button-mouse))))) (insert "\n If you want to learn Viper keys please see the ") (insert-button "Viper manual" 'action (lambda(button) (interactive) (info-other-window "(viper)") (message "Type C-x 0 to close the new window")) 'follow-link t 'face '(:inherit link :background "yellow")) (insert ".\n")) (insert " It is legitimate to change key bindings, but changed bindings do not correspond to what the tutorial says. (See also " ) (insert-button "Key Binding Conventions" 'action (lambda(button) (interactive) (info-other-window "(elisp) Key Binding Conventions") (message "Type C-x 0 to close the new window")) 'follow-link t 'face '(:inherit link :background "yellow")) (insert ".)\n\n") (setq end (point)) ;; Make the area with information about change key ;; bindings stand out: (put-text-property start end 'face ;; The default warning face does not ;;look good in this situation. Instead ;;try something that could be ;;recognized from warnings in normal ;;life: ;; 'font-lock-warning-face (list :background "yellow" :foreground "#c00")) ;; Make it possible to use Tab/S-Tab between fields in ;; this area: (put-text-property start end 'local-map tab-map) ;; Make this area read-only: (put-text-property start end 'read-only t)))) (setq point-after-message (point)) (goto-char (point-min)) (search-forward "\n<<") (beginning-of-line) ;; Convert the <<...>> line to the proper [...] line, ;; or just delete the <<...>> line if a [...] line follows. (cond ((save-excursion (forward-line 1) (looking-at "\\[")) (delete-region (point) (progn (forward-line 1) (point)))) ((looking-at "<<Blank lines inserted.*>>") (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) (t (looking-at "<<") (replace-match "[") (search-forward ">>") (replace-match "]"))) (beginning-of-line) (let ((n (- (window-height (selected-window)) (count-lines (point-min) (point)) 6))) (if (< n 8) (progn ;; For a short gap, we don't need the [...] line, ;; so delete it. (delete-region (point) (progn (end-of-line) (point))) (newline n)) ;; Some people get confused by the large gap. (newline (/ n 2)) ;; Skip the [...] line (don't delete it). (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min)) (setq buffer-undo-list nil) (set-buffer-modified-p nil)))) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Patch to remove minor modes in tutorial 2006-06-26 13:48 ` Lennart Borgman 2006-06-26 16:31 ` Kevin Rodgers @ 2006-06-27 16:14 ` Richard Stallman 1 sibling, 0 replies; 29+ messages in thread From: Richard Stallman @ 2006-06-27 16:14 UTC (permalink / raw) Cc: emacs-devel Then I would be glad if those who knows about minor modes that will not disturb the turorial would mail the names of them to me. Don't worry about completeness! Just put the ones you can think of. If we encounter others in the future, we can add them to the list then. ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2006-07-30 20:38 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-06-24 14:09 Patch to remove minor modes in tutorial Lennart Borgman 2006-06-25 15:34 ` Richard Stallman 2006-06-25 21:27 ` Lennart Borgman 2006-06-26 11:33 ` Richard Stallman 2006-06-26 13:48 ` Lennart Borgman 2006-06-26 16:31 ` Kevin Rodgers 2006-06-26 16:45 ` Lennart Borgman 2006-06-27 15:44 ` Kevin Rodgers 2006-06-27 16:41 ` Lennart Borgman 2006-06-28 17:25 ` Richard Stallman 2006-06-29 8:41 ` Kim F. Storm 2006-06-29 12:07 ` Mathias Dahl 2006-06-29 12:27 ` David Kastrup 2006-06-30 11:06 ` Richard Stallman 2006-06-29 17:57 ` Richard Stallman 2006-07-01 0:38 ` Lennart Borgman 2006-07-01 23:55 ` Richard Stallman 2006-07-02 8:54 ` Lennart Borgman 2006-07-02 22:30 ` Richard Stallman 2006-07-07 0:01 ` Lennart Borgman 2006-07-07 19:31 ` Richard Stallman 2006-07-08 3:14 ` Giorgos Keramidas 2006-07-08 20:57 ` Richard Stallman 2006-07-09 8:44 ` Lennart Borgman 2006-07-17 16:12 ` Lennart Borgman 2006-07-17 17:32 ` Lennart Borgman 2006-07-24 14:42 ` Richard Stallman 2006-07-30 20:38 ` Lennart Borgman 2006-06-27 16:14 ` Richard Stallman
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).