diff options
author | mms <michal@sapka.me> | 2024-07-28 20:57:11 +0200 |
---|---|---|
committer | mms <michal@sapka.me> | 2024-07-28 20:57:11 +0200 |
commit | f864511fe699fec99da4c45b37f17600f3516e71 (patch) | |
tree | 285db42dd824d9b3093c24d3eebb4219ae11e478 /content-org/cool-emacs.org | |
parent | f7f9b4b4670881fe3e51f1b1e55603df5ce21133 (diff) |
feat: Unify emacs with cool emacs
Diffstat (limited to 'content-org/cool-emacs.org')
-rw-r--r-- | content-org/cool-emacs.org | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/content-org/cool-emacs.org b/content-org/cool-emacs.org index 57e6578..0df2357 100644 --- a/content-org/cool-emacs.org +++ b/content-org/cool-emacs.org @@ -723,6 +723,177 @@ Be sure to check compatibility! :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :primary_menu cool-emacs-appendix :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 +:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :aliases '(/emacs/whys-of-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/. + + + + *** DONE Emacs as a Shell CLOSED: [2023-04-13 Wed 23:00] :PROPERTIES: @@ -836,3 +1007,386 @@ This method could easily be expanded to run dedicated =emacs servers= and connec I could have used "tonic" there to run the =erc= and pla play with the wordplay, but I decided against it. Dammit Jim, I'm an engineer, not a musician! Also, diatonic modes don't fit the "larger than major" mode. + + +*** DONE Input Completiton +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_CUSTOM_FRONT_MATTER+: :aliases '(/2023/input-completition-in-emacs/ /emacs/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 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_CUSTOM_FRONT_MATTER+: :aliases '(/emacs/literate-programing-in-emacs/) +: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 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_CUSTOM_FRONT_MATTER+: :aliases '(/emacs/org-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]] + |