What are your favorite Emacs packages?
93 points by jussi
93 points by jussi
Reading about Magit and people using Emacs as a web browser made me wonder: what are your essential packages for it?
Thank you
In no particular order, here are some that might not be "the obvious ones":
python-pytest and python-coverage author here. those two packages combined make a fantastic TDD loop right under your fingers indeed.
thanks for the shoutout! š
evil, of course. Emacs is a nice operating system, but it needs a good text editor. evil addresses that very competently.
How would it be an OS?
It's a joke that goes back to the 1980s. If it had been written after "desktop environments" were a thing, it'd probably have been "Emacs is a nice desktop environment, but...".
This is a good example of why people tend to think along these lines.
Built-in favorites:
External package highlights:
The full list is in my dotfiles repo: https://git.sr.ht/~technomancy/dotfiles/tree/main/item/.emacs.d/lib
meow-mode, i think its pretty much the best modal experience in emacs(and overall except for maybe kakoune, grab sucks a little)
What's your meow setup look like? I'm an evil user and I though meow sounds like a great idea bug building my own model setup from scratch didn't quite sound worth the time investment.
i use a split keyboard with a hands-down promethium layout, so my basic keybinds are pretty unorthodox, but i have pretty much no special keybinds set up and i never really felt the need to as the keypad gets me by
for more regular qwerty keyboard users theres https://github.com/meow-edit/meow/blob/master/KEYBINDING_QWERTY.org (and dvorak and colemak actually)
building my own model setup from scratch didn't quite sound worth the time investment.
You don't have to do that with meow if you're somewhat comfortable translating regular Emac keybindings to the modal mapping of meow, e.g. C-c <rest of mapping> would be <leader-key> <rest of mapping>.
It integrates almost seamlessly with existing packages, so it's the initial mapping (I basically copy pasted the default keybindings for qwerty users) and then off one goes.
I love the idea of meow-mode, but I've never really found bindings that make sense with Colemak. Also, I'm using home row mods, so the need for modal editing is greatly decreased.
for evil, there's emacs-evil-colemak-basics. you may enjoy the design rationale in the readme.
(i am the author and a decade long user of this layout)
Not already mentioned:
Iām a relatively unadventurous emacs user. Magit is about the only add-on package I couldnāt live without.
I tried lsp-mode once and it assaulted me with a barrage of incomprehensible popups so I immediately uninstalled it; so far I have found eglot much more usable and peaceful.
One thing I am currently unhappy with is the way eldoc and eglot use the minibuffer. Itās a great place for unobtrusive info tips, but I find it a bit too stealthy. In recent years I have got into the habit of using a full-screen emacs frame divided into 3 or 4 columns. With this layout the minibuffer notifications are usually too far away from where I am looking: I would prefer something directly below my current column, not way off to the far bottom left. Even before I started using eglot, my multi-column layout required a few dozen lines of faff in my .emacs to make popup windows less annoying; I still find it difficult to make them behave the way I want. And the minibuffer is even less configurable than popup windows. I think I will have to revert to my older layout where I had multiple narrow portrait frames, and I relied on my window manager for coordinating the columnar layout instead of emacs.
The weirdest thing in my config is folding-mode, which is a minor mode that does folding in the style of the transputer development environment. I interned at inmos before university where I used the āfā editor, which had very swish folding but apart from that was nothing special. When I started using emacs a couple of years later, I thought, now I have a programmable editor, I can make it do folding as well as all the other fun stuff! And, heh, for 30 years my .emacs has had weird folding-mode comments and I havenāt used folding-mode for anything else. (The fold comments are too annoying for anyone not using folding-mode, so itās no good for collaborative development.) Occasionally I fat-finger something in markdown-mode that causes it to fold up my blog post based on the subheadings, which (a) sends me on a sidequest to remind myself how to unfold it again; (b) makes me think I should disable that fucking key binding once I have finished this blog post; (c) wonder about eventually after all these years learning how to use emacsās builtin folding better; (d) publush the blog post, eat, sleep, forget to deal with the editor faff ā¦
I use the default colour scheme except I make the background black. I recently did another trawl through some of the theme packages to see if I could find something nicer, and failed again. Too many of the dark themes have non-black backgrounds (so they are too bright and have poor contrast) and the themes with black backgrounds are either low-contrast or neon angry fruit salad. Itās funny that I prefer the default colours even though I think I should like something else better.
One thing I am currently unhappy with is the way eldoc and eglot use the minibuffer. Itās a great place for unobtrusive info tips, but I find it a bit too stealthy.
https://github.com/casouri/eldoc-box aims to solve this.
The packages that made me quit neovim were:
Lots of other good packages out there, but those are the ones that pushed me over the edge.
Magit is extremely powerful and I love it; but I was happy with lazygit which is as powerful, just packaged in a different flow.
Magit has an Emacs-integrated philosophy that is quite enjoyable.
for direnv users, emacs-direnv or envrc (same ideas, different approaches) give the same (mostly) seamless experience inside emacs: always the right tools in the $PATH, etc.
My new favorite is tramp-rpc. I use tramp for my work over a high-latency connection. tramp-rpc is so much snappier! It has given Emacs a whole new lease on life.
My other favorite is agent-shell. I love using agents without needing to reach for the terminal or terminal emulators.
Many of those mentioned, plus super-save for auto saving after a duration and/or on focus loss. It's a very underrated default of the JetBrains based editors.
builtin I believe, but compile is such a good little command, and writing tools to make output that compile likes is a good use of time.
I'm probably the only person in the universe who will say they like lsp-mode but I kinda do! I've had to try and debug stuff with it so I "get" how it works... I've had less success with eglot tho I don't really undrestand why.
treemacs is helpful to turn on and off from time to time when you do want the file sidebar. I leave it off by default generally but turn it on to "look around" from time to time.
projectile is very nice for organizing project stuff.
Yup, grep -Hn, possibly fed by find and then compilation mode is such a nice thing for browsing matches.
Or, as you say, writing your own tools/scripts that output "file:line: ..."
All the posts on this thread are great. 2 packages that come to mind that really changed how I interact with stuff moment to moment:
what a goldmine of a post! I've been using it as an ide for 10 years or so but never got into heavy customization beside adding language modes and spacemacs. Posts like this one remind me that I'm definitely not a power user
A few things that improved my experience a little over the last few years:
Related question: what package manager do you use? Or how do you install and keep those packages up to date?
straight + use-package.
Straight gives you reproducibility via lock files. I probably way under utilise the rest of its feature, but the lockfile is essential to my sanity.
use-package is a nice QoL, makes package configuration neatly wrapped up.
These days use-package has the :vc keyword, which takes a :rev argument, so you could pin specific versions of packages, as long as you are getting them from e.g. git, and not a package repository.
I've installed Emacs through nix (and home-manager), so I just use the emacs overlay to install all my packages and keep them synced between my machines.
I'm also using about 0.1% of the functionality on offer there. I keep a nix file that manually lists all the packages to install, instead of any of the builtin tools for pulling the packages from my config file. I should get that set up one day, but I'm unreasonably superstitious.
The is also the secret https://gitlab.com/rycee/nur-expressions/blob/master/hm-modules/emacs-init.nix
There are a lot of good answers in this thread, but here are some I'm getting a lot out of lately:
So I use gptel in a basic way -- just for having quick chats with a clanker. I used to use org-mode and context branching via top-level org headlines, but I have since switched to markdown. It's hard to get the bots to not emit markdown, so gptel doesn't try. What it does instead is it post processes their output and converts to org format on the fly. This works pretty well, but not perfectly, and it's annoying enough when it doesn't work that I switched. I still greatly prefer org to markdown though.
I also use gptel as an elisp API for interfacing with LLMs, via gptel-request. I have a bunch of Latin language learning tasks I do, like sentence grammar/morphology/vocabulary breakdowns, audio transcriptions of YouTube videos and stuff I download from Patreon, and data enrichment for my transcription forced-alignment pipeline.
I use elfeed-tube with yt-dlp to enrich the XML feeds with extra YouTube metadata so I can browse YouTube content in Emacs. It's somewhat broken at the moment, as the API it used to use to gather this info no longer works, and the transition to using yt-dlp is experimental and not quite complete. I've added my own custom advise function to get elfeed-tube-fill-feed to use yt-dlp to backfill all the historical videos for a given channel or playlist, as YouTube lamely only gives you at max 15 videos via RSS.
Popper is great because it lets you easily manage the display and dismissal of pop-up buffers, it's just a quality of life window management thing that I can't live without now.
I recently started using the pi coding agent, and the Emacs package for it seems fine. I can do just about everything I can do from the CLI in Emacs which makes me happy.
I'm writing a ton of elisp code lately, and I really want to be the kind of person that paredit is for, that is to say the kind of person who doesn't lose track of what level of the atom/list/form hierarchy they're on, and isn't constantly deleting and adding parenthesis to sanity check their work. I have the cheatsheet printed out and taped to the bottom of my monitor and am forcing myself to use it for everything. It's been a week, and I'm still reasonably sane.
Thanks everyone for the overwhelming amount of responses and good tips!
One thing I am still interested to know:
Do you use Emacs in terminal or are you using a GUI?
Both. GUI locally, in a terminal remotely. TRAMP has never worked to my satisfaction, so it's easier to use (even vanilla!) emacs remotely in a terminal.
Not really packages, but these are the most ancient bits of my config, gleaned from the emacs wiki a decade ago:
(defun djr/kill-this-buffer ()
"Kill the current buffer."
(interactive)
(kill-buffer (current-buffer)))
(global-set-key (kbd "C-x k") 'djr/kill-this-buffer)
(defadvice pop-to-mark-command (around ensure-new-position activate)
"When popping the mark, continue popping until the cursor actually does move.
Also, if the last command was a copy - skip past all the expand-region cruft."
(let ((p (point)))
(when (eq last-command 'save-region-or-current-line)
ad-do-it
ad-do-it
ad-do-it)
(dotimes (i 10)
(when (= p (point)) ad-do-it))))
;; http://iqbalansari.github.io/blog/2014/12/07/automatically-create-parent-directories-on-visiting-a-new-file-in-emacs/
(defun my-create-non-existent-directory ()
"Offer to create parent directories if they do not exist."
(let ((parent-directory (file-name-directory buffer-file-name)))
(when (and (not (file-exists-p parent-directory))
(y-or-n-p (format "Directory `%s' does not exist! Create it? " parent-directory)))
(make-directory parent-directory t))))
(add-to-list 'find-file-not-found-functions 'my-create-non-existent-directory)
Unless I'm mistaken your djr/kill-this-buffer is not needed. Emacs' kill-buffer without argument kills the current buffer and is bound to C-x k.
The current manual at least indicates that kill-buffer prompts for a buffer name at the minibuffer, to which you can respond RET to kill the current buffer.
So it saves you one keystroke, but it's ground into my muscle memory now and my desire to kill non-current buffers is rare
I would recommend otpp which is one-tab-per-project. It automatically creates a new tab for a project. I found it's really useful and can be a great alternative for any session persistent package.
Maybe a bit late to the party but here are my packages I use which weren't mentioned yet:
helm-swoop, it's a grep with on-the-fly results.
ag.el and M-x wgrep to write on the search results.
This browser extension to write some FF text inputs in Emacs:Ā https://ghosttext.fregante.com/
And Slime for Common Lisp development because having a long-living Lisp process to evaluate stuff to (and a real language) is great. I just made my accounting, wrote stuff like (+ 68 80 127 ā¦) and called slime-eval-print-last-expression to have it print the result.
My current favorite is editing textareas/input boxes in FF or Chrome in Emacs.
It's live editing/sync. I'm editing this post in emacs.
It requires an extension in browser and an emacs package, but it seems to work really well so far. Github for the emacs package.
Install it something like this (emacs 30+):
(use-package atomic-chrome
:vc (:url "https://github.com/KarimAziev/atomic-chrome"
:rev :newest
:list-dir "lisp"
)
)
(atomic-chrome-start-server)
For Firefox use GhostText: https://github.com/GhostText/GhostText
For Chrome "Chrome Emacs" with a black kitty icon: https://chromewebstore.google.com/detail/chrome-emacs/dabdpcafiblbndpoadckibiaojbdnpjg
When done editing, just kill the buffer.
I'm definitely in the camp of "trying to use Emacs for everything". I used to use a long list of packages but slowly I've replaced them by either using built-in ones or just some custom homegrown elisp code. But maybe the packages that I use/appreciate the most are:
I'm definitely more of a vanilla emacs person, so apart from a couple language modes, projectile, and my own minimalist color theme I don't use that many packages.
One package I'd like to highlight though is straight.el, which I migrated onto just a couple weeks ago. In the age of LLM-based vulnerability discovery, and the unnerving situation with hostile takeovers of open-source packages, I figured the least I can do is to pin my emacs package versions and only upgrade explicitly when I absolutely need to.
Built in features:
I'm a happy Emacs Prelude user so I have that as a base. Magit for git usage and reviewing PRs. I'd like a better GitHub review layer on top of it, none of the usual extensions quite hit the spot. Tree-sitter is a great addition when your language mode supports it. Combobulate is really nifty for moving about source code with the same key bindings.
Some of the things I use all the time:
evil, evil-nerd-commenter, evil-quickscope, evil-lion, evil-surround, evil-args, gnus, bbdb, magit, git-gutter+, eglot, flymake, compile, wgrep, wdired, smartparens, org-mru-clock, org-aggregate, org-super-agenda, org-rich-yank, org-upcoming-modeline, org-download, vertico, consult, embark, marginalia, corfu-prescient, vlf, verb, focus, modus-themes, ...and of course a bunch of individual prog-modes and builtins
My preferred terminal is the built-in shell-mode. The shx package adds a bunch of features to shell-mode, but the only one I actually use is #ssh foo, which stops the current shell process and starts a new one on host foo via TRAMP. That way Emacs is aware that I'm now on host foo, so things like find-file-at-point, dired, etc. will be in the right place.
Note that shx uses a : prefix by default (so the above command would be :ssh), but I find that clashes too much with REPLs like nix repl, ghci, etc. so I set it to # instead.
I'm using swiper for its ability to show matches and navigate to them in the minibuffer but I dislike the order of the completions in ivy, so I'm using helm instead. All of this feels way too heavyweight just to be able to do fuzzy search in a buffer... I'd like something more "native" and built-in.
I had always felt that way with helm as well, and Iāve been happier after switching to vertico + orderless & friends. Ymmv ofc.
The find-file-at-point command is much more useful than find-file, since it will default to the filename/path under point. Those are both built-in, but ffap-goto-line makes find-file-at-point jump to a particular line and column number if they appear at the end of the filename/path under point, like foo.txt:123:456.
I found the code for that online years ago, but I wrapped it up in that package when I switched my config to use-package. I haven't published it in any repos, so you'll just have to grab it from git or copy/paste into your own config.
I tried Org, but just didn't like it.
Many good suggestions in the comments, I'll have a look at improving my Emacs setup.
Daily drivers:
Less often used but important:
The ones from emacs bedrock but then using straight.el to manage everything. Avy is cute but I use it less than I wish.
Some packages I use daily, in no particular order: