diff options
Diffstat (limited to 'lisp/tutorial.el')
| -rw-r--r-- | lisp/tutorial.el | 372 |
1 files changed, 141 insertions, 231 deletions
diff --git a/lisp/tutorial.el b/lisp/tutorial.el index b171ee9a07b..be50d793f0f 100644 --- a/lisp/tutorial.el +++ b/lisp/tutorial.el | |||
| @@ -33,21 +33,11 @@ | |||
| 33 | ;;; Code: | 33 | ;;; Code: |
| 34 | 34 | ||
| 35 | (require 'help-mode) ;; for function help-buffer | 35 | (require 'help-mode) ;; for function help-buffer |
| 36 | (eval-when-compile (require 'cl)) | ||
| 37 | 36 | ||
| 38 | (defface tutorial-warning-face | 37 | (defface tutorial-warning-face |
| 39 | '((((class color) (min-colors 88) (background light)) | 38 | '((t :inherit font-lock-warning-face)) |
| 40 | (:foreground "Red1" :weight bold)) | ||
| 41 | (((class color) (min-colors 88) (background dark)) | ||
| 42 | (:foreground "Pink" :weight bold)) | ||
| 43 | (((class color) (min-colors 16) (background light)) | ||
| 44 | (:foreground "Red1" :weight bold)) | ||
| 45 | (((class color) (min-colors 16) (background dark)) | ||
| 46 | (:foreground "Pink" :weight bold)) | ||
| 47 | (((class color) (min-colors 8)) (:foreground "red")) | ||
| 48 | (t (:inverse-video t :weight bold))) | ||
| 49 | "Face used to highlight warnings in the tutorial." | 39 | "Face used to highlight warnings in the tutorial." |
| 50 | :group 'font-lock-faces) | 40 | :group 'help) |
| 51 | 41 | ||
| 52 | (defvar tutorial--point-before-chkeys 0 | 42 | (defvar tutorial--point-before-chkeys 0 |
| 53 | "Point before display of key changes.") | 43 | "Point before display of key changes.") |
| @@ -168,8 +158,7 @@ options: | |||
| 168 | where | 158 | where |
| 169 | " to get the function `" | 159 | " to get the function `" |
| 170 | (format "%s" db) | 160 | (format "%s" db) |
| 171 | "'.")) | 161 | "'."))) |
| 172 | ) | ||
| 173 | (fill-region (point-min) (point))))) | 162 | (fill-region (point-min) (point))))) |
| 174 | (print-help-return-message)))) | 163 | (print-help-return-message)))) |
| 175 | 164 | ||
| @@ -213,110 +202,83 @@ LEFT and RIGHT are the elements to compare." | |||
| 213 | ((and (symbolp cx) | 202 | ((and (symbolp cx) |
| 214 | (symbolp cy)) | 203 | (symbolp cy)) |
| 215 | (string< (symbol-name cy) | 204 | (string< (symbol-name cy) |
| 216 | (symbol-name cx))) | 205 | (symbol-name cx))))))) |
| 217 | )))) | ||
| 218 | 206 | ||
| 219 | (defconst tutorial--default-keys | 207 | (defconst tutorial--default-keys |
| 220 | (let* ( | 208 | ;; On window system, `suspend-emacs' is replaced in the default |
| 221 | ;; On window system suspend Emacs is replaced in the | 209 | ;; keymap |
| 222 | ;; default keymap so honor this here. | 210 | (let* ((suspend-emacs (if window-system |
| 223 | (suspend-emacs (if window-system | ||
| 224 | 'iconify-or-deiconify-frame | 211 | 'iconify-or-deiconify-frame |
| 225 | 'suspend-emacs)) | 212 | 'suspend-emacs)) |
| 226 | (default-keys | 213 | (default-keys |
| 227 | `( | 214 | `((ESC-prefix [27]) |
| 228 | ;; These are not mentioned but are basic: | ||
| 229 | (ESC-prefix [27]) | ||
| 230 | (Control-X-prefix [?\C-x]) | 215 | (Control-X-prefix [?\C-x]) |
| 231 | (mode-specific-command-prefix [?\C-c]) | 216 | (mode-specific-command-prefix [?\C-c]) |
| 232 | |||
| 233 | (save-buffers-kill-emacs [?\C-x ?\C-c]) | 217 | (save-buffers-kill-emacs [?\C-x ?\C-c]) |
| 234 | 218 | ||
| 235 | |||
| 236 | ;; * SUMMARY | 219 | ;; * SUMMARY |
| 237 | (scroll-up [?\C-v]) | 220 | (scroll-up [?\C-v]) |
| 238 | (scroll-down [?\M-v]) | 221 | (scroll-down [?\M-v]) |
| 239 | (recenter [?\C-l]) | 222 | (recenter [?\C-l]) |
| 240 | 223 | ||
| 241 | |||
| 242 | ;; * BASIC CURSOR CONTROL | 224 | ;; * BASIC CURSOR CONTROL |
| 243 | (forward-char [?\C-f]) | 225 | (forward-char [?\C-f]) |
| 244 | (backward-char [?\C-b]) | 226 | (backward-char [?\C-b]) |
| 245 | |||
| 246 | (forward-word [?\M-f]) | 227 | (forward-word [?\M-f]) |
| 247 | (backward-word [?\M-b]) | 228 | (backward-word [?\M-b]) |
| 248 | |||
| 249 | (next-line [?\C-n]) | 229 | (next-line [?\C-n]) |
| 250 | (previous-line [?\C-p]) | 230 | (previous-line [?\C-p]) |
| 251 | |||
| 252 | (move-beginning-of-line [?\C-a]) | 231 | (move-beginning-of-line [?\C-a]) |
| 253 | (move-end-of-line [?\C-e]) | 232 | (move-end-of-line [?\C-e]) |
| 254 | |||
| 255 | (backward-sentence [?\M-a]) | 233 | (backward-sentence [?\M-a]) |
| 256 | (forward-sentence [?\M-e]) | 234 | (forward-sentence [?\M-e]) |
| 257 | |||
| 258 | (newline "\r") | 235 | (newline "\r") |
| 259 | |||
| 260 | (beginning-of-buffer [?\M-<]) | 236 | (beginning-of-buffer [?\M-<]) |
| 261 | (end-of-buffer [?\M->]) | 237 | (end-of-buffer [?\M->]) |
| 262 | |||
| 263 | (universal-argument [?\C-u]) | 238 | (universal-argument [?\C-u]) |
| 264 | 239 | ||
| 265 | |||
| 266 | ;; * WHEN EMACS IS HUNG | 240 | ;; * WHEN EMACS IS HUNG |
| 267 | (keyboard-quit [?\C-g]) | 241 | (keyboard-quit [?\C-g]) |
| 268 | 242 | ||
| 269 | |||
| 270 | ;; * DISABLED COMMANDS | 243 | ;; * DISABLED COMMANDS |
| 271 | (downcase-region [?\C-x ?\C-l]) | 244 | (downcase-region [?\C-x ?\C-l]) |
| 272 | 245 | ||
| 273 | |||
| 274 | ;; * WINDOWS | 246 | ;; * WINDOWS |
| 275 | (delete-other-windows [?\C-x ?1]) | 247 | (delete-other-windows [?\C-x ?1]) |
| 276 | ;; C-u 0 C-l | 248 | ;; C-u 0 C-l |
| 277 | ;; Type CONTROL-h k CONTROL-f. | 249 | ;; Type CONTROL-h k CONTROL-f. |
| 278 | 250 | ||
| 279 | |||
| 280 | ;; * INSERTING AND DELETING | 251 | ;; * INSERTING AND DELETING |
| 281 | ;; C-u 8 * to insert ********. | 252 | ;; C-u 8 * to insert ********. |
| 282 | |||
| 283 | (delete-backward-char [backspace]) | 253 | (delete-backward-char [backspace]) |
| 284 | (delete-backward-char "\d") | 254 | (delete-backward-char "\d") |
| 285 | (delete-char [?\C-d]) | 255 | (delete-char [?\C-d]) |
| 286 | |||
| 287 | (backward-kill-word [(meta backspace)]) | 256 | (backward-kill-word [(meta backspace)]) |
| 288 | (kill-word [?\M-d]) | 257 | (kill-word [?\M-d]) |
| 289 | |||
| 290 | (kill-line [?\C-k]) | 258 | (kill-line [?\C-k]) |
| 291 | (kill-sentence [?\M-k]) | 259 | (kill-sentence [?\M-k]) |
| 292 | |||
| 293 | (set-mark-command [?\C-@]) | 260 | (set-mark-command [?\C-@]) |
| 294 | (set-mark-command [?\C- ]) | 261 | (set-mark-command [?\C- ]) |
| 295 | (kill-region [?\C-w]) | 262 | (kill-region [?\C-w]) |
| 296 | (yank [?\C-y]) | 263 | (yank [?\C-y]) |
| 297 | (yank-pop [?\M-y]) | 264 | (yank-pop [?\M-y]) |
| 298 | 265 | ||
| 299 | |||
| 300 | ;; * UNDO | 266 | ;; * UNDO |
| 301 | (advertised-undo [?\C-x ?u]) | 267 | (advertised-undo [?\C-x ?u]) |
| 302 | (advertised-undo [?\C-x ?u]) | 268 | (advertised-undo [?\C-x ?u]) |
| 303 | 269 | ||
| 304 | |||
| 305 | ;; * FILES | 270 | ;; * FILES |
| 306 | (find-file [?\C-x ?\C-f]) | 271 | (find-file [?\C-x ?\C-f]) |
| 307 | (save-buffer [?\C-x ?\C-s]) | 272 | (save-buffer [?\C-x ?\C-s]) |
| 308 | 273 | ||
| 309 | |||
| 310 | ;; * BUFFERS | 274 | ;; * BUFFERS |
| 311 | (list-buffers [?\C-x ?\C-b]) | 275 | (list-buffers [?\C-x ?\C-b]) |
| 312 | (switch-to-buffer [?\C-x ?b]) | 276 | (switch-to-buffer [?\C-x ?b]) |
| 313 | (save-some-buffers [?\C-x ?s]) | 277 | (save-some-buffers [?\C-x ?s]) |
| 314 | 278 | ||
| 315 | |||
| 316 | ;; * EXTENDING THE COMMAND SET | 279 | ;; * EXTENDING THE COMMAND SET |
| 317 | ;; C-x Character eXtend. Followed by one character. | 280 | ;; C-x Character eXtend. Followed by one character. |
| 318 | (execute-extended-command [?\M-x]) | 281 | (execute-extended-command [?\M-x]) |
| 319 | |||
| 320 | ;; C-x C-f Find file | 282 | ;; C-x C-f Find file |
| 321 | ;; C-x C-s Save file | 283 | ;; C-x C-s Save file |
| 322 | ;; C-x s Save some buffers | 284 | ;; C-x s Save some buffers |
| @@ -326,44 +288,35 @@ LEFT and RIGHT are the elements to compare." | |||
| 326 | ;; C-x 1 Delete all but one window | 288 | ;; C-x 1 Delete all but one window |
| 327 | ;; C-x u Undo | 289 | ;; C-x u Undo |
| 328 | 290 | ||
| 329 | |||
| 330 | ;; * MODE LINE | 291 | ;; * MODE LINE |
| 331 | (describe-mode [?\C-h ?m]) | 292 | (describe-mode [?\C-h ?m]) |
| 332 | |||
| 333 | (set-fill-column [?\C-x ?f]) | 293 | (set-fill-column [?\C-x ?f]) |
| 334 | (fill-paragraph [?\M-q]) | 294 | (fill-paragraph [?\M-q]) |
| 335 | 295 | ||
| 336 | |||
| 337 | ;; * SEARCHING | 296 | ;; * SEARCHING |
| 338 | (isearch-forward [?\C-s]) | 297 | (isearch-forward [?\C-s]) |
| 339 | (isearch-backward [?\C-r]) | 298 | (isearch-backward [?\C-r]) |
| 340 | 299 | ||
| 341 | |||
| 342 | ;; * MULTIPLE WINDOWS | 300 | ;; * MULTIPLE WINDOWS |
| 343 | (split-window-vertically [?\C-x ?2]) | 301 | (split-window-vertically [?\C-x ?2]) |
| 344 | (scroll-other-window [?\C-\M-v]) | 302 | (scroll-other-window [?\C-\M-v]) |
| 345 | (other-window [?\C-x ?o]) | 303 | (other-window [?\C-x ?o]) |
| 346 | (find-file-other-window [?\C-x ?4 ?\C-f]) | 304 | (find-file-other-window [?\C-x ?4 ?\C-f]) |
| 347 | 305 | ||
| 348 | |||
| 349 | ;; * RECURSIVE EDITING LEVELS | 306 | ;; * RECURSIVE EDITING LEVELS |
| 350 | (keyboard-escape-quit [27 27 27]) | 307 | (keyboard-escape-quit [27 27 27]) |
| 351 | 308 | ||
| 352 | |||
| 353 | ;; * GETTING MORE HELP | 309 | ;; * GETTING MORE HELP |
| 354 | ;; The most basic HELP feature is C-h c | 310 | ;; The most basic HELP feature is C-h c |
| 355 | (describe-key-briefly [?\C-h ?c]) | 311 | (describe-key-briefly [?\C-h ?c]) |
| 356 | (describe-key [?\C-h ?k]) | 312 | (describe-key [?\C-h ?k]) |
| 357 | 313 | ||
| 358 | |||
| 359 | ;; * MORE FEATURES | 314 | ;; * MORE FEATURES |
| 360 | ;; F10 | 315 | ;; F10 |
| 361 | 316 | ||
| 362 | |||
| 363 | ;; * CONCLUSION | 317 | ;; * CONCLUSION |
| 364 | ;;(iconify-or-deiconify-frame [?\C-z]) | 318 | ;;(iconify-or-deiconify-frame [?\C-z]) |
| 365 | (,suspend-emacs [?\C-z]) | 319 | (,suspend-emacs [?\C-z])))) |
| 366 | ))) | ||
| 367 | (sort default-keys 'tutorial--sort-keys)) | 320 | (sort default-keys 'tutorial--sort-keys)) |
| 368 | "Default Emacs key bindings that the tutorial depends on.") | 321 | "Default Emacs key bindings that the tutorial depends on.") |
| 369 | 322 | ||
| @@ -374,7 +327,6 @@ LEFT and RIGHT are the elements to compare." | |||
| 374 | (interactive-p)) | 327 | (interactive-p)) |
| 375 | (with-current-buffer (help-buffer) | 328 | (with-current-buffer (help-buffer) |
| 376 | (let* ((tutorial-buffer (button-get button 'tutorial-buffer)) | 329 | (let* ((tutorial-buffer (button-get button 'tutorial-buffer)) |
| 377 | ;;(tutorial-arg (button-get button 'tutorial-arg)) | ||
| 378 | (explain-key-desc (button-get button 'explain-key-desc)) | 330 | (explain-key-desc (button-get button 'explain-key-desc)) |
| 379 | (changed-keys (with-current-buffer tutorial-buffer | 331 | (changed-keys (with-current-buffer tutorial-buffer |
| 380 | (save-excursion | 332 | (save-excursion |
| @@ -384,7 +336,7 @@ LEFT and RIGHT are the elements to compare." | |||
| 384 | (when changed-keys | 336 | (when changed-keys |
| 385 | (insert | 337 | (insert |
| 386 | "The following key bindings used in the tutorial had been changed | 338 | "The following key bindings used in the tutorial had been changed |
| 387 | from Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) | 339 | from the Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) |
| 388 | (let ((frm " %-9s %-27s %-11s %s\n")) | 340 | (let ((frm " %-9s %-27s %-11s %s\n")) |
| 389 | (insert (format frm "Key" "Standard Binding" "Is Now On" "Remark"))) | 341 | (insert (format frm "Key" "Standard Binding" "Is Now On" "Remark"))) |
| 390 | (dolist (tk changed-keys) | 342 | (dolist (tk changed-keys) |
| @@ -405,7 +357,7 @@ from Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) | |||
| 405 | (insert " " key-txt " ") | 357 | (insert " " key-txt " ") |
| 406 | (setq tot-len (length key-txt)) | 358 | (setq tot-len (length key-txt)) |
| 407 | (when (> 9 tot-len) | 359 | (when (> 9 tot-len) |
| 408 | (insert (make-string (- 9 tot-len) ? )) | 360 | (insert (make-string (- 9 tot-len) ?\s)) |
| 409 | (setq tot-len 9)) | 361 | (setq tot-len 9)) |
| 410 | ;; Insert a link describing the old binding: | 362 | ;; Insert a link describing the old binding: |
| 411 | (insert-button def-fun-txt | 363 | (insert-button def-fun-txt |
| @@ -417,7 +369,7 @@ from Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) | |||
| 417 | 'follow-link t) | 369 | 'follow-link t) |
| 418 | (setq tot-len (+ tot-len (length def-fun-txt))) | 370 | (setq tot-len (+ tot-len (length def-fun-txt))) |
| 419 | (when (> 36 tot-len) | 371 | (when (> 36 tot-len) |
| 420 | (insert (make-string (- 36 tot-len) ? ))) | 372 | (insert (make-string (- 36 tot-len) ?\s))) |
| 421 | (when (listp where) | 373 | (when (listp where) |
| 422 | (setq where "list")) | 374 | (setq where "list")) |
| 423 | ;; Tell where the old binding is now: | 375 | ;; Tell where the old binding is now: |
| @@ -438,29 +390,18 @@ from Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) | |||
| 438 | (insert "\n"))))) | 390 | (insert "\n"))))) |
| 439 | 391 | ||
| 440 | (insert " | 392 | (insert " |
| 441 | It is legitimate to change key bindings, but changed bindings do not | 393 | It is OK to change key bindings, but changed bindings do not |
| 442 | correspond to what the tutorial says. (See also " ) | 394 | correspond to what the tutorial says.\n\n") |
| 443 | (insert-button "Key Binding Conventions" | ||
| 444 | 'action | ||
| 445 | (lambda(button) (interactive) | ||
| 446 | (info | ||
| 447 | "(elisp) Key Binding Conventions") | ||
| 448 | (message "Type C-x 0 to close the new window")) | ||
| 449 | 'follow-link t) | ||
| 450 | (insert ".)\n\n") | ||
| 451 | (print-help-return-message))))) | 395 | (print-help-return-message))))) |
| 452 | 396 | ||
| 453 | (defun tutorial--find-changed-keys (default-keys) | 397 | (defun tutorial--find-changed-keys (default-keys) |
| 454 | "Find the key bindings that have changed. | 398 | "Find the key bindings used in the tutorial that have changed. |
| 455 | Check if the default Emacs key bindings that the tutorial depends | 399 | Return a list with elements of the form |
| 456 | on have been changed. | ||
| 457 | 400 | ||
| 458 | Return a list with the keys that have been changed. The element | 401 | '(KEY DEF-FUN DEF-FUN-TXT WHERE REMARK QUIET) |
| 459 | of this list have the following format: | ||
| 460 | 402 | ||
| 461 | \(list KEY DEF-FUN DEF-FUN-TXT WHERE REMARK) | 403 | where |
| 462 | 404 | ||
| 463 | Where | ||
| 464 | KEY is a key sequence whose standard binding has been changed | 405 | KEY is a key sequence whose standard binding has been changed |
| 465 | DEF-FUN is the standard binding of KEY | 406 | DEF-FUN is the standard binding of KEY |
| 466 | DEF-FUN-TXT is a short descriptive text for DEF-FUN | 407 | DEF-FUN-TXT is a short descriptive text for DEF-FUN |
| @@ -477,9 +418,10 @@ Where | |||
| 477 | rest of the list is used to show information when | 418 | rest of the list is used to show information when |
| 478 | the user clicks the link. | 419 | the user clicks the link. |
| 479 | 420 | ||
| 480 | KEY-FUN is the actual binding for KEY." | 421 | KEY-FUN is the actual binding for KEY. |
| 422 | QUIET is t if this changed keybinding should be handled quietly. | ||
| 423 | This is used by `tutorial--display-changes'." | ||
| 481 | (let (changed-keys remark) | 424 | (let (changed-keys remark) |
| 482 | ;; (default-keys tutorial--default-keys)) | ||
| 483 | (dolist (kdf default-keys) | 425 | (dolist (kdf default-keys) |
| 484 | ;; The variables below corresponds to those with the same names | 426 | ;; The variables below corresponds to those with the same names |
| 485 | ;; described in the doc string. | 427 | ;; described in the doc string. |
| @@ -518,26 +460,21 @@ Where | |||
| 518 | (setq remark (list "cua-mode, more info" 'cua-mode)) | 460 | (setq remark (list "cua-mode, more info" 'cua-mode)) |
| 519 | nil) | 461 | nil) |
| 520 | ((and cua-mode | 462 | ((and cua-mode |
| 521 | (or | 463 | (or (and (eq def-fun 'ESC-prefix) |
| 522 | (and (eq def-fun 'ESC-prefix) | 464 | (equal key-fun |
| 523 | (equal key-fun | ||
| 524 | `(keymap | 465 | `(keymap |
| 525 | (118 . cua-repeat-replace-region)))) | 466 | (118 . cua-repeat-replace-region))) |
| 526 | (and (eq def-fun 'mode-specific-command-prefix) | 467 | (setq def-fun-txt "\"ESC prefix\"")) |
| 527 | (equal key-fun | 468 | (and (eq def-fun 'mode-specific-command-prefix) |
| 528 | '(keymap | 469 | (equal key-fun |
| 529 | (timeout . copy-region-as-kill)))) | 470 | '(keymap |
| 530 | (and (eq def-fun 'Control-X-prefix) | 471 | (timeout . copy-region-as-kill))) |
| 531 | (equal key-fun | 472 | (setq def-fun-txt "\"C-c prefix\"")) |
| 532 | '(keymap (timeout . kill-region)))))) | 473 | (and (eq def-fun 'Control-X-prefix) |
| 474 | (equal key-fun | ||
| 475 | '(keymap (timeout . kill-region))) | ||
| 476 | (setq def-fun-txt "\"C-x prefix\"")))) | ||
| 533 | (setq remark (list "cua-mode replacement" 'cua-mode)) | 477 | (setq remark (list "cua-mode replacement" 'cua-mode)) |
| 534 | (cond | ||
| 535 | ((eq def-fun 'mode-specific-command-prefix) | ||
| 536 | (setq def-fun-txt "\"C-c prefix\"")) | ||
| 537 | ((eq def-fun 'Control-X-prefix) | ||
| 538 | (setq def-fun-txt "\"C-x prefix\"")) | ||
| 539 | ((eq def-fun 'ESC-prefix) | ||
| 540 | (setq def-fun-txt "\"ESC prefix\""))) | ||
| 541 | (setq where "Same key") | 478 | (setq where "Same key") |
| 542 | nil) | 479 | nil) |
| 543 | ;; viper-mode specials: | 480 | ;; viper-mode specials: |
| @@ -567,124 +504,110 @@ Where | |||
| 567 | key-fun def-fun key where)) | 504 | key-fun def-fun key where)) |
| 568 | nil)) | 505 | nil)) |
| 569 | (add-to-list 'changed-keys | 506 | (add-to-list 'changed-keys |
| 570 | (list key def-fun def-fun-txt where remark))))) | 507 | (list key def-fun def-fun-txt where remark nil))))) |
| 571 | changed-keys)) | 508 | changed-keys)) |
| 572 | 509 | ||
| 573 | (defvar tutorial--tab-map | 510 | (defun tutorial--key-description (key) |
| 574 | (let ((map (make-sparse-keymap))) | 511 | (let ((desc (key-description key))) |
| 575 | (define-key map [tab] 'forward-button) | 512 | (cond ((string= "ESC" desc) "<ESC>") |
| 576 | (define-key map [(shift tab)] 'backward-button) | 513 | ((string= "RET" desc) "<Return>") |
| 577 | (define-key map [(meta tab)] 'backward-button) | 514 | ((string= "DEL" desc) "<Delback>") |
| 578 | map) | 515 | (t desc)))) |
| 579 | "Keymap that allows tabbing between buttons.") | ||
| 580 | 516 | ||
| 581 | (defun tutorial--display-changes (changed-keys) | 517 | (defun tutorial--display-changes () |
| 582 | "Display changes to some default key bindings. | 518 | "Display changes to some default key bindings. |
| 583 | If some of the default key bindings that the tutorial depends on | 519 | If some of the default key bindings that the tutorial depends on |
| 584 | have been changed then display the changes in the tutorial buffer | 520 | have been changed then display the changes in the tutorial buffer |
| 585 | with some explanatory links. | 521 | with some explanatory links." |
| 586 | 522 | (let* ((changed-keys (tutorial--find-changed-keys | |
| 587 | CHANGED-KEYS should be a list in the format returned by | 523 | tutorial--default-keys)) |
| 588 | `tutorial--find-changed-keys'." | 524 | ;; Alist of element (DESC . CK) where DESC is the |
| 589 | (when (or changed-keys | 525 | ;; key-description of a changed key and CK is the |
| 590 | (boundp 'viper-mode-string)) | 526 | ;; corresponding element in `changed-keys'. |
| 527 | (changed-keys-alist | ||
| 528 | (mapcar (lambda (ck) (cons (tutorial--key-description (car ck)) ck)) | ||
| 529 | changed-keys)) | ||
| 530 | changed-key | ||
| 531 | (start (point)) | ||
| 532 | (case-fold-search nil) | ||
| 533 | (keybindings-regexp | ||
| 534 | (concat "[[:space:]]\\(" | ||
| 535 | (mapconcat (lambda (kdf) (regexp-quote | ||
| 536 | (tutorial--key-description | ||
| 537 | (nth 1 kdf)))) | ||
| 538 | tutorial--default-keys | ||
| 539 | "\\|") | ||
| 540 | "\\)[[:punct:][:space:]]"))) | ||
| 591 | ;; Need the custom button face for viper buttons: | 541 | ;; Need the custom button face for viper buttons: |
| 592 | (when (boundp 'viper-mode-string) | 542 | (if (boundp 'viper-mode-string) (require 'cus-edit)) |
| 593 | (require 'cus-edit)) | 543 | |
| 594 | (let ((start (point)) | 544 | (if (or changed-keys (boundp 'viper-mode-string)) |
| 595 | end | 545 | (let ((head (get-lang-string tutorial--lang 'tut-chgdhead)) |
| 596 | (head (get-lang-string tutorial--lang 'tut-chgdhead)) | 546 | (head2 (get-lang-string tutorial--lang 'tut-chgdhead2))) |
| 597 | (head2 (get-lang-string tutorial--lang 'tut-chgdhead2))) | 547 | (when (and head head2) |
| 598 | (when (and head head2) | 548 | (goto-char tutorial--point-before-chkeys) |
| 599 | (goto-char tutorial--point-before-chkeys) | 549 | (insert head " [") |
| 600 | (insert head) | 550 | (insert-button head2 'tutorial-buffer (current-buffer) |
| 601 | (insert-button head2 | 551 | 'action 'tutorial--detailed-help |
| 602 | 'tutorial-buffer | 552 | 'follow-link t 'face 'link) |
| 603 | (current-buffer) | 553 | (insert "]\n\n") |
| 604 | ;;'tutorial-arg arg | 554 | (add-text-properties tutorial--point-before-chkeys (point) |
| 605 | 'action | 555 | '(tutorial-remark remark |
| 606 | 'tutorial--detailed-help | 556 | face tutorial-warning-face |
| 607 | 'follow-link t | 557 | read-only t))))) |
| 608 | 'face 'link) | 558 | |
| 609 | (insert "]\n\n" ) | 559 | ;; Scan the tutorial for all key sequences. |
| 610 | (when changed-keys | 560 | (goto-char (point-min)) |
| 611 | (dolist (tk changed-keys) | 561 | (while (re-search-forward keybindings-regexp (point-max) t) |
| 612 | (let* ((def-fun (nth 1 tk)) | 562 | ;; Then highlight each rebound key sequence. |
| 613 | (key (nth 0 tk)) | 563 | ;; This avoids issuing a warning for, e.g., C-x C-b if C-b is rebound. |
| 614 | (def-fun-txt (nth 2 tk)) | 564 | (setq changed-key (assoc (match-string 1) changed-keys-alist)) |
| 615 | (where (nth 3 tk)) | 565 | (and changed-key |
| 616 | (remark (nth 4 tk)) | 566 | (not (get-text-property (match-beginning 1) 'tutorial-remark)) |
| 617 | (rem-fun (command-remapping def-fun)) | 567 | (let* ((desc (car changed-key)) |
| 618 | (key-txt (key-description key)) | 568 | (ck (cdr changed-key)) |
| 619 | (key-fun (key-binding key)) | 569 | (key (nth 0 ck)) |
| 620 | tot-len) | 570 | (def-fun (nth 1 ck)) |
| 621 | (unless (eq def-fun key-fun) | 571 | (where (nth 3 ck)) |
| 622 | ;; Mark the key in the tutorial text | 572 | s1 s2 help-string) |
| 623 | (unless (string= "Same key" where) | 573 | (unless (string= where "Same key") |
| 624 | (let ((here (point)) | 574 | (setq tutorial--point-after-chkeys (point-marker) |
| 625 | (case-fold-search nil) | 575 | s1 (get-lang-string tutorial--lang 'tut-chgdkey) |
| 626 | (key-desc (key-description key))) | 576 | s2 (get-lang-string tutorial--lang 'tut-chgdkey2) |
| 627 | (cond ((string= "ESC" key-desc) | 577 | help-string (and s1 s2 (format s1 desc where))) |
| 628 | (setq key-desc "<ESC>")) | 578 | (add-text-properties (match-beginning 1) (match-end 1) |
| 629 | ((string= "RET" key-desc) | 579 | '(face tutorial-warning-face |
| 630 | (setq key-desc "<Return>")) | 580 | tutorial-remark key-sequence)) |
| 631 | ((string= "DEL" key-desc) | 581 | (if help-string |
| 632 | (setq key-desc "<Delback>"))) | 582 | (if (nth 5 ck) |
| 633 | (while (re-search-forward | 583 | ;; Put help string in the tooltip. |
| 634 | (concat "[[:space:]]\\(" | 584 | (put-text-property (match-beginning 1) (match-end 1) |
| 635 | (regexp-quote key-desc) | 585 | 'help-echo help-string) |
| 636 | "\\)[[:space:]]") nil t) | 586 | ;; Put help string in the buffer. |
| 637 | (put-text-property (match-beginning 1) | 587 | (save-excursion |
| 638 | (match-end 1) | 588 | (setcar (nthcdr 5 ck) t) |
| 639 | 'tutorial-remark 'only-colored) | 589 | (forward-line) |
| 640 | (put-text-property (match-beginning 1) | 590 | ;; Two or more changed keys were on the same line. |
| 641 | (match-end 1) | 591 | (while (eq (get-text-property (point) 'tutorial-remark) |
| 642 | 'face 'tutorial-warning-face) | 592 | 'remark) |
| 643 | (forward-line) | 593 | (forward-line)) |
| 644 | (let ((s (get-lang-string tutorial--lang 'tut-chgdkey)) | 594 | (setq start (point)) |
| 645 | (s2 (get-lang-string tutorial--lang 'tut-chgdkey2)) | 595 | (insert "** " help-string " [") |
| 646 | (start (point)) | 596 | (insert-button s2 'tutorial-buffer (current-buffer) |
| 647 | end) | 597 | 'action 'tutorial--detailed-help |
| 648 | (when (and s s2) | 598 | 'explain-key-desc desc 'follow-link t |
| 649 | (setq s (format s key-desc where s2)) | 599 | 'face 'link) |
| 650 | (insert s) | 600 | (insert "] **\n") |
| 651 | (insert-button s2 | 601 | (add-text-properties start (point) |
| 652 | 'tutorial-buffer | 602 | '(tutorial-remark remark |
| 653 | (current-buffer) | 603 | rear-nonsticky t |
| 654 | ;;'tutorial-arg arg | 604 | face tutorial-warning-face |
| 655 | 'action | 605 | read-only t))))))))))) |
| 656 | 'tutorial--detailed-help | ||
| 657 | 'explain-key-desc key-desc | ||
| 658 | 'follow-link t | ||
| 659 | 'face 'link) | ||
| 660 | (insert "] **") | ||
| 661 | (insert "\n") | ||
| 662 | (setq end (point)) | ||
| 663 | (put-text-property start end 'local-map tutorial--tab-map) | ||
| 664 | ;; Add a property so we can remove the remark: | ||
| 665 | (put-text-property start end 'tutorial-remark t) | ||
| 666 | (put-text-property start end | ||
| 667 | 'face 'tutorial-warning-face) | ||
| 668 | (put-text-property start end 'read-only t)))) | ||
| 669 | (goto-char here))))))) | ||
| 670 | |||
| 671 | |||
| 672 | (setq end (point)) | ||
| 673 | ;; Make the area with information about change key | ||
| 674 | ;; bindings stand out: | ||
| 675 | (put-text-property start end 'tutorial-remark t) | ||
| 676 | (put-text-property start end | ||
| 677 | 'face 'tutorial-warning-face) | ||
| 678 | ;; Make it possible to use Tab/S-Tab between fields in | ||
| 679 | ;; this area: | ||
| 680 | (put-text-property start end 'local-map tutorial--tab-map) | ||
| 681 | (setq tutorial--point-after-chkeys (point-marker)) | ||
| 682 | ;; Make this area read-only: | ||
| 683 | (put-text-property start end 'read-only t))))) | ||
| 684 | 606 | ||
| 685 | (defun tutorial--saved-dir () | 607 | (defun tutorial--saved-dir () |
| 686 | "Directory where to save tutorials." | 608 | "Directory to which tutorials are saved." |
| 687 | (expand-file-name ".emacstut" "~/")) | 609 | (expand-file-name "tutorial" |
| 610 | (if (eq system-type 'ms-dos) "~/_emacs.d/" "~/.emacs.d/"))) | ||
| 688 | 611 | ||
| 689 | (defun tutorial--saved-file () | 612 | (defun tutorial--saved-file () |
| 690 | "File name in which to save tutorials." | 613 | "File name in which to save tutorials." |
| @@ -711,11 +634,8 @@ CHANGED-KEYS should be a list in the format returned by | |||
| 711 | (unless prop-end | 634 | (unless prop-end |
| 712 | (setq prop-end (point-max))) | 635 | (setq prop-end (point-max))) |
| 713 | (goto-char prop-end) | 636 | (goto-char prop-end) |
| 714 | (if (eq prop-val 'only-colored) | 637 | (unless (eq prop-val 'key-sequence) |
| 715 | (put-text-property prop-start prop-end 'face '(:background nil)) | 638 | (delete-region prop-start prop-end)))))) |
| 716 | (let ((orig-text (get-text-property prop-start 'tutorial-orig))) | ||
| 717 | (delete-region prop-start prop-end) | ||
| 718 | (when orig-text (insert orig-text)))))))) | ||
| 719 | 639 | ||
| 720 | (defun tutorial--save-tutorial () | 640 | (defun tutorial--save-tutorial () |
| 721 | "Save the tutorial buffer. | 641 | "Save the tutorial buffer. |
| @@ -724,9 +644,10 @@ showing changed keys. It also saves the point position and the | |||
| 724 | position where the display of changed bindings was inserted." | 644 | position where the display of changed bindings was inserted." |
| 725 | ;; This runs in a hook so protect it: | 645 | ;; This runs in a hook so protect it: |
| 726 | (condition-case err | 646 | (condition-case err |
| 727 | (tutorial--save-tutorial-to (tutorial--saved-file)) | 647 | (if (y-or-n-p "Save your position in the tutorial? ") |
| 728 | (error (message "Error saving tutorial state: %s" (error-message-string err)) | 648 | (tutorial--save-tutorial-to (tutorial--saved-file))) |
| 729 | (sit-for 4)))) | 649 | (error (message "Error saving tutorial state: %s" |
| 650 | (error-message-string err))))) | ||
| 730 | 651 | ||
| 731 | (defun tutorial--save-tutorial-to (saved-file) | 652 | (defun tutorial--save-tutorial-to (saved-file) |
| 732 | "Save the tutorial buffer to SAVED-FILE. | 653 | "Save the tutorial buffer to SAVED-FILE. |
| @@ -908,13 +829,7 @@ Run the Viper tutorial? ")) | |||
| 908 | (forward-line) | 829 | (forward-line) |
| 909 | (setq tutorial--point-before-chkeys (point-marker))) | 830 | (setq tutorial--point-before-chkeys (point-marker))) |
| 910 | 831 | ||
| 911 | 832 | (tutorial--display-changes) | |
| 912 | ;; Check if there are key bindings that may disturb the | ||
| 913 | ;; tutorial. If so tell the user. | ||
| 914 | (let ((changed-keys (tutorial--find-changed-keys tutorial--default-keys))) | ||
| 915 | (when changed-keys | ||
| 916 | (tutorial--display-changes changed-keys))) | ||
| 917 | |||
| 918 | 833 | ||
| 919 | ;; Clear message: | 834 | ;; Clear message: |
| 920 | (unless dont-ask-for-revert | 835 | (unless dont-ask-for-revert |
| @@ -971,22 +886,17 @@ Run the Viper tutorial? ")) | |||
| 971 | ;; are currently only used in the tutorial. | 886 | ;; are currently only used in the tutorial. |
| 972 | 887 | ||
| 973 | (defconst lang-strings | 888 | (defconst lang-strings |
| 974 | '( | 889 | '(("English" . |
| 975 | ("English" . | 890 | ((tut-chgdkey . "%s has been rebound, but you can use %s instead") |
| 976 | ( | 891 | (tut-chgdkey2 . "More") |
| 977 | (tut-chgdkey . "** The key %s has been rebound, but you can use %s instead [") | ||
| 978 | (tut-chgdkey2 . "More information") | ||
| 979 | (tut-chgdhead . " | 892 | (tut-chgdhead . " |
| 980 | NOTICE: The main purpose of the Emacs tutorial is to teach you | 893 | NOTICE: The main purpose of the Emacs tutorial is to teach you |
| 981 | the most important standard Emacs commands (key bindings). | 894 | the most important standard Emacs commands (key bindings). |
| 982 | However, your Emacs has been customized by changing some of | 895 | However, your Emacs has been customized by changing some of |
| 983 | these basic editing commands, so it doesn't correspond to the | 896 | these basic editing commands, so it doesn't correspond to the |
| 984 | tutorial. We have inserted colored notices where the altered | 897 | tutorial. We have inserted colored notices where the altered |
| 985 | commands have been introduced. [") | 898 | commands have been introduced.") |
| 986 | (tut-chgdhead2 . "Details") | 899 | (tut-chgdhead2 . "More")))) |
| 987 | ) | ||
| 988 | ) | ||
| 989 | ) | ||
| 990 | "Language specific strings for Emacs. | 900 | "Language specific strings for Emacs. |
| 991 | This is an association list with the keys equal to the strings | 901 | This is an association list with the keys equal to the strings |
| 992 | that can be returned by `read-language-name'. The elements in | 902 | that can be returned by `read-language-name'. The elements in |