summaryrefslogtreecommitdiff
path: root/modes/modes.el
blob: 538ab938bdc43b3ee556627040c240d6f1ff9cd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
;;; A modal interface

;;; Dictionary

;; ;;;###autoload
;; (defvar modes-concepts
;;   (list 'down 'up 'left 'right 'next 'previous
;;         'down-max 'up-max 'left-max 'right-max 'next-max 'previous-max
;; 	'jump)
;;   "The concepts that a mode can define.")


;;;###autoload
(defvar modes-concept-keymap
  (list
   (cons 'down '(?j down))
   (cons 'up '(?k up))
   (cons 'right '(?l right))
   (cons 'left '(?h left))
   (cons 'forward ?n)
   (cons 'backward ?p)
   (cons 'down-max '([?J] S-down))
   (cons 'up-max '([?K] S-up))
   (cons 'right-max '([?L] S-right))
   (cons 'left-max '([?H] S-left))
   (cons 'forwrad-max ?N)
   (cons 'backward-max ?P)
   (cons 'jump 'tab)
   (cons 'other ?o)
   (cons 'undo ?u)
   (cons 'redo ?U))
  "An alist that maps concepts to keys.")

;;;###autoload
(defvar modes-map-alist (cons (cons 'modes-mode '(keymap "Modes alist")) nil)
  "The current mode map.")

(push 'modes-map-alist emulation-mode-map-alists)

;;;###autoload
(define-minor-mode modes-mode "A modal interface" nil "Modes" nil :global t)

;;;###autoload
(defun modes-process-key (key)
  "Process keys appropriately.
The return value is a list of keys acceptable by `define-key'."
  (cond
   ((stringp key) (list (kbd key)))
   ((vectorp key) (list key))
   ((or (symbolp key) (integerp key)) (list (vector key)))
   ((listp key)
    (mapcar (lambda (k)
	      (cond
	       ((stringp k) (kbd k))
	       ((vectorp k) k)
	       ((integerp k) (vector k))
	       ((symbolp k) (vector k))
	       (t (user-error "Unsupported key: %S" k))))
	    key))
   (t (user-error "Unsupported key: %S" key))))

;;;###autoload
(defun modes-set-mode (alist)
  "Set a mode.
A mode is just an ALIST between concepts and functions."
  (let ((map (cons 'keymap "Modes")))
    (dolist (concept-to-function alist)
      (let* ((key (or
		   (alist-get (car concept-to-function)
			      modes-concept-keymap)
		   (error "Unsupported concept: %S" (car concept-to-function))))
	     (keys (modes-process-key key))
	     (fun (cdr concept-to-function)))
	(mapc (lambda (k) (define-key map k fun)) keys)))
    (set 'modes-map-alist (list (cons 'modes-mode map)))))

;;; Modes

;;; buffer mode

(defun switch-to-last-buffer ()
  "Switch to the last buffer."
  (interactive)
  (switch-to-buffer (other-buffer)))

(set 'modes-buffer-mode
     '((down . next-buffer)
       (up . previous-buffer)
       (other . switch-to-last-buffer)
       (jump . ibuffer)))