summaryrefslogtreecommitdiff
path: root/content-org/emacs.org
blob: 3c6fdc7d5e1ac16f345582252712403dbd8d121c (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
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
#+TITLE: Emacs @ mms site
#+AUTHOR: Michał Sapka
#+URL: https://michal.sapka.me
#+STARTUP: show2levels indent logdone

#+HUGO_BASE_DIR: ~/ghq/vcs.sapka.me/michal-sapka-me/
#+HUGO_WEIGHT: auto
#+HUGO_SECTION: emacs


* Guides                                                :@emacs:
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu emacs :parent guides
:END:

** DONE Emacs: Input Completiton in Emacs
CLOSED: [2023-05-26 Wed 23:00]
:PROPERTIES:
:EXPORT_FILE_NAME: input-completition-in-emacs
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :abstract Icomplete, IDO and FIDO
:EXPORT_HUGO_MENU_OVERRIDE:  :name "Input completition (Icomplete, IDO, and FIDO)"
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :aliases '(/2023/input-completition-in-emacs/)
:END:
Emacs consists of a massive set of tools with a long history.
Therefore, whatever the problem is, someone likely has already created a package for it.
In many cases, this package is already baked in Emacs.
This is great for veterans but very confusing to newcomers - like me. 

*** The three modes

Emacs comes with three modes for input completion: Icomplete, IDO, and FIDO.
Input completion works with whatever you select in the Minibuffer section.
For text competition, you must use a different solution, like Company mode[fn:company].

The oldest one of those is /icomplete/[fn:icomplete] mode.
It allows you to select from a list of choices incrementally[fn:hist], so you need to type the beginning, and icomplete will narrow the list of propositions.
For example, when searching for "magit", the user needs to type "m" first as omitting it and starting with "i" will instead narrow to options beginning with "i".
Similarly, "mgt" will not limit to "magit" as we're missing"a".
Newer Emacs versions allowallow us to use "flex" matching with icomplete, but more on this later.
Incomplete work for all lists using a mini buffer, like filenames or imenu. 

Then /IDO/[fn:ido] mode (Interactively Do) came in.
It uses the aforementioned "flex" matching, where you can search for any part of the word.
"Magit" would be found with "agit", "mgt" or just "git".
IDO, however, works only with files and buffers, so `M-x` would still fall back to icomplete.

Starting with Emacs 27, we've got /fido/ mode (Fake Ido).
It combines the best things about icomplete (works anywhere) with flex matching.
In fact, all Fido does under the hood is to enable Icomplete with flex matching.

There are also other solutions for competition, not baked into emacs, with the most popular being Helm[fn:helm] and Ivy[fn:ivy].
Personally, I always try the default option, and only if their limits become annoying do I look at the alternatives.
So, I am now a happy FIDO mode user.

[fn:company] [[https://company-mode.github.io/][Company-mode website]]
[fn:hist] According to a [[https://www.reddit.com/r/emacs/comments/13szol7/comment/jltmaud/?utm_source=reddit&utm_medium=web2x&context=3][Reddit comment]] this behavior is relatively new.
Until recently, Icompelete only showed the narrowed selection in a dedicated buffer, similar to using `Tab-Tab` now.
The actual input was still up to the user to type in. Thanks for the tidbit
[fn:icomplete] [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html][Icomplete documentation]]
[fn:ido] [[https://www.gnu.org/software/emacs/manual/html_mono/ido.html][IDO documentation]]
[fn:helm] [[https://emacs-helm.github.io/helm/][Helm website]]
[fn:ivy] [[https://oremacs.com/swiper/][Ivy website]]

*** Using FIDO

To start FIDO mode run

#+BEGIN_SRC emacs-lisp
fido-mode
#+END_SRC

or, if you find a vertical list to be more readable, use

#+BEGIN_SRC emacs-lisp
fido-veritcal-mode
#+END_SRC

You can also customize variables to have it auto-load in your `init.el`:

#+BEGIN_SRC emacs-lisp
(fido-mode t)
;; or
(fido-vertical-mode t)
#+END_SRC

As I've stated above, FIDO is nothing more than flex-enabled Icomplete, so all keybindings work the same.
For vertical mode:

- Typing a string will narrow the selection
- `C-n` and `C-p` will select the next/prev element on the list
- `Tab` will display a buffer with a list of narrowed elements
- `enter` or `C-j` will select the option

One cool thing you can do with FIDO is file deletion (when selecting files) or closing buffers (when selecting buffers) using `C-k`.

*** Customizing the Minibuffer

We can, of course, customize how Icomplete looks works[^savanah].

- /icompleteatches-format/ (default "%s/%s") - how the number of filtered and total options is presented
- /complete-first-match/ (default (t :weight bold)) - how the first filtered option is presented
- /icomplete-selected-match/ (default (t :inherit highlight)) - the same as above, but for vertical mode
- /icomplete-section/ (default (t :inherit shadow :slant italic)) - how the section title for vertical mode is presented
- /icomplete-compute-delay/ (default .15) - how fast the filtering will start after a keypress when a larger number of options is presented
- /icomplete-delay-completions-threshold/ (default 400) - defines the "large number" for icomplete-compute-delay
- /icomplete-max-delay-chars/ (default 2) - maximum number of initial characters before applying /icomplete-compute-delay/. I have no idea what it means, nor have I the knowledge of Elisp to dig into it.
- /icomplete-in-buffer/ (default nil) - enables usage of Icomplete outside of the Minibuffer. I have not tested it.

We can also use /icomplete-minibuffer-setup-hook/ hook if needed.
[^savanah]: list based on [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/icomplete.el][Icomplete source code]]

*** Using Completions from Elisp

The great thing about FIDO is that it, like Icomplete, uses Minibuffer API[fn:minibuffer], so you can simply:

#+BEGIN_SRC emacs-lisp
(completing-read
 "prompt: "
 '(("option1" 1) ("option" 2))
 nil t "default query")
#+END_SRC

[fn:minibuffer] [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html][Guide on Minibuffer completition]]
** DONE Emacs: Introduction to Literate programming
CLOSED: [2024-01-30 Tue 19:10]
:PROPERTIES:
:EXPORT_FILE_NAME: literate-programing-in-emacs
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: abstract A short introduction into the idea of literate programming
:EXPORT_HUGO_MENU_OVERRIDE:  :identifier "litprog" :name "Literate programming"
:END:

*** Abstract

In this article I give a short, theoretical introduction to the idea of Literate programming

*** Introduction

Literate programming is not a subject that comes out often, except if you are talking with an Emacs enthusiast.
There is a significant chance that most programmers don't even know the term.
Let's fix that with a quote:

#+begin_quote
Literate programming is an approach to programming which emphasises that programs should be written to be read by people as well as compilers.
From a purist standpoint, a program could be considered a publishable-quality document that argues mathematically for its own correctness.
A different approach is that a program could be a document that teaches programming to the reader through its own example.
A more casual approach to literate programming would be that a program should be documented at least well enough that someone could maintain the code properly and make informed changes in a reasonable amount of time without direct help from the author.
At the most casual level, a literate program should at least make its own workings plain to the author of the program so that at least the author can easily maintain the code over its lifetime.

-- Christopher Lee[fn:lee]
#+end_quote

The idea is therefore a conversion of an entity out of which one can extract code or documentation.
A semi-abstract in-between called "web[fn:web]".
The process of creating code is called "tangling", and generation of document is a "weave".


*** An example

Let's say we want to show the reader how to install DWM.
We can create a document in a style:

#+begin_quote
DWM is a window manager that can be changed only via source code modification.
Here, we will fetch and compile it.
First, we need to download the tarball:

#+begin_src shell
wget https://dl.suckless.org/dwm/dwm-6.4.tar.gz
#+end_src

then, simply extract it

#+begin_src shell
tar - xvzf dwm-6.4.tar.gz
#+end_src

And then we compile it

#+begin_src shell
  cd dwm-6.4
  doas make clean install
#+end_src

After the compilation finishes, add executable to your .xinit

#+begin_src shell
  echo "exec dwm" >> ~/.xinit
#+end_src
#+end_quote

So yeah, it's a blog post.
A blog post which one can execute.
The example assumes shell, but the actual language can be anything.
We can /tangle/ C code without any problems.

*** Literate programming

This is *not* the way we do programming.
We smack spaghetti code together, add a random sentence here and there, commit is as "bug fix" and voilà!
In a few months no one knows what's going on.
Success, up to the next JIRA task.

Very often code comments are treated as an harmful or (at best) a necessary evil.
We think that code should be self-documenting.
And this is completely valid.
A developer needs to understand what given code does, just by reading it.
If your function is so convoluted, nested and complicated that it's impossible to comprehend without a descriptive comment.

But this is not the whole story.
A function may be very simple, but there is always /context/ in which it is used.

Literate Programming promotes telling story to the reader.
You are free to do narration giving all extra info in one place.
Since the code coexists with documentation, the reader gets the whole picture.

[fn:lee] [[https://web.archive.org/web/20170603045917/http://vasc.ri.cmu.edu:80/old_help/Programming/Literate/literate.html]["Literate Programming -- Propaganda and Tools", Christopher Lee, 1997]]
[fn:babel] [[https://orgmode.org/worg/org-contrib/babel/intro.html][Org Babel]]
[fn:jupyter] I know that Jupyter is not strictly a literate program, but it's close enough.
[fn:web] this name was choosen, because at the time it was not in use related to computing.
We're dealing with history here!

*** Conclusion

Now, this is not a generic fix for all programs.
We work on massive systems with hundreds of intertwined, moving parts.
It is impossible to create a cohesive narrative when the program jumps all over the place.

Literate programing, however, found a different home.
It is loved by scientists (just look at Jupyter Notebooks[fn:jupyter]) who use it for reproducible resarch.
We, amongts Emacs crowed, use it extensively for literate configuration of our environments.
It could be used for scripts, runbooks, debugging logs and so on.
Wherever one can see a logical A, B and C points, we can explain the interconnections.

You can learn more (including much better example) by reading the [[https://michal.sapka.me/papers/literate_programming_knuth_1984.pdf][original Knuth's paper]].

** DONE Emacs: Executing code in Org files with Babel
CLOSED: [2024-02-07 Wed 21:23]
:PROPERTIES:
:EXPORT_FILE_NAME: org-babel
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: abstract A short introduction into the world if Org Babel
:EXPORT_HUGO_MENU_OVERRIDE:  :parent "litprog" :name "Literate programing in Org with Babel"
:END:
*Abstract*: a very short introduction into the word of Org Babel.

No other package seems to have had such huge impact on Emacs community as the introduction of Org Babel[fn:magit].
It made folks not only love their Org Mode, but /live/ in it.

In short: Babel allows for [[/emacs/literate-programing-in-emacs/][literate programming]] form within an Org document.

[fn:magit] you may argue and say that =magit= had bigger impact.
I disagree.
Magit made using git nicer and easier, but it is still the old, old git.
Babel changed the way we use the edit code, the way we think and how we work.

*** Source code basics

Babel comes baked into any modern version of =Emacs=, so you've already got everything you need.
Open any =org= document, add the code to the document within source code blocks:

#+BEGIN_SRC emacs-lisp
  regular text

  ,#+BEGIN_SRC emacs-lisp
  (+ 1 1)
  ,#+END_SRC

  and more regular text
#+END_SRC

Now, move the pointer to with the blocks, tap =C-c C-c= and the code is evaluated.
The result will be appended just below the source code, in a =RESULT= block.

You now know how to do literate programming in Emacs.
Create an Org document, add your narrative, add your source code and execute.
Simple, isn't it?

By default, =Babel= allows only for execution of =emacs-lisp= mode, but it supports many more.
You can enable all supported via:

  #+begin_src emacs-lisp
    (org-babel-do-load-languages 'org-babel-load-languages
                                 '((shell      . t)
                                   (js         . t)
                                   (emacs-lisp . t)
                                   (clojure    . t)
                                   (python     . t)
                                   (ruby       . t)
                                   (dot        . t)
                                   (css        . t)
                                   (plantuml   . t)))
#+end_src

There are even more provided as dedicated packages.

*** Being faster

Typing =#+BEGIN_SRC= can become tedious pretty quick.
We can use the =org-tempo= package to make it much faster.


#+begin_src emacs-lisp
  (require 'org-tempo)
  (setq org-structure-template-alist
        '(("s" . "src")))
#+end_src

  Now, we can create new block simply by taping =<s= and pressing tab.

  Org tempo supports many more blocks, you can refer to [[https://orgmode.org/manual/Structure-Templates.html][the official manual]].

*** Joining the blocks together

In /strict/ Literate Programming sense, your /web// should not be where you execute code.
Instead, you should extract programmatic parts and run it separately - the process is called /tangling/.

Babel bypasses this limitation with =noweb= mode, in which code blocks can reference each other.
First, you need to name your code blocks:

#+begin_src emacs-lisp
,#+NAME: two
,#+BEGIN_SRC emacs-lisp
(+ 1 1)
,#+END_SRC
#+end_src

Then we can use it the result other code blocks

#+begin_src emacs-lisp
,#+NAME: three
,#+BEGIN_SRC emacs-lisp :noweb yes
(+ <<two>> 1)
,#+END_SRC
#+end_src

Here, the =<<two>>= will be replaced with the result of block named =two=.
This makes the block =three= return the number =3=.

This mode gives quite a lot more option.
You can read about them inside [[https://orgmode.org/manual/Noweb-Reference-Syntax.html][manual]].

*** Running on remote machines

To make it even /cooler/, Babel integrates with =Tramp= mode which allows for execution over ssh!
You can add a tramp-style header argument as =:dir= and the code will be executed over the established connection.

#+begin_src emacs-lisp
,#+BEGIN_SRC shell :dir /user@host:~/
rm -rf /
,#+END_SRC
#+END_SRC

And boom - we've got a bomb.

*** Babel as source for Emacs configuration

The most popular use case of Babel however is Emacs configuration.
You can have as many org files as you want, have the configuration inside =emacs-lisp= code blocks and use that as config.

**** Loading files directly

If your config isn't /very/ complicated, you can force Emacs to parse the files on boot.
To achieve that, add

#+begin_src emacs-lisp
(org-babel-load-file "~/.emacs.d/config.org")
#+END_SRC

To your =init.el=.

What happens is, that Emacs will create a corresponding =config.el= (/tangle/) file and load it as a elisp file.
Just remember not to name your config as =init.org= as there will be naming conflict with =init.el=.

**** Pre-tangling

If you don't want /tangling/ on boot time, but rather want to have it ready you can manually /org-babel-tangle/.
To achieve it, add a =tangle= header argument to all you code blocks:

#+begin_src emacs-lisp
,#+BEGIN_SRC emacs-lisp :tangle ~/.emacs.d/init.el
(+ 1 1)
,#+END_SRC
#+END_SRC

And then, after any changes of the file run =org-babel-tangle= and your =init.el= will be up-to-date.
This is the approach [[https://protesilaos.com/codelog/2023-12-18-emacs-org-advanced-literate-conf/][Prot]] uses, but his config consists of over /17_000/ [sic!] lines of org file, so your mileage may vary.

*** Links

If you are interested in the subject, you can look at much more details sources:

- [[https://orgmode.org/worg/org-contrib/babel/intro.html][Official website]]
- [[https://howardism.org/Technical/Emacs/literate-devops.html][Literate devops]] on Howardism
- [[https://protesilaos.com/codelog/2023-12-18-emacs-org-advanced-literate-conf/][Advanced literate configuration]] on Prot's website.
- [[https://org-babel.readthedocs.io/en/latest/][Cheat sheet]]


* Varia                                                              :@emacs:
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu emacs :parent varia
:END:
  
** DONE My "whys" for Emacs
CLOSED: [2023-12-26 Tue 22:12]
:PROPERTIES:
:EXPORT_FILE_NAME: whys-of-emacs
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :abstract My reasons for using Emacs
:END:
I have used many editors over the years.
I've started with Notepad, then moved to Notepad++, Sublime Text, IntelliJ, and VS Code.
Heck, I even Nova at some point.
But only two really stayed with me for longer - the first being Vim, the second Emacs.
Choosing Vim[fn:nvim] seems like the logical option[fn:popular].
It's an extremely popular editor with a huge community.

But first: I *strongly* believe, that everyone working with computer, owe to themselves to spend some quality time with both, Vim, and Emacs.
Vim is amazing.
Modal editing is second to none when it comes to natural text processing.
They keybindings are close to perfect.
It requires some time to get used to, but let's not overstate that.
You can get semi-fluent in Vim in 2 weeks.

And then there's Emacs.
I've tried it for a year.
I like it, but something felt off[fn:off].
Then, for a few months I have returned to using Neovim.
But here I am.
Using Emacs once again.
Why is that?

[fn:popular] amongst specific crowd at least.
But since you are here, it's quite possible that you are one of us.
[fn:nvim] I don't distinguish between Vim and Neovim here.
[fn:off] mostly keybindings. I am now armed with Evil mode, the best replication of Vim in any editor.

*** License

VSCode is released under non-free license[fn:vsclicense], and therefore the code you can see is not necessary what you run.
In fact we know this, as VSCode spies on users[fn:vsctelemetry], so it's an instant No for me. 

[[https://vscodium.com/][Codium]] exists as /libre/ version of VSCode, so it's an option.
However, it is not the same program as VSCode as incompatibilities exist, and the presence of plugins is limited[fn:codium].
Any advancement of Codium is to the benefit of VSCode, and I hove problems with this.

IntelliJ is completely closed-source, so it's also a no-go for me.

Emacs[fn:gnu] is released on GPL[fn:emacsgpl]
Vim is released under custom /libre/ license[fn:vimlicense].
Neovim is released under Apache license[fn:nvimlicense]
This means that the software is truly free.
I can see the entirety of codebase, not just the Lite version (like with VSCode).
I can redistribute it, I can copy, and share it without any limitations.
I can fork it, I can change it.
I can do almost whatever the hell I want it - as this was the basis of FSF.
This may be not important to you, but it is for me.

I believe /libre/ software is a necessity.
Some people prefer /proprietary/ programs - some even don't see problems with /software as a service/.
But only /libre/ software allows for betterment of our /craft/.
Only by being able to freely modify and share software are we able to make the /craft/ better for future generations[fn:libre].
I am paying for free software without any second thoughts by donating to some foundations.
Yes, I make my living creating /properties/ software, but I try to give back.
I refuse to /choose/ non-free software.
I am forced to use some, but whenever there is a choice, I will choose /free/.

This leaves Vim and Emacs as two the two /important/ and /libre/ editors.
And with this, I have quickly removed almost all competition.
Now, how did I choose between those two?

[fn:gnu] I refer to "GNU Emacs" as "Emacs".
[fn:vsclicense] https://code.visualstudio.com/license
[fn:vsctelemetry] "The software may collect information about you and your use of the software, and send that to Microsoft"[fn:vsclicense]
[fn:codium] https://ruky.me/2022/06/11/im-switching-form-vs-code-to-vs-codium/
[fn:emacsgpl] https://www.gnu.org/philosophy/free-sw.html
[fn:vimlicense] https://github.com/vim/vim/blob/master/LICENSE
[fn:nvimlicense] https://github.com/neovim/neovim/blob/master/LICENSE.txt
[fn:libre] I will need to write a dedicated article about it at some point, as all that would only mud this one.

*** Different visions of computing

Vim and Emacs represent two, vastly different visions of computing.

Vim is a precompiled program with plugin capabilities.
This is the vision of computing that has won.
You get a binary (or, worse, a webpage) which makes your program do its thing.
You can /expand/ it using different plugins and configuration, but the /program/ is an unmovable object[fn:os]

Emacs is different.
We've got a very small /core/ written in C.
It handles basic functionalities, but by itself is close to useless.
But then we've got Lisp.
Almost all user-facing functionalities are written in Emacs specific dialect Lisp.

And Lisp is the keyword here.
All of the codebase is exposed to the user, ready to be not only read (as with Vim) but also modified during runtime.
You can /change/ Emacs at a whim.

VSCode tries the same, as it's a JavaScript-backed browser dressed as an editor.
Emacs therefore can be though as a Lisp-backed virtual machine dressed as an editor.
But the former was already rejected on the basis of being non-free (and I don't to run more Chromes that it's absolutely necessary), so it leaves me with Emacs.

I am not a Lisp programmer, but I started learning it.
For now I like it more than JavaScript.

[fn:os] I know you can modify the source code, but then you are running a fork and not the original program.

*** Community

I am not a people person, but people are what drive me.

And this another aspect which drives me to Emacs.
There are folks who are happy with all-batteries-included distributions, like Doom Emacs.

But there's a huge community of personalization maniacs.
People change every possible aspect of Emacs, because the program allows it.
Lisp is right there, and Emacs seems to be the last standing in the good fight to preserve /Literate Coding/ with /Literate Configuration/ people share.
To name just a few, who are my personal inspiration:
- [[https://se30.xyz/conf.html][Alex Maestas]]
- [[https://sqrtminusone.xyz/configs/readme/][Pavel Korytov]]
- [[https://protesilaos.com/emacs/dotemacs][Protesilaos Stavrou]]
- [[https://gitlab.com/dwt1/dotfiles/-/blob/master/.config/emacs/config.org?ref_type=heads][Derek Taylor]]
- [[https://sachachua.com/dotemacs/index.html][Sacha Chua]]

But at the same time the community is /small/ and I have a thing for smaller communities.
There are Vim users everywhere, but it's not that easy to find an Emacsian[fn:bsd].
But when you do, there are huge chances you've met someone at least interesting.
All Emacs users who I've ever meet in real life became my mentors to some degree.

Also, what is *very* important to mention: despite popular joke, there is very little hate in the Emacs community.
People into Vim tend to tell mean joke about Emacs users[fn:vimjoke] - and part of this joke is that the feeling is mutual.
It couldn't be further from the truth.
We all have great respect for other /libre/ editors and their users.
In fact, a lot of us move between Emacs and Vim on a daily basis.

Maybe this is partly due to age[fn:paah]?
Emacs users tend to be, well, older.
Some have their configs evolving since the 90s!
They've already got a lot to show, so they don't need to be mean spirited?
I have no idea, but what I know is that they are a lovely bunch!

[fn:bsd] this also applies my other love, [[/bsd/][BSD]]
[fn:vimjoke] sadly, this was one of the biggest reasons I stopped following certain hyperactive Vim evangelist.
Let him become nameless.
[fn:paah] there is a very funny movie about this https://www.youtube.com/watch?v=urcL86UpqZc

*** Stability

Lastly, stability.
I use [[/bsd/][BSD]] because it doesn't change for the sake of change.
No SystemD will ruin a perfectly good workflow.

Emacs is the same.
It's badge of honor - very rarely were there any bigger breaking changes.
When I used NeoVim, every few weeks something broke due to unfortunate update.
In Emacs on the other hand?
Not even once has something broke not from my own volition.

Emacs comes with multiple competing solutions for the same problem, as people may rely on one of those.
If a new one comes along, the old ones are not replaced.
This increases the confusion of a new user, but it's very much appreciated.

*** Summary

Emacs is the only empowering, libre and limitless editor I know.
It has an amazing community which values I share, and I want to participate in.
Also, it does not require constant maintenance because someone changed something.

Using Emacs /sparks joy/.




* Local vars
# Local Variables:
# org-num-skip-tags: ("UNNUMBERED")
# End: