Emacs’s Builtin Elisp Cheat Sheet
masteringemacs.org
masteringemacs.org
The defaults are absolutely awful. The editor is pretty unusable without at least a hundred lines of ELisp: basic stuff like CUA, setting up fonts, disabling useless UI clutter, delete-selection-mode, rebinding a couple keys, setting up packages, explaining where to find coreutils on BSD systems, etc. And then you get to packages.
If you want to do anything remotely useful, you're gonna have to start installing random stuff from GNU ELPA, MELPA, etc. There's no package pinning or SemVer so you get what you get, packages sometimes break in mysterious ways. So you write more code to work around various broken stuff in packages.
I've gone through several iterations of throwing away my entire init.el and starting from scratch with just the bare minimum needed to get work done. At the current iteration, ELisp is still ~33% of all source code volume in my dotfiles repo[0]. I haven't pushed my latest effort to unbreak "jump to definition" (because apparently dumb-jump is deprecated??? and I need to use xref??? but it doesn't work???) so that'll likely go up.
I never wanted to write enough ELisp to justify calling it a program, but Emacs made me.
But then there is magit[1], which is so damn good, it makes every other VCS interface look like a sad joke. Which is problematic, because configuring Emacs itself is a bit of a sad joke. I want to just write code, not write code to make just writing code less of a pain. :(
[0]: https://github.com/rollcat/dotfiles
[1]: https://magit.vc
Previous discussion on HN here : https://news.ycombinator.com/item?id=31833101
But Emacs is nothing but clay, an assortment of Lego pieces, building blocks, programmers' equivalent of IKEA furniture, DYI toolkit, etc.
It's not an editor, it's material for you to build your own editor.
> I never wanted to write enough ELisp
That's the mistake Emacs newcomers often make. If you truly want to master Emacs, there's no way around it - you have to accept Emacs Lisp. With all its flaws and incredible power.
If you hate Lisp because it's not like languages you learned and used before; it doesn't look like Python, Javascript or Ruby, then maybe you're missing something.
One needs to set aside their prejudice about parenthesis, learn structural editing commands, understand REPL-driven workflow, and then, once they are over that initial barrier, they may realize that all those [more popular] languages borrowed heavily from Lisp, and Lisp is an extremely nice programming language.
True craftsmen very often make their own tools. I am of course biased here, but in all honesty, every single professional I know, whom I can count as an Emacs power-user or even a master; Every single one of them is truly an incredible hacker.
ps.: "you" used here in the general sense, not targeted to the OC personally.
I've only been using Emacs for 20ish years. (That's more than half of my life.)
At some point I even used Emacs to read my email and RSS, but the stability problems with a single process handling both that and coding led me to try crazy workarounds, like running two instances... Which created problems of its own... Which was all eventually solved by moving back to dedicated apps for mail and news.
> If you hate Lisp because it's not like languages you learned and used before; it doesn't look like Python, Javascript or Ruby, then maybe you're missing something.
I really like Scheme, have had a good time with Common Lisp, wrote my own Lisp dialects for fun; in fact ELisp as a language is not that bad, once you get used to dynamic scoping etc.
My problem is the fact that you have to write actual software to work around deficiencies in your tools. If Emacs was magically rewritten overnight, bug-for-bug, in Scheme, Python, Rust, whatever else, I don't think it would change anything. The problem isn't the language, the problem is the editor/framework/runtime isn't aging well; GuileEmacs or REmacs were/are trying to address the internals, but the problems are running deep across every layer, including incidents like RMS trying to veto emoji support.
All I ask is that an editor do ~80% of the stuff that ~80% of its users want it to do, out of the box, without hassle. VSCode gets it, Jetbrains gets it, heck Notepad gets it. You don't need to write extra code just to convince e.g. GEdit to not shit itself when /bin/ls comes from a BSD userland.
Again, I'd switch to VSCode right now, if it had anything even remotely as good as magit.
Could be explained as selection bias, instead of a causal factor.
I find them awful too but many people are fine with these defaults.
> There's no package pinning or SemVer so you get what you get, packages sometimes break in mysterious ways. So you write more code to work around various broken stuff in packages.
There's however a way around it which you may like, seen your complaint... What I do, and it's not unheard of but definitely not the most common when it comes to Emacs, is that I load specific versions of packages. And I commit my entire Emacs setup in Git.
So when I upgrade packages (or install new ones) if anything goes wrong I can just checkout/restore a known fully working state.
There are trade offs when versioning your entire "emacs.d" directory but honestly I don't see many downsides. And I share that emacs.d between several user accounts / machines and any change I made are one "git pull" away.
When I start Emacs I don't check for packages / refresh package contents or anything like that: I only do that when I actually plan to upgrade packages (which I do maybe once every six months or so).
> I want to just write code, not write code to make just writing code less of a pain.
I'd say that's kinda a big selling point of Emacs though: you can write elisp code to make anything you do (not just writing code) less of a pain.
I agree in principle, but in practice, I find myself writing a lot of ELisp just to work around Emacs' shortcomings. E.g. on macOS, to support dark/light theme switching integrated with the rest of the system, I need an external program[0], a shell script to tell that program to call emacsclient, a LaunchAgent to keep it running, an unholy build of Emacs with all of the GNU-unapproved Cocoa integrations that some kind soul is maintaining, and only THEN a piece of ELisp (which is also calling out to AppleScript) to actually change the theme[1]. And as I wrote this, I realised half of this glue didn't even make it into version control.
[0]: https://github.com/cormacrelf/dark-notify
[1]: https://github.com/rollcat/dotfiles/blob/7f6a6d7/.emacs.d/in...
I've been using Emacs for about 20 years, and with every passing year I just wish there was *less* ELisp for me to think about. The actual useful customisations (like adding the +x bit on shell scripts) are few and far between, most of it is just glue and fixes.
Why isn't your Emacs session running dark-notify itself, reading its output, and switching accordingly? That seems to remove the need for shell script running emacsclient, the launch agent, and the OSA integration. (But also, I thought ns-do-applescript was stock Emacs? At least I had some ELisp using it and I only ever used emacsformacosox.)
Thanks for the hint. Maybe I would try that first, if it popped into my head when I was originally writing it; but at this point, it works, and I want less stuff in init.el.
Also I will likely reuse the dark-notify script to change the theme in Terminal.app as well, and Terminal.app doesn't have an ELisp runtime. (Also very weird that Apple's own software doesn't properly support this.)
> But also, I thought ns-do-applescript was stock Emacs?
I don't know. I've switched to macOS only a couple years ago, and the Emacs build I've initially used didn't have it.
I understand the gripes though. Emacs really shines when you have a workflow that is poorly supported by mainstream tooling and you want to write your own. I don't know of any other editor that allows you to add keyboard shortcuts/commands/functionality that easily.
My dream config file is probably 10-20 lines of my actual preferences, not 40-60k lines on top of which I have to add another several hundred.
E.g., re the GP's complaint about lack of CUA: CUA is an IBM effort to standardize a dozen shortcuts that are considered more or less universally useful.
But Emacs predates CUA by a couple of decades, and supports easy access to an insanely wider (two, three orders of magnitude) space of functionality.
If you want CUA, Notepad is 100% conformant.
Disclaimer: Yes I would adore a clean pure new Emacs, but given the dearth of Stallmans, the new Emacs would take even longer to not have CUA by default.
Panta rhei - you can either pick a tool that comes with you, or deal with switching at each stop on the river.
Only a couple of years if you're taking GNU Emacs specifically. About one decade if you're talking about editor macros for TECO.
I'm one of those weirdos that disable transient-mark-mode because I don't feel like it does the right thing for all situations where you use mark. Sometimes I want to use mark like a cheap bookmark and C-x C-x between mark and point, sometimes I use the rectangle commands and for those transient-mark-mode only makes things worse.
(I know the CUA mode has some fancy rectangle features, but that's not for me)
https://www.masteringemacs.org/article/fixing-mark-commands-...
Also, the CUA rectangle stuff's actually mainlined and can be used without CUA (`C-x SPC')
I enjoyed your article but I think the solution for me is to leave TMM disabled, though it makes me curious about what else I've missed in the last decade(s). You just made a sale of your book.
If vim bindings aren't your bag that's not a problem either.
Worth a look.
(Source : Some old geezer who's been hand coding an emacs config since the 90s, Doom has allowed me to throw a lot of it away.)
I don't care for the defaults either, but I also don't care for CUA, so if you had your way the defaults would be just as objectionable to me as they are now. Since you can't make everybody happy, I think the best way forward is to continue the status quo, so at least you won't be forcing configuration on users who were previously fine with the default.
In other applications I mostly avoid the ctrl-v/ctrl-c and use X's highlighting and middleclicking system instead. When those aren't available, I actually prefer context menu copy/paste entries to the CUA shortcuts.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Sh...
Please, try to get into the habit of not only sharing the keystrokes but also commands they bind to. With all different Emacs "distros" popping up, it's hard to track the bindings. "Is it in vanilla, Doom or Spacemacs?..."
My hope is for a convention to emerge where the proper etiquette of Emacs pedagogy would be always mentioning the command.
Also, I think you meant to say C-h r s <search_term>, where <s> binds to Info-search
I can do basic stuff alright, being able to jump into source in particular is very helpful to at least find snippets of code doing what I want, but I don't have a good sense of how to work effectively in it.
(For example, when trying to test things out I haven't really found a way much better than typing into scratch, selecting code and running it while staring at messages....)
I would gladly pay money to watch somebody just write and debug emacs lisp code for half an hour cuz I feel wanting for usability when trying to work with this.
https://www.masteringemacs.org/article/evaluating-elisp-emac...
Are you talking about when you're noodling, trying to figure how things work, or actually trying to build something?
For playing around, I found that scratch works ok, but I found a better workflow.
I end up using a daily note in org-roam, with #begin_src elisp... I then tag the heading with :REFILE:ELISP: so I can always find it later. Basically evaluate everything inline within that org-babel block.
When I'm building something, or driving towards a specific goal, I use buttercup [0] to write actual unit tests. If I squint, it kinda looks like TDD.
Finally, for debugging of running elisp, take a look at edebug [1]. It's a pretty standard looking debugger (if you used something like gdb). By default emacs uses debug which is not as friendly.
[0]: https://github.com/jorgenschaefer/emacs-buttercup
[1]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Ed...
That's what I've been using it for. Once you find a function you're interested in, call `eval-defun` in it. Next time it's executed you should get a prompt with a stack trace and ability to step through the code (with `n`) or evaluate an expression in context (`e`).
> if I may ask a noob question, is there an easy way to keep a persistent eye on a closure or arbitrary set of a variables
I discovered edebug last week when I finally had to; so we're in the same boat. My guess is "yes" :)
To clarify for anyone reading, `eval-defun` needs to be called with a prefix argument to instrument the first function, and `edebug-instrument-callee` (`I`) can be used to instrument the function following point in edebug's source-code-buffer, which I think is what you reffered to as a backtrace; I printed the edebug manual and brought it to work with me, in which I see that you can get a real back trace by calling `edebug-pop-to-backtrace` (`d`).
By `disassembled `, I meant bytecode, which after thinking about for a bit, maybe it could be done with lapcode, which is like bytecode made of s-expressions, but what I'd really want is a way to see the stack. Anyway, that seems like a whole 'nother beast, outside the scope of edebug.
Edit: I was looking for an evaluation list, see `edebug-visit-eval-list` (`E`) and `edebug-update-eval-list` (`C-c C-u`) c:
Outside of edebug I've used `trace-function` and `watch-variable` in the past for this.
I’ve done this for years and found it very helpful. Also learn how to use the scratch buffer — e.g. you can write a function and try it out and see it’s output easily with [C-j], that’s bound to the eval-print-last-sexpr function.
The built in help is amazing, there are at least 50 commands that provide some form of help or documentation, I use 3 very heavily: [C-h f] that’s describe-function, [C-h v] describe-variable, and [C-h k] describe-key.
The only complaint I have about Emacs is its look and feel and a lack of a usable Sidebar. If they could "steal" that from Sublime Text it would be perfect.
The primary difficulty is in being able to find exactly what you're looking for. Precise terminology and specific terms of art (i.e. linting, directory traversal, syntax hiliting) will help here.
From sidebar, what I look is an exact equivalent of Sublime Text's sidebar.
- It opens in the same frame - I can add/pin a folder tree there, it should be operable by mouse (open/close subtree, click to open a file in buffer or switch to it) - Have a list of open files / buffers - clicking on it should switch to buffer
Currently looking at treemacs and neotree that were suggested by me. Previously I was giving up trying to configure them, now I may be more persistent.
https://carnet.danielhan.dev/linux-unix/emacs/speedbar-in-on...