aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorEli Barzilay2015-11-27 10:21:30 -0500
committerEli Barzilay2015-11-29 12:49:06 -0500
commit1b4570bc08b35ba98d48b3a8465948949cf5a31f (patch)
treec76712140d22a829da93453b11e35af92d1b7486 /lisp
parente875e68b325f1d621a21798d4c4244790ecaf77f (diff)
downloademacs-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'.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/calculator.el179
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
2931. The key that is bound to for this operation, a string that is 2931. The key(s) that is bound to for this operation, a string that is
294 used with `kbd'; 294 used with `kbd';
295 295
2962. The displayed symbol for this function; 2962. The displayed symbol for this function;
@@ -313,8 +313,8 @@ user-defined operators, use `calculator-user-operators' instead.")
313 313
314It it possible have a unary prefix version of a binary operator if it 314It it possible have a unary prefix version of a binary operator if it
315comes later in this list. If the list begins with the symbol `nobind', 315comes later in this list. If the list begins with the symbol `nobind',
316then no key binding will take place -- this is only useful for 316then no key binding will take place -- this is only used for predefined
317predefined keys. 317keys.
318 318
319Use `calculator-user-operators' to add operators to this list, see its 319Use `calculator-user-operators' to add operators to this list, see its
320documentation for an example.") 320documentation 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."
783Adds MORE-OPS to `calculator-operator', called initially to handle 797Adds 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))