From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Lennart Borgman Newsgroups: gmane.emacs.devel Subject: Re: Patch to remove minor modes in tutorial Date: Sat, 01 Jul 2006 02:38:49 +0200 Message-ID: <44A5C419.5090908@student.lu.se> References: <449D4787.6030809@student.lu.se> <449EFFBB.80508@student.lu.se> <449FE5AB.1080906@student.lu.se> <44A00F46.3010000@student.lu.se> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1151714364 30757 80.91.229.2 (1 Jul 2006 00:39:24 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 1 Jul 2006 00:39:24 +0000 (UTC) Cc: ihs_4664@yahoo.com, emacs-devel@gnu.org, "Kim F. Storm" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jul 01 02:39:18 2006 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1FwTVy-0007AR-D6 for ged-emacs-devel@m.gmane.org; Sat, 01 Jul 2006 02:39:17 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FwTVv-0002TE-RX for ged-emacs-devel@m.gmane.org; Fri, 30 Jun 2006 20:39:11 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FwTVi-0002Q5-Rz for emacs-devel@gnu.org; Fri, 30 Jun 2006 20:38:58 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FwTVh-0002O9-IP for emacs-devel@gnu.org; Fri, 30 Jun 2006 20:38:57 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FwTVh-0002Nz-Es for emacs-devel@gnu.org; Fri, 30 Jun 2006 20:38:57 -0400 Original-Received: from [81.228.11.98] (helo=pne-smtpout1-sn1.fre.skanova.net) by monty-python.gnu.org with esmtp (Exim 4.52) id 1FwTiX-0003lw-Fq; Fri, 30 Jun 2006 20:52:14 -0400 Original-Received: from [192.168.123.121] (83.249.218.244) by pne-smtpout1-sn1.fre.skanova.net (7.2.075) id 44A1364D000EA9AB; Sat, 1 Jul 2006 02:38:52 +0200 User-Agent: Thunderbird 1.5.0.4 (Windows/20060516) Original-To: rms@gnu.org In-Reply-To: X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:56336 Archived-At: 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 " 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 " " '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 "<>") (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))))