Emacs
MarkdownI started using Emacs for the mu4e mail client after using and liking the mu mail indexer on the command line (read more about my mail client setup). Similarly, I was using the ledger-cli accounting system, and found the Emacs minor mode to be great. Then I got curious about Emacs Org Mode and started using it for note taking and task management. Now I’m using Emacs as my primary development environment.
I realised that configuring Emacs to my liking would be like second job, which I didn’t have the bandwidth for, so I started using the ‘distribution’ Doom Emacs. It enables Vim bindings everywhere with Evil Mode which, coming from Vim, made it much easier to get up to speed.
The Emacs philosophy is different from Vim’s, it
aims to be the ‘everything program’. It is it’s own operating system: a
big Lisp machine distinct from the Unix shell I’m used to working in.
It’s much more configurable and extensible than Vim – plugins are
written in the same language that most of the Editor is itself, Emacs
Lisp. A small example of how this results in a seamless experience; in
Emacs I have vertico
providing fuzzy finding capabilities, which extends to built-in UI
elements. For example, M-x will fuzzy
match on commands I can execute. In contrast, in Neovim I use telescope to
provide fuzzy searching which I have to invoke separately – I still have
the normal command prompt with : but I can
fuzzy search commands with <leader>fq with this binding:
vim.keymap.set('n', '<leader>fq', require('telescope.builtin').commands)Neovim might be adding similar extensibility for fuzzy searching. It seems like with things like Evil mode and Neovim’s Lua-focused extensibility the two editors are moving towards each other somewhat.
Emacs can be slow and a bit unwieldy however, so I still use Vim sometimes, like for small edits on remote servers.
You can find my Doom Emacs configuration here.
Below are my working notes on learning and using Emacs. There are some open questions that I haven’t found time to look in to – please get in touch if you have an answer!
§general
C-b C-x list buffers
C-b x open buffer
help:
variable C-h v
function C-h f
key C-h k
M-xcommandC-x C-e/ (grin evil) evaluate expression selectedM-:/ (SPC ;in doom) evaluate expression from minibufferkmacro-edit-macroto edit recorded macro-
looks like evil-numbers provides this functionality but is bound to
g=in Doom Emacs view-lossageview recent history of commands invoked with key bindingsO try xref (doom emacs lookup module)
O search and replace in project
O why is ]e not working?
SPC w C-o/delete-other-windowsto close all windows but the focused
§email / mu4e
mmove maila vopen in firefoxCcomposeR/W/F/C/Ereply/reply-to-all/forward/compose/edit(draft)Prtoggle property- Ptr mu4e-include-related
eextract attachments- ~/.mailcap for external openers
Afor more options
- blue/yellow in header view mu4e-unread-face mu4e-flagged-face
- exit composer
ZZ / C-c C-csend messageZD / C-c C-dsave to drafts and leaveZF attachZQ / C-c C-kkill the message buffer (the message remains in the draft folder)ZA / C-c C-aattach a file (pro-tip: drag & drop works as well in graphical context)C-c C-;switch the context
- disable include relevant by default
- how to add a filter to a maildir
- mu4e-search-narrow
/with evil-collection, and\to undo - similarly mark pattern
- mu4e-search-narrow
- how to open URL with keyboard shortcut?
shr-browse-urlRETbrowse-url-at-pointM-RETmu4e--view-browse-url-from-bindinggx
cwwide reply in message view with evil modeM-qformat paragraph.view headers- how to switch message from plaintext to html with a keyboard shortcut?
- custom account completition?
- open attachment
mu4e-view-mime-part-action- doom’s
A/+mu4e-view-select-mime-part-actionis currently broken
O how to have
m/mu4e-headers-mark-for-movepick up the contextit seems like
match-funcworks for replies but not this
§doom macs
SPC h b twhich key show all bindingsC-hin which key to search bindingsSPC h vhelp variablesSPC h ohelp symbolKhelpgdgo to definition- map!
SPC f ssave fileSPC TABworkspacesSPC bbuffersSPC ssearchgrevaluate lispSPC g gmagitSPC o mmu4eSPC o tterminalSPC q s/SPC q lsave / load sessionSPC p ffile in project- in minibuffer
C-ssearches history SPC p popens project in new workspace- jumplist
C-i/C-onot working in terminal?- terminal can’t distinguish between Tab and C-i
- https://github.com/doomemacs/doomemacs/issues/8101
- Why does the help menu not stay opening when switching windows?
- Doom’s popup window implementation
C-~make popup real window
- How to get into normal mode in emacs minibuffers?
(setq evil-collection-setup-minibuffer t)
- how to edit properties in org mode?
SPC m o
- how to see org mode agenda?
SPC o a
M-`does menu barSPC h wwhere-is commandSevil-surround- spell checker
gssevil-avy-goto-char-2 leap.nvim equivalent
§org-mode
-
-to look at past day, e.g.-sun
bindings
org mode key bindings
M-retadd entryM-S-rettodo entryTAB/S-TAB- NB
S-TABis bound toorg-shifttabinstead oforg-global-cycle
- NB
M-LEFT/M-RIGHT/M-UP/M-DOWN/M-S-LEFT/M-S-RIGHTorg-metaRETopen link
-
<</>>org-metavae/vaR[ h/] hgj/gk/gh/glS-UP/S-DOWNprev / next item in list
-
zc/zo/zOSPC m h(SPC m *) /SPC m itoggle heading / itemSPC m d t/ org-time-stampSPC m s Ssubtree sortSPC m s ssubtree sparseSPC m xtoggle checkboxSPC u SPC m xadd checkboxSPC m +/S-LEFT/S-RIGHTcycle checkboxesSPC n lstore link e.g. in email / mu4eSPC m l linsert linkC-c RETinsert headingC-M-RETinsert subheading https://github.com/doomemacs/doomemacs/issues/3306M-S-RETinsert todo headingSPC m t/S-LEFT/S-RIGHTTODOSPC m q/C-c C-c(on heading) set tagC-c \org-match-sparse-tree on tagsSPC m oset propertyC-c C-con property property actionC-c ./SPC m d t/SPC m d Torg timestampSPC u SPC m d tfor date time
SPC m cclock commandsTABsee drawerSPC m s rrefileSPC m r Rrefile reverseSPC XcaptureSPC m AarchiveSPC m s aarchive tagSPC m aattachmentSPC u 3 TABshow 3 level deep headings
scripting
#+begin_src python a = [ 1, 2, 3 ] return a #+end_src #+RESULTS: | 1 | 2 | 3 |evaluate with
RETadd with
org-insert-structure-template
agenda
- how to exclude LOOP todo items from the todo list?
org-agenda-filter-by-category/sc/\on line - how to filter by tag?
org-agenda-filter-by-tag/st/< gDselect time range
- how to exclude LOOP todo items from the todo list?
how to do bibtex citations?
- biblio doom module
org-cite-insertcitar-open-notes
O org mode: enter on a pdf opens it in evince instead of emacs
§latex
got a project compiling using doom emacs latex module which pulls in AUCTeX
synctex
SPC m v and Ctrl+click in evince
X figure out how to use internal pdf viewer (seems like +latex/viewers isn’t respected)
X figure out how to get SPC m v working from another tex file (seems like the master file detection is off)
TeX-master-fileX auto reload pdf on changes
auto-revert-modeO pdf viewer search highlight https://github.com/vedang/pdf-tools/issues/162
X resize pdf frame to page width
X jump to section in source with
SPC s i/imenuX how to insert a block?
latex-insert-block =LaTeX-mark-environment/C-c .X how to fold section headings?
outline-minor-modeandzcX go to label
reftex-goto-label
§android
Using doom-emacs in Android Emacs
§ledger-mode
[[/]]next / prev transactionSPC m axactTABcompletionSPC m tclearSPC m RreconciliationTABmark transaction cleared (in reconciliation)
§magit
SPC g Cgit clone
See log of current buffer file
SPC g L
See diff inline
L -p s
§lsp-mode
X figure out how to not watch
.gitignorefiles
§how to act on all search matches
- embark-collect (SPC a S)
§LSP from devshells
- get lsp environment from nix devshell
- using direnv
O how to configure this to run?
- currently it runs for all files (e.g. markup files in my website directory, when I only need the Haskell LSP server for editing the static site generator)
- it also triggers if I add website org file to the agenda list
§shells
shelldrops you into a very minimal shell- basically just I/O in a buffer, ANSI escape codes and such aren’t supported
shell-command- run a shell command in your default shell
- doesn’t support sudo as can’t read from stdin
eshella ‘shell-like’ command interpreter implemented in emacs lisp- e.g. an alternative to your system shell
eshell-command- runs a command in an
eshell, and supports sudo with a prompt for the password
- runs a command in an
async-shell-command/M-&- like shell-command but doesn’t lock emacs while the command is running and opens a buffer to display the output
- also supports sudo with a prompt for the password
project-<all of these commands- runs these shells in the current project root directory, as opposed to the current file’s directory
term/vterm- runs a terminal emulator in emacs
what do I use?
- I’ll default to
SPC p &which runsprojectile-run-async-shell-command-in-root, which as far as I can tell is basically the same asproject-async-shell-command, just because it’s the default in Doom Emacs. - Though it seems
projectileis on the way out in favour of the in-builtproject.
- I’ll default to
O how do I stop the async shell output splitting to the side and open a new window instead?
O eshell-command supports completion, but the other shell commands don’t
emacs-bash-completion might be something to look at
§find a CalDAV calendaring application
-
- recurrence support is broken
- basically, we need a good CLI caldav client
- the mu to mu4e
- but I don’t want to do it
~ Khalel
- just imports a selection into an org file, and the org format is less expressive in some ways and more expressive in others
- we really need to deal with the iCalendar format directly
-
- okay, I’ve done it