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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
Title: Concepts and designs of modes
Author: JSDurand
Created: 2021-01-01
-------------------------------------
======================================================================
Introduction
======================================================================
In this document, and in this document only, sometimes we refer to
Emacs as "the editor", though the situations referred to are
definitely different from those of other editors, and the editor Emacs
does not represent other editors in any way. This reference is solely
out of personal preferences.
When we edit texts through a text editor, since there are a lot of
functionalities we would like to perform in the editor, we oft end up
with binding many keys with various functions in the editor. This
causes a problem: the keys are either too long to conveniently press
or too compactly packaged that it requires experience to remember and
use them at ease (what if we can execute the form “(require
'experience)” in Emacs ;P).
The proposed way in this document to solve this dilemma is to make
keys behave according to the "contexts" of the editor. That is to say,
we are using the same key to perform such different tasks as to switch
buffers, to select different windows, and even to pop up a different
mail to read.
To be honest, there is nothing new in this idea: it is the core idea
of the so-called "modal editing". And there are numerous packages that
implement similar ideas in Emacs already, such as evil, god-mode, or
even viper, just to name a few.
The difference of my implementation with other packages is that I
would like to first push this idea to a more general level, before
specialising to some specific states. In other words, the modes should
reflect more dedicated states of the editor and the current task I am
performing. More precisely, when I am trying to switch buffers, I
shall be in a "buffer mode", that permits me to switch buffers just by
arrow keys, or whatever keys I have chosen for the concepts of "up"
and "down". Moreover, the concepts include not only four directions
but also "previous" and "next", whose functions are to switch to the
previously used and the next-to-be-used buffer respectively.
Simply put, a mode is nothing but a correspondence from concepts to
functions. And the user should decide how to map these concepts to
keys.
Then this document tries to record the modes that I accumulated
through the use of the editor.
======================================================================
Analogy with the languages
======================================================================
If we view pressing keys as the user speaking to the computer, then
these keypresses of a user form a "language", in a formal sense. The
letters are the keys on the keyboard (so each user has a potentially
different set of letters), and the words are valid key sequences, as
per the Emacs parlance. For example, in the built-in language of
Emacs, the word "C-x 4 d" means to open a directory in another window.
There are some characteristics of this kind of languages. The most
obvious characteristics is that the verbs are all in one of two
"moods" (this term comes from Latin grammar if my memory serves me):
imperative and interrogative, since this language serves the only
purpose for the user to give the computer commands, or to query some
states.
Another characteristics is that, there are a myriad of "tenses",
"conjugations" and "declensions". These refer to the fact that a key's
meaning depends upon the contexts. So we can view "C-x 4 d" as a
conjugation of the verb "C-x d", which is to open a directory in the
current window.
However, as one of the reasons that the Sanskrit language is deemed
not easy to learn is that it has numerous declensions, conjugations,
liaisons, and irregularities, the same thing happens with the
key-binding language. If a key-binding language has too many tenses
and irregularities, then it is difficult to remember, to use, and to
"speak". And, from my point of view, the built-in key-binding language
of the editor is too difficult to use, however logical the design of
that language may be.
The aim of this document is thus to solve this problem, for me and for
me only, at the same time laying some foundation upon which others may
build their own languages to solve their own problems, in the future.
======================================================================
The solution in terms of the analogy with the languages
======================================================================
So what does our solution mean in terms of the above analogy with the
languages? I think this is the difference between the agglutinative
languages and analytical languages.
According to Wikipedia, "an agglutinative language is a type of
synthetic languages with morphology that primarily uses
agglutination." And agglutination is "a linguistic process pertaining
to derivational morphology in which complex words are formed by
stringing together morphemes without changing them in spelling or
phonetics."
Basically, this is one of the characteristics of the default Emacs
language: concatenating affixes after affixes, or prefixes.
Again according to Wikipedia, "an analytic language is a language that
primarily conveys relationships between words in sentences by way of
helper words (particles, prepositions, etc.) and word order, as
opposed to using inflections (changing the form of a word to convey
its role in the sentence)."
In our contexts, this means we use helper words (key sequences) to
alter the meanings of keys. In addition, it is also a common oral
practice to use "persistent" contexts. For example, (I don't know
about English, so here I refer to the situation with my mother tongue
Chinese), when telling a story, after one declares this happened in
the past, we can safely use verbs without tenses and expect that the
listener understands this is a past action. Hence the effect I want to
achieve is that we can expect the editor to understand that after we
changed our contexts, the keys have a different meaning now.
======================================================================
Major modes and minor modes
======================================================================
One might wonder why I don't just use Emacs' built-in major modes and
minor modes, as those sound like a generalization of the ideas of
modes already. In this regard, I really think my idea of modes is just
like a minor mode, in that it is not directly relateed to the file or
the buffer being operated on. Rather it concerns the intention of the
user. And in effect we can implement the modes as depicted above using
nothing but major and minor modes.
There is a problem though: the minor modes control the keymaps through
the variable "minor-mode-map-alist". It is a plain association list
that associates minor-mode symbols to keymaps. Wheneven the minor-mode
symbol has a non-nil value, the associated keymaps is in effect.
However, the order of priority for these maps is the same as the order
of appearance in this association list. This means we might sometimes
get unpredictable results when we try to activate certain functions in
our modes. Therefore, to avoid this problem, I decided to avail of a
higher-priority map, namely "emulation-mode-map-alists". And it
functions in the same way as the former.
======================================================================
General concepts
======================================================================
Some concepts are in a sense "universal" to all modes. These are the
concepts that don't concern with the specific functionalities of
modes, but rather with the abstract notion of modes.
quit - Quit a mode, and nothing else.
quit & bury - Quit a mode and bury the current buffer.
quit & quit - Quit a mode and quit the selected window.
quit & kill - Quit a mode and kill the current buffer.
======================================================================
Buffer mode
======================================================================
The first mode that I desire is a mode that operates on the buffers.
As Protesilaos Stavrou rightly observed, the true power of Emacs lies
in its handling of the buffers, since this frees the limited screen
estate and leverages the power of the computer to manage the editing
resources. So naturally there are a lot of operations related to
buffers that are quite useful to us. Below is a list of the
correspondence between concepts and functions that I can think of.
up - The previous buffer in the list of buffers.
down - The next buffer in the list of buffers.
previous - The previously used buffer.
next - The next-to-be-used buffer.
In practice this means the buffers that the user left by
going to the previous buffer.
jump/show - Either use the completion framework to select a buffer
or display an interactive list of buffers, i.e. ibuffer.
This can first call ibuffer, and the second call uses
the completion framework.
last - Whether this deserves an independent concept is still
debatable. This just switches to the last used buffer. If
called repeatedly, it switches between two buffers.
save - Save a buffer.
I am used to frequently save buffers, so it is important
to access this conveniently.
kill - Kill and save a buffer.
delete - Simply kill a buffer.
rename - Rename a buffer.
search - Search through a buffer.
======================================================================
Window mode
======================================================================
To be honest I don't believe I really need to manage windows. Rather I
would like Emacs to automatically handle the windows the way I want.
But since it is too difficult to guess my mind, this mode is still
relevant.
up - Go up a window.
down - Go down a window.
left - Go left a window.
right - Go right a window.
jump/show - Use the completion framework to choose a window to go to.
It might make sense to have a buffer list all windows that
I can jump to, just like an "iwindow".
save - Save a window configuration.
load - Load a window configuration.
delete - Kill a window.
======================================================================
Help mode
======================================================================
The idea is to make the help system behave more conveniently. For
example, currently if the user opens a file thruogh the help system,
then the user is put in the major mode corresponding to that file. I
think it might be more convenient if the user is still in the help
mode. When and only when the user chooses to exit the help mode,
should the user be put in the major mode corresponding to that file.
up - Scroll "down".
down - Scroll "up".
previous - Go to the previous help buffer.
next - Go to the next help buffer.
search - Searching through the help buffer is also important.
======================================================================
Selection mode
======================================================================
I haven't decided yet whether this should be a separate mode or just a
concept for other different modes that turn the current "object" into
a selection.
======================================================================
View mode, or the screen mode
======================================================================
This mode of Emacs really surprised me when I first learned about its
existence. It hinted at endless possibilities, in some sense. But it
does not fully meet my expectations.
I view document frequently. I believe that writing is a reflection of
thinking, and while I am thinking, I like to scroll through the
document to answer such questions as what have I written, does the
current writing follow the outline or the sketch in my mind, do the
writings hint at some directions that I didn't notice before I wrote
them down, and the rest. Consequently, it is am important part of my
editing activity to view the documents.
Since my screen is limited, the occassion occurs frequently that I
need to scroll the document to view some parts of it. In addition, I
like to highlight things, so it is equally important to easily select
or highlight arbitrary things on the screen. Thus my primary focus in
viewing documents are scrolling, positioning the cursor, highlighting,
and (re)centering the buffer.
To be more precise, I would like the directional concepts to be
directly (no pun intended) related to the scrolling of the documents;
this covers eight directional concepts (up, down, left, right, and
their "maximal" versions).
In addition to the above, I would also like to have special "concepts"
to go to the top, the middle, and the bottom of the screen.
Lastly, about the jump/show concept I shall talk a little. I used to
love the package "avy", which permits the user to jump to anywhere on
the screen by matching either a line, a character, or any character
sequence the user inputs. Upon further reflection, however, I do not
find anything this package offers that a plain old "interactive
search" does not offer.
By the way, instead of the name "view mode" it would probably be
better to call it "screen mode", since it concerns the screens. And to
view is a verb, not a state of the editor; after all, we are always
viewing something on the editor, unless it crashes.
|