diff options
| author | Eli Barzilay | 2015-11-27 10:21:30 -0500 |
|---|---|---|
| committer | Eli Barzilay | 2015-11-29 12:49:06 -0500 |
| commit | 1b4570bc08b35ba98d48b3a8465948949cf5a31f (patch) | |
| tree | c76712140d22a829da93453b11e35af92d1b7486 | |
| parent | e875e68b325f1d621a21798d4c4244790ecaf77f (diff) | |
| download | emacs-1b4570bc08b35ba98d48b3a8465948949cf5a31f.tar.gz emacs-1b4570bc08b35ba98d48b3a8465948949cf5a31f.zip | |
* lisp/calculator.el: Re-do key bindings.
Use a helper function that arranges a parent keymap that binds alternate
case keys so if some letter key is unbound and it's un/shifted version
is, it will get used. This makes the global-map trickery unnecessary.
Also switch to passing strings that name keys through `kbd'.
| -rw-r--r-- | lisp/calculator.el | 179 |
1 files changed, 89 insertions, 90 deletions
diff --git a/lisp/calculator.el b/lisp/calculator.el index 55ef461990c..3d44b6d86c5 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el | |||
| @@ -290,7 +290,7 @@ user-defined operators, use `calculator-user-operators' instead.") | |||
| 290 | (defvar calculator-operators nil | 290 | (defvar calculator-operators nil |
| 291 | "The calculator operators, each a list with: | 291 | "The calculator operators, each a list with: |
| 292 | 292 | ||
| 293 | 1. The key that is bound to for this operation, a string that is | 293 | 1. The key(s) that is bound to for this operation, a string that is |
| 294 | used with `kbd'; | 294 | used with `kbd'; |
| 295 | 295 | ||
| 296 | 2. The displayed symbol for this function; | 296 | 2. The displayed symbol for this function; |
| @@ -313,8 +313,8 @@ user-defined operators, use `calculator-user-operators' instead.") | |||
| 313 | 313 | ||
| 314 | It it possible have a unary prefix version of a binary operator if it | 314 | It it possible have a unary prefix version of a binary operator if it |
| 315 | comes later in this list. If the list begins with the symbol `nobind', | 315 | comes later in this list. If the list begins with the symbol `nobind', |
| 316 | then no key binding will take place -- this is only useful for | 316 | then no key binding will take place -- this is only used for predefined |
| 317 | predefined keys. | 317 | keys. |
| 318 | 318 | ||
| 319 | Use `calculator-user-operators' to add operators to this list, see its | 319 | Use `calculator-user-operators' to add operators to this list, see its |
| 320 | documentation for an example.") | 320 | documentation for an example.") |
| @@ -371,74 +371,95 @@ Used for repeating operations in calculator-repR/L.") | |||
| 371 | (list (cons ?e float-e) (cons ?p float-pi))) | 371 | (list (cons ?e float-e) (cons ?p float-pi))) |
| 372 | "The association list of calculator register values.") | 372 | "The association list of calculator register values.") |
| 373 | 373 | ||
| 374 | (defvar calculator-saved-global-map nil | ||
| 375 | "Saved global key map.") | ||
| 376 | |||
| 377 | (defvar calculator-restart-other-mode nil | 374 | (defvar calculator-restart-other-mode nil |
| 378 | "Used to hack restarting with the electric mode changed.") | 375 | "Used to hack restarting with the electric mode changed.") |
| 379 | 376 | ||
| 380 | ;;;--------------------------------------------------------------------- | 377 | ;;;--------------------------------------------------------------------- |
| 381 | ;;; Key bindings | 378 | ;;; Key bindings |
| 382 | 379 | ||
| 380 | (defun calculator-define-key (key cmd &optional map) | ||
| 381 | ;; arranges for unbound alphabetic keys to be used as their un/shifted | ||
| 382 | ;; versions if those are bound (mimics the usual Emacs global | ||
| 383 | ;; bindings) | ||
| 384 | (let* ((key (if (stringp key) (kbd key) key)) | ||
| 385 | (map (or map calculator-mode-map)) | ||
| 386 | (omap (keymap-parent map))) | ||
| 387 | (define-key map key cmd) | ||
| 388 | ;; "other" map, used for case-flipped bindings | ||
| 389 | (unless omap | ||
| 390 | (setq omap (make-sparse-keymap)) | ||
| 391 | (suppress-keymap omap t) | ||
| 392 | (set-keymap-parent map omap)) | ||
| 393 | (let ((m omap)) | ||
| 394 | ;; bind all case-flipped versions | ||
| 395 | (dotimes (i (length key)) | ||
| 396 | (let* ((c (aref key i)) | ||
| 397 | (k (vector c)) | ||
| 398 | (b (lookup-key m k)) | ||
| 399 | (defkey (lambda (x) | ||
| 400 | (define-key m k x) | ||
| 401 | (when (and (characterp c) | ||
| 402 | (or (<= ?A c ?Z) (<= ?a c ?z))) | ||
| 403 | (define-key m (vector (logxor 32 c)) x))))) | ||
| 404 | (cond ((= i (1- (length key))) | ||
| 405 | ;; prefer longer sequences | ||
| 406 | (unless (keymapp b) (funcall defkey cmd))) | ||
| 407 | ((keymapp b) (setq m b)) | ||
| 408 | (t (let ((sub (make-sparse-keymap))) | ||
| 409 | (funcall defkey sub) | ||
| 410 | (setq m sub))))))))) | ||
| 411 | |||
| 383 | (defvar calculator-mode-map | 412 | (defvar calculator-mode-map |
| 384 | (let ((map (make-sparse-keymap))) | 413 | (let ((map (make-sparse-keymap))) |
| 385 | (suppress-keymap map t) | 414 | (suppress-keymap map t) |
| 386 | (define-key map "i" nil) | 415 | (dolist (x '((calculator-digit |
| 387 | (define-key map "o" nil) | 416 | "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" |
| 388 | (let ((p | 417 | "d" "f" "<kp-0>" "<kp-1>" "<kp-2>" "<kp-3>" "<kp-4>" |
| 389 | '((calculator-open-paren "[") | 418 | "<kp-5>" "<kp-6>" "<kp-7>" "<kp-8>" "<kp-9>") |
| 390 | (calculator-close-paren "]") | 419 | (calculator-open-paren "[") |
| 391 | (calculator-op-or-exp "+" "-" [kp-add] [kp-subtract]) | 420 | (calculator-close-paren "]") |
| 392 | (calculator-digit "0" "1" "2" "3" "4" "5" "6" "7" "8" | 421 | (calculator-op-or-exp "+" "-" |
| 393 | "9" "a" "b" "c" "d" "f" | 422 | "<kp-add>" "<kp-subtract>") |
| 394 | [kp-0] [kp-1] [kp-2] [kp-3] [kp-4] | 423 | (calculator-op "<kp-divide>" "<kp-multiply>") |
| 395 | [kp-5] [kp-6] [kp-7] [kp-8] [kp-9]) | 424 | (calculator-decimal "." "<kp-decimal>") |
| 396 | (calculator-op [kp-divide] [kp-multiply]) | 425 | (calculator-exp "e") |
| 397 | (calculator-decimal "." [kp-decimal]) | 426 | (calculator-dec/deg-mode "D") |
| 398 | (calculator-exp "e") | 427 | (calculator-set-register "s") |
| 399 | (calculator-dec/deg-mode "D") | 428 | (calculator-get-register "g") |
| 400 | (calculator-set-register "s") | 429 | (calculator-radix-mode "H" "X" "O" "B") |
| 401 | (calculator-get-register "g") | 430 | (calculator-radix-input-mode "iD" "iH" "iX" "iO" "iB") |
| 402 | (calculator-radix-mode "H" "X" "O" "B") | 431 | (calculator-radix-output-mode "oD" "oH" "oX" "oO" "oB") |
| 403 | (calculator-radix-input-mode "id" "ih" "ix" "io" "ib" | 432 | (calculator-rotate-displayer "'") |
| 404 | "iD" "iH" "iX" "iO" "iB") | 433 | (calculator-rotate-displayer-back "\"") |
| 405 | (calculator-radix-output-mode "od" "oh" "ox" "oo" "ob" | 434 | (calculator-displayer-prev "{") |
| 406 | "oD" "oH" "oX" "oO" "oB") | 435 | (calculator-displayer-next "}") |
| 407 | (calculator-rotate-displayer "'") | 436 | (calculator-saved-up "<up>" "C-p") |
| 408 | (calculator-rotate-displayer-back "\"") | 437 | (calculator-saved-down "<down>" "C-n") |
| 409 | (calculator-displayer-prev "{") | 438 | (calculator-quit "q" "C-g") |
| 410 | (calculator-displayer-next "}") | 439 | (calculator-enter "<enter>" "<linefeed>" |
| 411 | (calculator-saved-up [up] [?\C-p]) | 440 | "<kp-enter>" "<return>" |
| 412 | (calculator-saved-down [down] [?\C-n]) | 441 | "RET" "LFD") |
| 413 | (calculator-quit "q" [?\C-g]) | 442 | (calculator-save-on-list "SPC" "<space>") |
| 414 | (calculator-enter [enter] [linefeed] [kp-enter] | 443 | (calculator-clear-saved "C-c" "<C-delete>") |
| 415 | [return] [?\r] [?\n]) | 444 | (calculator-save-and-quit "<C-return>" "<C-kp-enter>") |
| 416 | (calculator-save-on-list " " [space]) | 445 | (calculator-paste "<insert>" "<S-insert>" |
| 417 | (calculator-clear-saved [?\C-c] [(control delete)]) | 446 | "<paste>" "<mouse-2>" "C-y") |
| 418 | (calculator-save-and-quit [(control return)] | 447 | (calculator-clear "<delete>" "DEL" "C-d") |
| 419 | [(control kp-enter)]) | 448 | (calculator-help "h" "?" "<f1>" "<help>") |
| 420 | (calculator-paste [insert] [(shift insert)] | 449 | (calculator-copy "<C-insert>" "<copy>") |
| 421 | [paste] [mouse-2] [?\C-y]) | 450 | (calculator-backspace "<backspace>") |
| 422 | (calculator-clear [delete] [?\C-?] [?\C-d]) | 451 | )) |
| 423 | (calculator-help [?h] [??] [f1] [help]) | 452 | ;; reverse the keys so earlier definitions come last -- makes the |
| 424 | (calculator-copy [(control insert)] [copy]) | 453 | ;; more sensible bindings visible in the menu |
| 425 | (calculator-backspace [backspace]) | 454 | (dolist (k (reverse (cdr x))) |
| 426 | ))) | 455 | (calculator-define-key k (car x) map))) |
| 427 | (while p | ||
| 428 | ;; reverse the keys so earlier definitions come last -- makes | ||
| 429 | ;; the more sensible bindings visible in the menu | ||
| 430 | (let ((func (caar p)) (keys (reverse (cdar p)))) | ||
| 431 | (while keys | ||
| 432 | (define-key map (car keys) func) | ||
| 433 | (setq keys (cdr keys)))) | ||
| 434 | (setq p (cdr p)))) | ||
| 435 | (if calculator-bind-escape | 456 | (if calculator-bind-escape |
| 436 | (progn (define-key map [?\e] 'calculator-quit) | 457 | (progn (calculator-define-key "ESC" 'calculator-quit map) |
| 437 | (define-key map [escape] 'calculator-quit)) | 458 | (calculator-define-key "<escape>" 'calculator-quit map)) |
| 438 | (define-key map [?\e ?\e ?\e] 'calculator-quit)) | 459 | (calculator-define-key "ESC ESC ESC" 'calculator-quit map)) |
| 439 | ;; make C-h work in text-mode | 460 | ;; make C-h work in text-mode |
| 440 | (unless window-system | 461 | (unless window-system |
| 441 | (define-key map [?\C-h] 'calculator-backspace)) | 462 | (calculator-define-key "C-h" 'calculator-backspace map)) |
| 442 | ;; set up a menu | 463 | ;; set up a menu |
| 443 | (when (and calculator-use-menu (not (boundp 'calculator-menu))) | 464 | (when (and calculator-use-menu (not (boundp 'calculator-menu))) |
| 444 | (let ((radix-selectors | 465 | (let ((radix-selectors |
| @@ -691,19 +712,14 @@ See the documentation for `calculator-mode' for more information." | |||
| 691 | (if calculator-electric-mode | 712 | (if calculator-electric-mode |
| 692 | (save-window-excursion | 713 | (save-window-excursion |
| 693 | (require 'electric) (message nil) ; hide load message | 714 | (require 'electric) (message nil) ; hide load message |
| 694 | (let (old-g-map old-l-map | 715 | (let ((old-buf (window-buffer (minibuffer-window))) |
| 695 | (old-buf (window-buffer (minibuffer-window))) | ||
| 696 | (echo-keystrokes 0) | 716 | (echo-keystrokes 0) |
| 697 | (garbage-collection-messages nil)) ; no gc msg when electric | 717 | (garbage-collection-messages nil)) ; no gc msg when electric |
| 698 | (set-window-buffer (minibuffer-window) calculator-buffer) | 718 | (set-window-buffer (minibuffer-window) calculator-buffer) |
| 699 | (select-window (minibuffer-window)) | 719 | (select-window (minibuffer-window)) |
| 700 | (calculator-reset) | 720 | (calculator-reset) |
| 701 | (calculator-update-display) | 721 | (calculator-update-display) |
| 702 | (setq old-l-map (current-local-map) | 722 | (use-local-map calculator-mode-map) |
| 703 | old-g-map (current-global-map) | ||
| 704 | calculator-saved-global-map (current-global-map)) | ||
| 705 | (use-local-map nil) | ||
| 706 | (use-global-map calculator-mode-map) | ||
| 707 | (run-hooks 'calculator-mode-hook) | 723 | (run-hooks 'calculator-mode-hook) |
| 708 | (unwind-protect | 724 | (unwind-protect |
| 709 | (catch 'calculator-done | 725 | (catch 'calculator-done |
| @@ -714,9 +730,7 @@ See the documentation for `calculator-mode' for more information." | |||
| 714 | nil | 730 | nil |
| 715 | (lambda (_x _y) (calculator-update-display)))) | 731 | (lambda (_x _y) (calculator-update-display)))) |
| 716 | (set-window-buffer (minibuffer-window) old-buf) | 732 | (set-window-buffer (minibuffer-window) old-buf) |
| 717 | (kill-buffer calculator-buffer) | 733 | (kill-buffer calculator-buffer)))) |
| 718 | (use-local-map old-l-map) | ||
| 719 | (use-global-map old-g-map)))) | ||
| 720 | (progn | 734 | (progn |
| 721 | (cond | 735 | (cond |
| 722 | ((not (get-buffer-window calculator-buffer)) | 736 | ((not (get-buffer-window calculator-buffer)) |
| @@ -783,23 +797,11 @@ Defaults to 1." | |||
| 783 | Adds MORE-OPS to `calculator-operator', called initially to handle | 797 | Adds MORE-OPS to `calculator-operator', called initially to handle |
| 784 | `calculator-initial-operators' and `calculator-user-operators'." | 798 | `calculator-initial-operators' and `calculator-user-operators'." |
| 785 | (let ((added-ops nil)) | 799 | (let ((added-ops nil)) |
| 786 | (while more-ops | 800 | (dolist (op more-ops) |
| 787 | (unless (eq (caar more-ops) 'nobind) | 801 | (unless (eq (car op) 'nobind) |
| 788 | (let ((i -1) (key (caar more-ops))) | 802 | (calculator-define-key (car op) 'calculator-op)) |
| 789 | ;; make sure the key is undefined, so it's easy to define | 803 | (push (if (eq (car op) 'nobind) (cdr op) op) |
| 790 | ;; prefix keys | 804 | added-ops)) |
| 791 | (while (< (setq i (1+ i)) (length key)) | ||
| 792 | (unless (keymapp (lookup-key calculator-mode-map | ||
| 793 | (substring key 0 (1+ i)))) | ||
| 794 | (define-key calculator-mode-map (substring key 0 (1+ i)) | ||
| 795 | nil) | ||
| 796 | (setq i (length key)))) | ||
| 797 | (define-key calculator-mode-map key 'calculator-op))) | ||
| 798 | (push (if (eq (caar more-ops) 'nobind) | ||
| 799 | (cdar more-ops) | ||
| 800 | (car more-ops)) | ||
| 801 | added-ops) | ||
| 802 | (setq more-ops (cdr more-ops))) | ||
| 803 | ;; added-ops come first, but in correct order | 805 | ;; added-ops come first, but in correct order |
| 804 | (setq calculator-operators | 806 | (setq calculator-operators |
| 805 | (append (nreverse added-ops) calculator-operators)))) | 807 | (append (nreverse added-ops) calculator-operators)))) |
| @@ -1569,14 +1571,11 @@ registers." | |||
| 1569 | (if (eq last-command 'calculator-help) | 1571 | (if (eq last-command 'calculator-help) |
| 1570 | (let ((mode-name "Calculator") | 1572 | (let ((mode-name "Calculator") |
| 1571 | (major-mode 'calculator-mode) | 1573 | (major-mode 'calculator-mode) |
| 1572 | (g-map (current-global-map)) | ||
| 1573 | (win (selected-window))) | 1574 | (win (selected-window))) |
| 1574 | (require 'ehelp) | 1575 | (require 'ehelp) |
| 1575 | (if (not calculator-electric-mode) | 1576 | (if (not calculator-electric-mode) |
| 1576 | (describe-mode) | 1577 | (describe-mode) |
| 1577 | (progn (use-global-map calculator-saved-global-map) | 1578 | (electric-describe-mode)) |
| 1578 | (electric-describe-mode) | ||
| 1579 | (use-global-map g-map))) | ||
| 1580 | (select-window win) | 1579 | (select-window win) |
| 1581 | (message nil)) | 1580 | (message nil)) |
| 1582 | (let ((one (one-window-p t)) | 1581 | (let ((one (one-window-p t)) |