;;; tutorial.el --- tutorial for Emacs
-;; Copyright (C) 2006 Free Software Foundation, Inc.
+;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: help, internal
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
(format "%s" db)
" RET instead."))
(insert "\n\nWith your current key bindings"
- " you can use the key "
+ " you can use "
+ (if (string-match "^the .*menus?$" where)
+ ""
+ "the key")
where
" to get the function `"
(format "%s" db)
(defconst tutorial--default-keys
;; On window system, `suspend-emacs' is replaced in the default
;; keymap
- (let* ((suspend-emacs (if window-system
- 'iconify-or-deiconify-frame
- 'suspend-emacs))
+ (let* ((suspend-emacs 'suspend-frame)
(default-keys
`((ESC-prefix [27])
(Control-X-prefix [?\C-x])
(mode-specific-command-prefix [?\C-c])
- (save-buffers-kill-emacs [?\C-x ?\C-c])
+ (save-buffers-kill-terminal [?\C-x ?\C-c])
;; * SUMMARY
(scroll-up [?\C-v])
;; * INSERTING AND DELETING
;; C-u 8 * to insert ********.
- (delete-backward-char [backspace])
(delete-backward-char "\d")
(delete-char [?\C-d])
- (backward-kill-word [(meta backspace)])
+ (backward-kill-word [?\M-\d])
(kill-word [?\M-d])
(kill-line [?\C-k])
(kill-sentence [?\M-k])
tutorial--default-keys)))))
(when changed-keys
(insert
- "The following key bindings used in the tutorial had been changed
-from the Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" )
- (let ((frm " %-9s %-27s %-11s %s\n"))
- (insert (format frm "Key" "Standard Binding" "Is Now On" "Remark")))
+ "The following key bindings used in the tutorial have been changed
+from the Emacs default:\n\n" )
+ (let ((frm " %-14s %-27s %-16s\n"))
+ (insert (format frm
+ "Standard Key" "Command" "In Your Emacs")))
(dolist (tk changed-keys)
(let* ((def-fun (nth 1 tk))
(key (nth 0 tk))
(put-text-property 0 (length key-txt)
'face 'tutorial-warning-face key-txt))
(insert " " key-txt " ")
- (setq tot-len (length key-txt))
- (when (> 9 tot-len)
- (insert (make-string (- 9 tot-len) ?\s))
- (setq tot-len 9))
+ (indent-to 18)
;; Insert a link describing the old binding:
(insert-button def-fun-txt
'value def-fun
'action
- (lambda(button) (interactive)
+ (lambda (button) (interactive)
(describe-function
(button-get button 'value)))
'follow-link t)
- (setq tot-len (+ tot-len (length def-fun-txt)))
- (when (> 36 tot-len)
- (insert (make-string (- 36 tot-len) ?\s)))
+ (indent-to 45)
(when (listp where)
(setq where "list"))
;; Tell where the old binding is now:
- (insert (format " %-11s "
+ (insert (format " %-16s "
(if (string= "" where)
(format "M-x %s" def-fun-txt)
where)))
;; cua-mode replacements:
(insert-button (car remark)
'action
- (lambda(b) (interactive)
+ (lambda (b) (interactive)
(let ((value (button-get b 'value)))
(tutorial--describe-nonstandard-key value)))
'value (cdr remark)
WHERE is a text describing the key sequences to which DEF-FUN is
bound now (or, if it is remapped, a key sequence
for the function it is remapped to)
- REMARK is a list with info about rebinding. It has either of these
- formats:
+ REMARK is a list with info about rebinding. It has either of
+ these formats:
\(TEXT cua-mode)
\(TEXT current-binding KEY-FUN DEF-FUN KEY WHERE)
QUIET is t if this changed keybinding should be handled quietly.
This is used by `tutorial--display-changes'."
(let (changed-keys remark)
- (dolist (kdf default-keys)
- ;; The variables below corresponds to those with the same names
- ;; described in the doc string.
- (let* ((key (nth 1 kdf))
- (def-fun (nth 0 kdf))
- (def-fun-txt (format "%s" def-fun))
- (rem-fun (command-remapping def-fun))
- (key-fun (if (eq def-fun 'ESC-prefix)
- (lookup-key global-map [27])
- (key-binding key)))
- (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)
- ;; No rebinding, return t
- t)
- ((and key-fun
- (eq key-fun (command-remapping def-fun)))
- ;; Just a remapping, return t
- 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)))
- (setq def-fun-txt "\"ESC prefix\""))
- (and (eq def-fun 'mode-specific-command-prefix)
- (equal key-fun
- '(keymap
- (timeout . copy-region-as-kill)))
- (setq def-fun-txt "\"C-c prefix\""))
- (and (eq def-fun 'Control-X-prefix)
- (equal key-fun
- '(keymap (timeout . kill-region)))
- (setq def-fun-txt "\"C-x prefix\""))))
- (setq remark (list "cua-mode replacement" 'cua-mode))
- (setq where "Same key")
- nil)
- ;; viper-mode specials:
- ((and (boundp 'viper-mode-string)
- (boundp 'viper-current-state)
- (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))))
- ;; These bindings works as the default bindings,
- ;; return t
- t)
- ((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))))
- ;; This is the strange handling of C-delete and
- ;; C-backspace, return t
- t)
- (t
- ;; This key has indeed been rebound. Put information
- ;; in `remark' and return nil
- (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 nil)))))
+ ;; Look up the bindings in a Fundamental mode buffer
+ ;; so we do not get fooled by some other major mode.
+ (with-temp-buffer
+ (fundamental-mode)
+ (dolist (kdf default-keys)
+ ;; The variables below corresponds to those with the same names
+ ;; described in the doc string.
+ (let* ((key (nth 1 kdf))
+ (def-fun (nth 0 kdf))
+ (def-fun-txt (format "%s" def-fun))
+ (rem-fun (command-remapping def-fun))
+ ;; Handle prefix definitions specially
+ ;; so that a mode that rebinds some subcommands
+ ;; won't make it appear that the whole prefix is gone.
+ (key-fun (if (eq def-fun 'ESC-prefix)
+ (lookup-key global-map [27])
+ (if (eq def-fun 'Control-X-prefix)
+ (lookup-key global-map [24])
+ (key-binding key))))
+ (where (where-is-internal (if rem-fun rem-fun def-fun)))
+ cwhere)
+
+ (if where
+ (progn
+ (setq cwhere (car where)
+ where (key-description cwhere))
+ (when (and (< 10 (length where))
+ (string= (substring where 0 (length "<menu-bar>"))
+ "<menu-bar>"))
+ (setq where
+ (if (and (vectorp cwhere)
+ (setq cwhere (elt cwhere 1))
+ (setq cwhere
+ (cadr
+ (assoc cwhere
+ (lookup-key global-map
+ [menu-bar]))))
+ (stringp cwhere))
+ (format "the `%s' menu" cwhere)
+ "the menus"))))
+ (setq where ""))
+ (setq remark nil)
+ (unless
+ (cond ((eq key-fun def-fun)
+ ;; No rebinding, return t
+ t)
+ ((and key-fun
+ (eq key-fun (command-remapping def-fun)))
+ ;; Just a remapping, return t
+ 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)))
+ (setq def-fun-txt "\"ESC prefix\""))
+ (and (eq def-fun 'mode-specific-command-prefix)
+ (equal key-fun
+ '(keymap
+ (timeout . copy-region-as-kill)))
+ (setq def-fun-txt "\"C-c prefix\""))
+ (and (eq def-fun 'Control-X-prefix)
+ (equal key-fun
+ '(keymap (timeout . kill-region)))
+ (setq def-fun-txt "\"C-x prefix\""))))
+ (setq remark (list "cua-mode replacement" 'cua-mode))
+ (setq where "Same key")
+ nil)
+ ;; viper-mode specials:
+ ((and (boundp 'viper-mode-string)
+ (boundp 'viper-current-state)
+ (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))))
+ ;; These bindings works as the default bindings,
+ ;; return t
+ t)
+ ((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))))
+ ;; This is the strange handling of C-delete and
+ ;; C-backspace, return t
+ t)
+ (t
+ ;; This key has indeed been rebound. Put information
+ ;; in `remark' and return nil
+ (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 nil))))))
changed-keys))
(defun tutorial--key-description (key)
(defun tutorial--saved-dir ()
"Directory to which tutorials are saved."
- (expand-file-name "tutorial"
- (if (eq system-type 'ms-dos) "~/_emacs.d/" "~/.emacs.d/")))
+ (expand-file-name "tutorial" user-emacs-directory))
(defun tutorial--saved-file ()
"File name in which to save tutorials."
(setq file-name (concat file-name ".tut")))
(expand-file-name file-name (tutorial--saved-dir))))
-(defun tutorial--remove-remarks()
+(defun tutorial--remove-remarks ()
"Remove the remark lines that was added to the tutorial buffer."
(save-excursion
(goto-char (point-min))
;; This runs in a hook so protect it:
(condition-case err
(if (y-or-n-p "Save your position in the tutorial? ")
- (tutorial--save-tutorial-to (tutorial--saved-file)))
+ (tutorial--save-tutorial-to (tutorial--saved-file))
+ (message "Tutorial position not saved"))
(error (message "Error saving tutorial state: %s"
(error-message-string err)))))
(delete-region (point-min) (point))
(goto-char tutorial--point-before-chkeys)
(setq tutorial--point-before-chkeys (point-marker)))
- (insert-file-contents (expand-file-name filename data-directory))
+ (insert-file-contents (expand-file-name filename tutorial-directory))
(forward-line)
(setq tutorial--point-before-chkeys (point-marker)))
See `get-lang-string' for more information.")
-(defun get-lang-string(lang stringid &optional no-eng-fallback)
+(defun get-lang-string (lang stringid &optional no-eng-fallback)
"Get a language specific string for Emacs.
-In certain places Emacs can replace a string showed to the user with a language specific string.
-This function retrieves such strings.
+In certain places Emacs can replace a string shown to the user with
+a language specific string. This function retrieves such strings.
LANG is the language specification. It should be one of those
strings that can be returned by `read-language-name'. STRINGID
is a symbol that specifies the string to retrieve.
-If no string is found for STRINGID in the choosen language then
+If no string is found for STRINGID in the chosen language then
the English string is returned unless NO-ENG-FALLBACK is non-nil.
See `lang-strings' for more information.