Sources/OrgCore/Keymap/Presets.swift
189 lines · 4746 bytes
1/// The keymaps the app ships. The user's `keymap.toml` is layered on top of the chosen one.
2public enum KeymapPreset: String, Sendable, CaseIterable {
3 case emacs, mac
4
5 public var title: String {
6 switch self {
7 case .emacs: "Emacs"
8 case .mac: "Mac"
9 }
10 }
11
12 public var keymap: Keymap {
13 var problems: [String] = []
14 let map = try! Keymap(toml: toml, problems: &problems)
15 precondition(problems.isEmpty, "preset \(rawValue): \(problems)")
16 return map
17 }
18
19 public var toml: String {
20 switch self {
21 case .emacs: Self.common + Self.emacsBindings
22 case .mac: Self.common + Self.macBindings
23 }
24 }
25
26 static let common = """
27 [[bind]]
28 keys = "TAB"
29 command = "org.cycle"
30 when = "heading"
31
32 [[bind]]
33 keys = "S-TAB"
34 command = "org.cycle-global"
35
36 """
37
38 static let emacsBindings = """
39 # Movement and editing. With a mark set (C-SPC), movement extends the region.
40 [[bind]]
41 keys = "C-f"
42 command = "edit.forward-char"
43 [[bind]]
44 keys = "C-b"
45 command = "edit.backward-char"
46 [[bind]]
47 keys = "C-n"
48 command = "edit.next-line"
49 [[bind]]
50 keys = "C-p"
51 command = "edit.previous-line"
52 [[bind]]
53 keys = "C-a"
54 command = "edit.beginning-of-line"
55 [[bind]]
56 keys = "C-e"
57 command = "edit.end-of-line"
58 [[bind]]
59 keys = "M-f"
60 command = "edit.forward-word"
61 [[bind]]
62 keys = "M-b"
63 command = "edit.backward-word"
64 [[bind]]
65 keys = "M-<"
66 command = "edit.beginning-of-buffer"
67 [[bind]]
68 keys = "M->"
69 command = "edit.end-of-buffer"
70 [[bind]]
71 keys = "C-v"
72 command = "edit.scroll-up"
73 [[bind]]
74 keys = "M-v"
75 command = "edit.scroll-down"
76 [[bind]]
77 keys = "C-l"
78 command = "edit.recenter"
79 [[bind]]
80 keys = "C-d"
81 command = "edit.delete-char"
82 [[bind]]
83 keys = "M-d"
84 command = "edit.kill-word"
85 [[bind]]
86 keys = "M-DEL"
87 command = "edit.backward-kill-word"
88 [[bind]]
89 keys = "C-k"
90 command = "edit.kill-line"
91 [[bind]]
92 keys = "C-y"
93 command = "edit.yank"
94 [[bind]]
95 keys = "C-SPC"
96 command = "edit.set-mark"
97 [[bind]]
98 keys = "C-x h"
99 command = "edit.select-all"
100 [[bind]]
101 keys = "C-w"
102 command = "edit.kill-region"
103 [[bind]]
104 keys = "M-w"
105 command = "edit.copy-region"
106 [[bind]]
107 keys = "C-/"
108 command = "edit.undo"
109 [[bind]]
110 keys = "C-_"
111 command = "edit.undo"
112 [[bind]]
113 keys = "C-x u"
114 command = "edit.undo"
115 [[bind]]
116 keys = "C-g"
117 command = "edit.keyboard-quit"
118 [[bind]]
119 keys = "C-t"
120 command = "edit.transpose-chars"
121 [[bind]]
122 keys = "C-s"
123 command = "edit.find"
124 [[bind]]
125 keys = "C-r"
126 command = "edit.find"
127
128 # Files and commands
129 [[bind]]
130 keys = "C-x C-s"
131 command = "app.save"
132 [[bind]]
133 keys = "C-x C-f"
134 command = "app.quick-open"
135 [[bind]]
136 keys = "C-x b"
137 command = "app.quick-open"
138 [[bind]]
139 keys = "M-x"
140 command = "app.palette"
141
142 # Org
143 [[bind]]
144 keys = "C-c C-t"
145 command = "org.todo.cycle"
146 [[bind]]
147 keys = "S-<right>"
148 command = "org.todo.cycle"
149 when = "heading"
150 [[bind]]
151 keys = "S-<up>"
152 command = "org.priority.up"
153 when = "heading"
154 [[bind]]
155 keys = "S-<down>"
156 command = "org.priority.down"
157 when = "heading"
158 [[bind]]
159 keys = "M-<left>"
160 command = "org.heading.promote"
161 when = "heading"
162 [[bind]]
163 keys = "M-<right>"
164 command = "org.heading.demote"
165 when = "heading"
166
167 """
168
169 /// Standard Mac text keys stay as they are; org commands use Control-Command chords, which
170 /// macOS text editing leaves free.
171 static let macBindings = """
172 [[bind]]
173 keys = "C-s-t"
174 command = "org.todo.cycle"
175 [[bind]]
176 keys = "C-s-<up>"
177 command = "org.priority.up"
178 [[bind]]
179 keys = "C-s-<down>"
180 command = "org.priority.down"
181 [[bind]]
182 keys = "C-s-<left>"
183 command = "org.heading.promote"
184 [[bind]]
185 keys = "C-s-<right>"
186 command = "org.heading.demote"
187
188 """
189}