Thicket data repository for the EEG
1{
2 "id": "https://ryan.freumh.org/emacs.html",
3 "title": "Emacs",
4 "link": "https://ryan.freumh.org/emacs.html",
5 "updated": "2025-02-18T00:00:00",
6 "published": "2025-02-02T00:00:00",
7 "summary": "<div>\n \n <span>Published 2 Feb 2025.</span>\n \n \n <span>Last update 18 Feb 2025.</span>\n \n </div>\n \n <div> Tags: <a href=\"/technology.html\" title=\"All pages tagged 'technology'.\">technology</a>. </div>\n \n \n\n <p><span>I started using Emacs for the <a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/\">mu4e</a> mail client\nafter using and liking the <a href=\"https://www.djcbsoftware.nl/code/mu/\">mu</a> mail indexer on the\ncommand line (read more about my <a href=\"mail-client.html\">mail client\nsetup</a>). Similarly, I was using the <a href=\"https://ledger-cli.org/\">ledger-cli</a> accounting system, and\nfound the Emacs minor mode to be great. Then I got curious about Emacs\n<a href=\"https://orgmode.org/\">Org Mode</a> and started using it for\nnote taking and task management. Now I’m using Emacs as my primary\ndevelopment environment.</span></p>\n<p><span>I realised that configuring Emacs to my liking\nwould be like second job, which I didn’t have the bandwidth for, so I\nstarted using the ‘distribution’ <a href=\"https://github.com/doomemacs/doomemacs\">Doom Emacs</a>. It enables\nVim bindings everywhere with <a href=\"https://github.com/emacs-evil/evil\">Evil Mode</a> which, coming\nfrom <a href=\"vim.html\">Vim</a>, made it much easier to get up to\nspeed.</span></p>\n<p><span>The Emacs philosophy is different from Vim’s, it\naims to be the ‘everything program’. It is it’s own operating system: a\nbig Lisp machine distinct from the Unix shell I’m used to working in.\nIt’s much more configurable and extensible than Vim – plugins are\nwritten in the same language that most of the Editor is itself, Emacs\nLisp. A small example of how this results in a seamless experience; in\nEmacs I have <a href=\"https://github.com/minad/vertico\">vertico</a>\nproviding fuzzy finding capabilities, which extends to built-in UI\nelements. For example, <code>M-x</code> will fuzzy\nmatch on commands I can execute. In contrast, in Neovim I use <a href=\"https://github.com/nvim-telescope/telescope.nvim\">telescope</a> to\nprovide fuzzy searching which I have to invoke separately – I still have\nthe normal command prompt with <code>:</code> but I can\nfuzzy search commands with <code><leader>fq</code> with this binding:</span></p>\n<div><pre><code><span><a href=\"#cb1-1\"></a><span>vim</span><span>.</span><span>keymap</span><span>.</span>set<span>(</span><span>'n'</span><span>,</span> <span>'<leader>fq'</span><span>,</span> <span>require</span><span>(</span><span>'telescope.builtin'</span><span>).</span><span>commands</span><span>)</span></span></code></pre></div>\n<p><span>Neovim <a href=\"https://github.com/neovim/neovim/issues/16142\">might</a> be adding\nsimilar extensibility for fuzzy searching. It seems like with things\nlike Evil mode and Neovim’s Lua-focused extensibility the two editors\nare moving towards each other somewhat.</span></p>\n<p><span>Emacs can be slow and a bit unwieldy however, so I\nstill use Vim sometimes, like for small edits on remote\nservers.</span></p>\n<p><span>You can find my Doom Emacs configuration <a href=\"https://github.com/RyanGibb/doom\">here</a>.</span></p>\n<p><span>Below are my working notes on learning and using\nEmacs. There are some open questions that I haven’t found time to look\nin to – please get in touch if you have an answer!</span></p>\n\n\n<h2>general</h2>\n<ol>\n<li><p><span>C-b C-x list buffers</span></p></li>\n<li><p><span>C-b x open buffer</span></p></li>\n<li><p><span>help:</span></p>\n<ol>\n<li><p><span>variable C-h v</span></p></li>\n<li><p><span>function C-h f</span></p></li>\n<li><p><span>key C-h k</span></p></li>\n</ol></li>\n<li><p><span><code>M-x</code>\ncommand</span></p></li>\n<li><p><span><code>C-x C-e</code> /\n(<code>gr</code> in evil) evaluate expression\nselected</span></p></li>\n<li><p><span><code>M-:</code> /\n(<code>SPC ;</code> in doom) evaluate expression from\nminibuffer</span></p></li>\n<li><p><span><a href=\"https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Conventions.html\">key\nbinding conventions</a></span></p></li>\n<li><p><span><code>kmacro-edit-macro</code> to edit recorded\nmacro</span></p></li>\n<li><p><span><span>X</span> <a href=\"https://github.com/emacs-evil/evil/issues/1851\">evil-mode <code>v_g_CTRL-A</code></a></span></p>\n<p><span>looks like evil-numbers provides this\nfunctionality but is bound to <code>g=</code> in Doom\nEmacs</span></p></li>\n<li><p><span><code>view-lossage</code> view recent history of commands\ninvoked with key bindings</span></p></li>\n<li><p><span><span>O</span> try\nxref (<a href=\"https://github.com/doomemacs/doomemacs/blob/2bc052425ca45a41532be0648ebd976d1bd2e6c1/modules/tools/lookup/README.org#L12\">doom\nemacs lookup module</a>)</span></p></li>\n<li><p><span><span>O</span>\nsearch and replace in project</span></p>\n<p><span><a href=\"https://github.com/hungyiloo/hungyi.net/blob/archive-2024/content/posts/doom-emacs-search-replace-project.org\">https://github.com/hungyiloo/hungyi.net/blob/archive-2024/content/posts/doom-emacs-search-replace-project.org</a></span></p></li>\n</ol>\n<h2>email / mu4e</h2>\n<ul>\n<li><code>m</code> move mail</li>\n<li><code>a v</code> open in firefox</li>\n<li><code>C</code> compose</li>\n<li><code>R/W/F/C/E</code>\nreply/reply-to-all/forward/compose/edit(draft)</li>\n<li><code>Pr</code> toggle property\n<ul>\n<li>Ptr mu4e-include-related</li>\n</ul></li>\n<li><code>e</code> extract attachments\n<ul>\n<li>~/.mailcap for external openers</li>\n<li><code>A</code> for more options</li>\n</ul></li>\n<li>blue/yellow in header view mu4e-unread-face mu4e-flagged-face</li>\n<li>exit composer\n<ul>\n<li><code>ZZ / C-c C-c</code> send message</li>\n<li><code>ZD / C-c C-d</code> save to drafts and\nleave</li>\n<li><code>ZF attach</code></li>\n<li><code>ZQ / C-c C-k</code> kill the message buffer\n(the message remains in the draft folder)</li>\n<li><code>ZA / C-c C-a</code> attach a file (pro-tip:\ndrag & drop works as well in graphical context)</li>\n<li><code>C-c C-;</code> switch the context</li>\n</ul></li>\n<li>disable include relevant by default\n<ul>\n<li><a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/Other-search-functionality.html#Including-related-messages-1\">https://www.djcbsoftware.nl/code/mu/mu4e/Other-search-functionality.html#Including-related-messages-1</a></li>\n</ul></li>\n<li>how to add a filter to a maildir\n<ul>\n<li>mu4e-search-narrow <code>/</code> with\nevil-collection, and <code>\\</code> to undo</li>\n<li>similarly mark pattern\n<ul>\n<li><a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/Marking-messages.html\">https://www.djcbsoftware.nl/code/mu/mu4e/Marking-messages.html</a></li>\n</ul></li>\n</ul></li>\n<li>how to open URL with keyboard shortcut?\n<ul>\n<li><code>shr-browse-url</code></li>\n<li><code>RET</code></li>\n<li><code>browse-url-at-point</code></li>\n<li><code>M-RET</code> <code>mu4e--view-browse-url-from-binding</code></li>\n<li><a href=\"https://github.com/emacs-evil/evil-collection/blob/6365e7c8ae728f7a26294db261b6778d089a6263/modes/mu4e/evil-collection-mu4e.el#L59\"><code>gx</code></a></li>\n</ul></li>\n<li><code>cw</code> wide reply in message view with\nevil mode</li>\n<li><code>M-q</code> format paragraph</li>\n<li><code>.</code> view headers</li>\n<li>how to switch message from plaintext to html with a keyboard\nshortcut?</li>\n<li>custom account completition?</li>\n<li>open attachment\n<ul>\n<li><code>mu4e-view-mime-part-action</code></li>\n<li>doom’s <code>A</code> / <code>+mu4e-view-select-mime-part-action</code> is <a href=\"https://github.com/doomemacs/doomemacs/issues/7847\">currently\nbroken</a></li>\n</ul></li>\n</ul>\n<ol>\n<li><p><span><span>O</span> how\nto have <code>m</code> / <code>mu4e-headers-mark-for-move</code> pick up the\ncontext</span></p>\n<p><span>it seems like <code>match-func</code> works for replies but not\nthis</span></p></li>\n</ol>\n<h2>doom macs</h2>\n<ul>\n<li><code>SPC h b t</code> which key show all\nbindings</li>\n<li><code>C-h</code> in which key to search\nbindings</li>\n<li><code>SPC h v</code> help variables</li>\n<li><code>SPC h o</code> help symbol</li>\n<li><code>K</code> help</li>\n<li><code>gd</code> go to definition</li>\n<li>map!</li>\n<li><code>SPC f s</code> save file</li>\n<li><code>SPC TAB</code> workspaces</li>\n<li><code>SPC b</code> buffers</li>\n<li><code>SPC s</code> search</li>\n<li><code>gr</code> evaluate lisp</li>\n<li><code>SPC g g</code> <span><em>magit</em></span></li>\n<li><code>SPC o m</code> mu4e</li>\n<li><code>SPC o t</code> terminal</li>\n<li><code>SPC q s</code> / <code>SPC q l</code> save / load session</li>\n<li><code>SPC p f</code> file in project</li>\n<li>in minibuffer <code>C-s</code> searches\nhistory</li>\n<li><code>SPC p p</code> opens project in new\nworkspace</li>\n<li>jumplist <code>C-i</code> / <code>C-o</code> not working in terminal?\n<ul>\n<li>terminal can’t distinguish between Tab and C-i</li>\n<li><a href=\"https://github.com/doomemacs/doomemacs/issues/8101\">https://github.com/doomemacs/doomemacs/issues/8101</a></li>\n</ul></li>\n<li>Why does the help menu not stay opening when switching windows?\n<ul>\n<li>Doom’s popup window implementation</li>\n<li><code>C-~</code> make popup real window</li>\n</ul></li>\n<li>How to get into normal mode in emacs minibuffers?\n<ul>\n<li><code>(setq evil-collection-setup-minibuffer t)</code></li>\n</ul></li>\n<li>how to edit properties in org mode?\n<ul>\n<li><code>SPC m o</code></li>\n</ul></li>\n<li>how to see org mode agenda?\n<ul>\n<li><code>SPC o a</code></li>\n</ul></li>\n<li>how to remove icons from\nmu4e?</li>\n<li><code>M-`</code> does menu bar</li>\n<li><code>SPC h w</code> where-is command</li>\n<li><code>S</code> evil-surround</li>\n<li>spell checker</li>\n</ul>\n<h2>org-mode</h2>\n<p><span><a href=\"https://orgmode.org/manual/index.html\">manual</a></span></p>\n<ol>\n<li><p><span><a href=\"https://orgmode.org/manual/The-date_002ftime-prompt.html\">time\nprompt</a></span></p>\n<ul>\n<li><code>-</code> to look at past day, e.g. <code>-sun</code></li>\n</ul></li>\n<li><p><span>bindings</span></p>\n<ol>\n<li><p><span>org mode key bindings</span></p>\n<ul>\n<li><code>M-ret</code> add entry</li>\n<li><code>M-S-ret</code> todo entry</li>\n<li><code>TAB</code> / <code>S-TAB</code>\n<ul>\n<li>NB <code>S-TAB</code> is bound to <code>org-shifttab</code> instead of <code>org-global-cycle</code></li>\n</ul></li>\n<li><code>M-LEFT</code> / <code>M-RIGHT</code> / <code>M-UP</code> /\n<code>M-DOWN</code> / <code>M-S-LEFT</code> / <code>M-S-RIGHT</code> org-meta</li>\n<li><code>RET</code> open link</li>\n</ul></li>\n<li><p><span><a href=\"https://github.com/Somelauw/evil-org-mode?tab=readme-ov-file#keybindings\">evil\norg keybindings</a></span></p>\n<ul>\n<li><code><<</code> / <code>>></code> org-meta</li>\n<li><code>vae</code> / <code>vaR</code></li>\n<li><code>[ h</code> / <code>] h</code></li>\n<li><code>gj</code> / <code>gk</code>\n/ <code>gh</code> / <code>gl</code></li>\n<li><code>S-UP</code> / <code>S-DOWN</code> prev / next item in list</li>\n</ul></li>\n<li><p><span><a href=\"~/.config/emacs/modules/lang/org/config.el#map-map-evil-org-mode-map\">doom\nemacs org mode bindings</a></span></p>\n<ul>\n<li><code>zc</code> / <code>zo</code>\n/ <code>zO</code></li>\n<li><code>SPC m h</code> (<code>SPC m *</code>) / <code>SPC m i</code>\ntoggle heading / item</li>\n<li><code>SPC m d t</code> / org-time-stamp</li>\n<li><code>SPC m s S</code> subtree sort</li>\n<li><code>SPC m s s</code> subtree sparse</li>\n<li><code>SPC m x</code> toggle checkbox <code>SPC u SPC m x</code> add checkbox</li>\n<li><code>SPC m +</code> / <code>S-LEFT</code> / <code>S-RIGHT</code>\ncycle checkboxes</li>\n<li><code>SPC n l</code> store link e.g. in <span><em>email /\nmu4e</em></span></li>\n<li><code>SPC m l l</code> insert link</li>\n<li><code>C-c RET</code> insert heading <code>C-M-RET</code> insert subheading <a href=\"https://github.com/doomemacs/doomemacs/issues/3306\">https://github.com/doomemacs/doomemacs/issues/3306</a></li>\n<li><code>M-S-RET</code> insert todo heading</li>\n<li><code>SPC m t</code> / <code>S-LEFT</code> / <code>S-RIGHT</code>\n<code>TODO</code></li>\n<li><code>SPC m q</code> / <code>C-c C-c</code> (on heading) set tag</li>\n<li><code>C-c \\</code> org-match-sparse-tree on\ntags</li>\n<li><code>SPC m o</code> set property</li>\n<li><code>C-c C-c</code> on property property\naction</li>\n<li><code>C-c .</code> / <code>SPC m d t</code> / <code>SPC m d T</code> org timestamp\n<ul>\n<li><code>SPC u SPC m d t</code> for date time</li>\n</ul></li>\n<li><code>SPC m c</code> clock commands</li>\n<li><code>TAB</code> see drawer</li>\n<li><code>SPC m s r</code> refile <code>SPC m r R</code> refile reverse</li>\n<li><code>SPC X</code> capture</li>\n<li><code>SPC m A</code> archive</li>\n<li><code>SPC m s a</code> archive tag</li>\n<li><code>SPC m a</code> attachment</li>\n<li><code>SPC u 3 TAB</code> show 3 level deep\nheadings</li>\n</ul></li>\n</ol></li>\n<li><p><span>scripting</span></p>\n<pre><code>#+begin_src python\na = [ 1, 2, 3 ]\nreturn a\n#+end_src\n\n#+RESULTS:\n| 1 | 2 | 3 |\n</code></pre>\n<p><span>evaluate with <code>RET</code></span></p>\n<ol>\n<li><p><span>add with <code>org-insert-structure-template</code></span></p></li>\n</ol></li>\n<li><p><span>agenda</span></p>\n<ul>\n<li>how to exclude LOOP todo items from the todo list? <code>org-agenda-filter-by-category</code> / <code>sc</code> / <code>\\</code> on\nline</li>\n<li>how to filter by tag? <code>org-agenda-filter-by-tag</code> / <code>st</code> / <code><</code></li>\n<li><code>gD</code> select time range</li>\n</ul></li>\n<li><p><span>how to do bibtex\ncitations?</span></p>\n<ul>\n<li>biblio doom module</li>\n<li><code>org-cite-insert</code></li>\n<li><code>citar-open-notes</code></li>\n</ul></li>\n<li><p><span><span>O</span> org\nmode: enter on a pdf opens it in evince instead of emacs</span></p></li>\n</ol>\n<h2>latex</h2>\n<p><span>got a project compiling using doom emacs\nlatex module which pulls in AUCTeX</span></p>\n<ol>\n<li><p><span>synctex</span></p>\n<p><span>SPC m v and Ctrl+click in\nevince</span></p></li>\n<li><p><span><span>X</span> figure\nout how to use internal pdf viewer (seems like +latex/viewers isn’t\nrespected)</span></p></li>\n<li><p><span><span>X</span> figure\nout how to get SPC m v working from another tex file (seems like the\nmaster file detection is off)</span></p>\n<p><span><code>TeX-master-file</code></span></p></li>\n<li><p><span><span>X</span> auto\nreload pdf on changes</span></p>\n<p><span><code>auto-revert-mode</code></span></p></li>\n<li><p><span><span>O</span> pdf\nviewer search highlight <a href=\"https://github.com/vedang/pdf-tools/issues/162\">https://github.com/vedang/pdf-tools/issues/162</a></span></p></li>\n<li><p><span><span>X</span> resize\npdf frame to page width</span></p>\n<p><span><a href=\"https://github.com/RyanGibb/doom/blob/bf6cd234a6da944cf03c85274a4bfb0404abaf4a/config.el#L67-L79\">here</a></span></p></li>\n<li><p><span><span>X</span> jump to\nsection in source with <code>SPC s i</code> / <code>imenu</code></span></p></li>\n<li><p><span><span>X</span> how to\ninsert a block? <code>latex-insert-block\n=LaTeX-mark-environment</code> / <code>C-c .</code></span></p></li>\n<li><p><span><span>X</span> how to\nfold section headings?</span></p>\n<p><span><code>outline-minor-mode</code> and <code>zc</code></span></p></li>\n<li><p><span><span>X</span> go to\nlabel</span></p>\n<p><span><code>reftex-goto-label</code></span></p></li>\n</ol>\n<h2>android</h2>\n<p><span><a href=\"http://yuchen-lea.github.io/2024-02-04-android-emacs-with-doom-emacs-en/\">Using\ndoom-emacs in Android Emacs</a></span></p>\n<h2>ledger-mode</h2>\n<ul>\n<li><code>[[</code> / <code>]]</code>\nnext / prev transaction</li>\n<li><code>SPC m a</code> xact</li>\n<li><code>TAB</code> completion</li>\n<li><code>SPC m t</code> clear</li>\n<li><code>SPC m R</code> reconciliation</li>\n<li><code>TAB</code> mark transaction cleared (in\nreconciliation)</li>\n</ul>\n<h2>magit</h2>\n<ul>\n<li><code>SPC g C</code> git clone</li>\n</ul>\n<ol>\n<li><p><span>See log of current buffer file</span></p>\n<ul>\n<li><code>SPC g L</code></li>\n</ul></li>\n<li><p><span>See diff inline</span></p>\n<ul>\n<li><code>L -p s</code></li>\n</ul></li>\n</ol>\n<h2>lsp-mode</h2>\n<ol>\n<li><p><span><span>X</span>\nfigure out how to not watch <code>.gitignore</code>\nfiles</span></p>\n<p><span><a href=\"https://github.com/emacs-lsp/lsp-mode/issues/713#issuecomment-2708157288\">here</a></span></p></li>\n</ol>\n<h2>how to act on all search\nmatches</h2>\n<ul>\n<li>embark-collect (SPC a S)</li>\n</ul>\n<h2>LSP from devshells</h2>\n<ul>\n<li><a href=\"https://discourse.doomemacs.org/t/running-lsp-servers-inside-a-nix-shell/4701/2\">get\nlsp environment from nix devshell</a></li>\n<li>using direnv</li>\n</ul>\n<ol>\n<li><p><span><span>O</span> how to configure this to run?</span></p>\n<ul>\n<li>currently it runs for all files (e.g. markup files in my website\ndirectory, when I only need the Haskell LSP server for editing the\nstatic site generator)</li>\n<li>it also triggers if I add website org file to the agenda list</li>\n</ul></li>\n</ol>\n<h2>shells</h2>\n<ol>\n<li><p><span><code>shell</code>\ndrops you into a very minimal shell</span></p>\n<ul>\n<li>basically just I/O in a buffer, ANSI escape codes and such aren’t\nsupported</li>\n</ul></li>\n<li><p><span><code>shell-command</code></span></p>\n<ul>\n<li>run a shell command in your default shell</li>\n<li>doesn’t support sudo as can’t read from stdin</li>\n</ul></li>\n<li><p><span><code>eshell</code> a\n‘shell-like’ command interpreter implemented in emacs lisp</span></p>\n<ul>\n<li>e.g. an alternative to your system shell</li>\n</ul></li>\n<li><p><span><code>eshell-command</code></span></p>\n<ul>\n<li>runs a command in an <code>eshell</code>, and\nsupports sudo with a prompt for the password</li>\n</ul></li>\n<li><p><span><code>async-shell-command</code> / <code>M-&</code></span></p>\n<ul>\n<li>like shell-command but doesn’t lock emacs while the command is\nrunning and opens a buffer to display the output</li>\n<li>also supports sudo with a prompt for the password</li>\n</ul></li>\n<li><p><span><code>project-<all of these commands</code></span></p>\n<ul>\n<li>runs these shells in the current project root directory, as opposed\nto the current file’s directory</li>\n</ul></li>\n<li><p><span><code>term</code> /\n<code>vterm</code></span></p>\n<ul>\n<li>runs a terminal emulator in emacs</li>\n</ul></li>\n<li><p><span>what do I use?</span></p>\n<ul>\n<li>I’ll default to <code>SPC p &</code> which runs\n<code>projectile-run-async-shell-command-in-root</code>,\nwhich as far as I can tell is basically the same as <code>project-async-shell-command</code>, just because it’s\nthe default in Doom Emacs.</li>\n<li>Though it seems <code>projectile</code> is <a href=\"https://github.com/doomemacs/doomemacs/issues/6291#issuecomment-1097506995\">on\nthe way out</a> in favour of the in-built <code>project</code>.</li>\n</ul></li>\n<li><p><span><span>O</span> how do\nI stop the async shell output splitting to the side and open a new\nwindow instead?</span></p></li>\n<li><p><span><span>O</span>\neshell-command supports completion, but the other shell commands\ndon’t</span></p>\n<p><span><a href=\"https://github.com/szermatt/emacs-bash-completion\">emacs-bash-completion</a>\nmight be something to look at</span></p></li>\n</ol>\n<h2>find a CalDAV calendaring\napplication</h2>\n<ol>\n<li><p><span><span>~</span> <a href=\"https://github.com/dengste/org-caldav\">org-caldav</a></span></p>\n<ul>\n<li><a href=\"https://github.com/dengste/org-caldav/issues/322\">recurrence\nsupport is broken</a></li>\n<li>basically, we need a good CLI caldav client</li>\n<li>the mu to mu4e</li>\n<li>but I don’t want to do it</li>\n</ul></li>\n<li><p><span><span>~</span> <a href=\"https://gitlab.com/hperrey/khalel\">Khalel</a></span></p>\n<ul>\n<li>just imports a selection into an org file, and the org format is\nless expressive in some ways and more expressive in others</li>\n<li>we really need to deal with the iCalendar format directly</li>\n</ul></li>\n<li><p><span><span>X</span> <a href=\"https://github.com/RyanGibb/caledonia\">Caledonia</a></span></p>\n<ul>\n<li>okay, I’ve done it</li>\n</ul></li>\n</ol>",
8 "content": "<div>\n \n <span>Published 2 Feb 2025.</span>\n \n \n <span>Last update 18 Feb 2025.</span>\n \n </div>\n \n <div> Tags: <a href=\"/technology.html\" title=\"All pages tagged 'technology'.\">technology</a>. </div>\n \n \n\n <p><span>I started using Emacs for the <a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/\">mu4e</a> mail client\nafter using and liking the <a href=\"https://www.djcbsoftware.nl/code/mu/\">mu</a> mail indexer on the\ncommand line (read more about my <a href=\"mail-client.html\">mail client\nsetup</a>). Similarly, I was using the <a href=\"https://ledger-cli.org/\">ledger-cli</a> accounting system, and\nfound the Emacs minor mode to be great. Then I got curious about Emacs\n<a href=\"https://orgmode.org/\">Org Mode</a> and started using it for\nnote taking and task management. Now I’m using Emacs as my primary\ndevelopment environment.</span></p>\n<p><span>I realised that configuring Emacs to my liking\nwould be like second job, which I didn’t have the bandwidth for, so I\nstarted using the ‘distribution’ <a href=\"https://github.com/doomemacs/doomemacs\">Doom Emacs</a>. It enables\nVim bindings everywhere with <a href=\"https://github.com/emacs-evil/evil\">Evil Mode</a> which, coming\nfrom <a href=\"vim.html\">Vim</a>, made it much easier to get up to\nspeed.</span></p>\n<p><span>The Emacs philosophy is different from Vim’s, it\naims to be the ‘everything program’. It is it’s own operating system: a\nbig Lisp machine distinct from the Unix shell I’m used to working in.\nIt’s much more configurable and extensible than Vim – plugins are\nwritten in the same language that most of the Editor is itself, Emacs\nLisp. A small example of how this results in a seamless experience; in\nEmacs I have <a href=\"https://github.com/minad/vertico\">vertico</a>\nproviding fuzzy finding capabilities, which extends to built-in UI\nelements. For example, <code>M-x</code> will fuzzy\nmatch on commands I can execute. In contrast, in Neovim I use <a href=\"https://github.com/nvim-telescope/telescope.nvim\">telescope</a> to\nprovide fuzzy searching which I have to invoke separately – I still have\nthe normal command prompt with <code>:</code> but I can\nfuzzy search commands with <code><leader>fq</code> with this binding:</span></p>\n<div><pre><code><span><a href=\"#cb1-1\"></a><span>vim</span><span>.</span><span>keymap</span><span>.</span>set<span>(</span><span>'n'</span><span>,</span> <span>'<leader>fq'</span><span>,</span> <span>require</span><span>(</span><span>'telescope.builtin'</span><span>).</span><span>commands</span><span>)</span></span></code></pre></div>\n<p><span>Neovim <a href=\"https://github.com/neovim/neovim/issues/16142\">might</a> be adding\nsimilar extensibility for fuzzy searching. It seems like with things\nlike Evil mode and Neovim’s Lua-focused extensibility the two editors\nare moving towards each other somewhat.</span></p>\n<p><span>Emacs can be slow and a bit unwieldy however, so I\nstill use Vim sometimes, like for small edits on remote\nservers.</span></p>\n<p><span>You can find my Doom Emacs configuration <a href=\"https://github.com/RyanGibb/doom\">here</a>.</span></p>\n<p><span>Below are my working notes on learning and using\nEmacs. There are some open questions that I haven’t found time to look\nin to – please get in touch if you have an answer!</span></p>\n\n\n<h2>general</h2>\n<ol>\n<li><p><span>C-b C-x list buffers</span></p></li>\n<li><p><span>C-b x open buffer</span></p></li>\n<li><p><span>help:</span></p>\n<ol>\n<li><p><span>variable C-h v</span></p></li>\n<li><p><span>function C-h f</span></p></li>\n<li><p><span>key C-h k</span></p></li>\n</ol></li>\n<li><p><span><code>M-x</code>\ncommand</span></p></li>\n<li><p><span><code>C-x C-e</code> /\n(<code>gr</code> in evil) evaluate expression\nselected</span></p></li>\n<li><p><span><code>M-:</code> /\n(<code>SPC ;</code> in doom) evaluate expression from\nminibuffer</span></p></li>\n<li><p><span><a href=\"https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Conventions.html\">key\nbinding conventions</a></span></p></li>\n<li><p><span><code>kmacro-edit-macro</code> to edit recorded\nmacro</span></p></li>\n<li><p><span><span>X</span> <a href=\"https://github.com/emacs-evil/evil/issues/1851\">evil-mode <code>v_g_CTRL-A</code></a></span></p>\n<p><span>looks like evil-numbers provides this\nfunctionality but is bound to <code>g=</code> in Doom\nEmacs</span></p></li>\n<li><p><span><code>view-lossage</code> view recent history of commands\ninvoked with key bindings</span></p></li>\n<li><p><span><span>O</span> try\nxref (<a href=\"https://github.com/doomemacs/doomemacs/blob/2bc052425ca45a41532be0648ebd976d1bd2e6c1/modules/tools/lookup/README.org#L12\">doom\nemacs lookup module</a>)</span></p></li>\n<li><p><span><span>O</span>\nsearch and replace in project</span></p>\n<p><span><a href=\"https://github.com/hungyiloo/hungyi.net/blob/archive-2024/content/posts/doom-emacs-search-replace-project.org\">https://github.com/hungyiloo/hungyi.net/blob/archive-2024/content/posts/doom-emacs-search-replace-project.org</a></span></p></li>\n</ol>\n<h2>email / mu4e</h2>\n<ul>\n<li><code>m</code> move mail</li>\n<li><code>a v</code> open in firefox</li>\n<li><code>C</code> compose</li>\n<li><code>R/W/F/C/E</code>\nreply/reply-to-all/forward/compose/edit(draft)</li>\n<li><code>Pr</code> toggle property\n<ul>\n<li>Ptr mu4e-include-related</li>\n</ul></li>\n<li><code>e</code> extract attachments\n<ul>\n<li>~/.mailcap for external openers</li>\n<li><code>A</code> for more options</li>\n</ul></li>\n<li>blue/yellow in header view mu4e-unread-face mu4e-flagged-face</li>\n<li>exit composer\n<ul>\n<li><code>ZZ / C-c C-c</code> send message</li>\n<li><code>ZD / C-c C-d</code> save to drafts and\nleave</li>\n<li><code>ZF attach</code></li>\n<li><code>ZQ / C-c C-k</code> kill the message buffer\n(the message remains in the draft folder)</li>\n<li><code>ZA / C-c C-a</code> attach a file (pro-tip:\ndrag & drop works as well in graphical context)</li>\n<li><code>C-c C-;</code> switch the context</li>\n</ul></li>\n<li>disable include relevant by default\n<ul>\n<li><a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/Other-search-functionality.html#Including-related-messages-1\">https://www.djcbsoftware.nl/code/mu/mu4e/Other-search-functionality.html#Including-related-messages-1</a></li>\n</ul></li>\n<li>how to add a filter to a maildir\n<ul>\n<li>mu4e-search-narrow <code>/</code> with\nevil-collection, and <code>\\</code> to undo</li>\n<li>similarly mark pattern\n<ul>\n<li><a href=\"https://www.djcbsoftware.nl/code/mu/mu4e/Marking-messages.html\">https://www.djcbsoftware.nl/code/mu/mu4e/Marking-messages.html</a></li>\n</ul></li>\n</ul></li>\n<li>how to open URL with keyboard shortcut?\n<ul>\n<li><code>shr-browse-url</code></li>\n<li><code>RET</code></li>\n<li><code>browse-url-at-point</code></li>\n<li><code>M-RET</code> <code>mu4e--view-browse-url-from-binding</code></li>\n<li><a href=\"https://github.com/emacs-evil/evil-collection/blob/6365e7c8ae728f7a26294db261b6778d089a6263/modes/mu4e/evil-collection-mu4e.el#L59\"><code>gx</code></a></li>\n</ul></li>\n<li><code>cw</code> wide reply in message view with\nevil mode</li>\n<li><code>M-q</code> format paragraph</li>\n<li><code>.</code> view headers</li>\n<li>how to switch message from plaintext to html with a keyboard\nshortcut?</li>\n<li>custom account completition?</li>\n<li>open attachment\n<ul>\n<li><code>mu4e-view-mime-part-action</code></li>\n<li>doom’s <code>A</code> / <code>+mu4e-view-select-mime-part-action</code> is <a href=\"https://github.com/doomemacs/doomemacs/issues/7847\">currently\nbroken</a></li>\n</ul></li>\n</ul>\n<ol>\n<li><p><span><span>O</span> how\nto have <code>m</code> / <code>mu4e-headers-mark-for-move</code> pick up the\ncontext</span></p>\n<p><span>it seems like <code>match-func</code> works for replies but not\nthis</span></p></li>\n</ol>\n<h2>doom macs</h2>\n<ul>\n<li><code>SPC h b t</code> which key show all\nbindings</li>\n<li><code>C-h</code> in which key to search\nbindings</li>\n<li><code>SPC h v</code> help variables</li>\n<li><code>SPC h o</code> help symbol</li>\n<li><code>K</code> help</li>\n<li><code>gd</code> go to definition</li>\n<li>map!</li>\n<li><code>SPC f s</code> save file</li>\n<li><code>SPC TAB</code> workspaces</li>\n<li><code>SPC b</code> buffers</li>\n<li><code>SPC s</code> search</li>\n<li><code>gr</code> evaluate lisp</li>\n<li><code>SPC g g</code> <span><em>magit</em></span></li>\n<li><code>SPC o m</code> mu4e</li>\n<li><code>SPC o t</code> terminal</li>\n<li><code>SPC q s</code> / <code>SPC q l</code> save / load session</li>\n<li><code>SPC p f</code> file in project</li>\n<li>in minibuffer <code>C-s</code> searches\nhistory</li>\n<li><code>SPC p p</code> opens project in new\nworkspace</li>\n<li>jumplist <code>C-i</code> / <code>C-o</code> not working in terminal?\n<ul>\n<li>terminal can’t distinguish between Tab and C-i</li>\n<li><a href=\"https://github.com/doomemacs/doomemacs/issues/8101\">https://github.com/doomemacs/doomemacs/issues/8101</a></li>\n</ul></li>\n<li>Why does the help menu not stay opening when switching windows?\n<ul>\n<li>Doom’s popup window implementation</li>\n<li><code>C-~</code> make popup real window</li>\n</ul></li>\n<li>How to get into normal mode in emacs minibuffers?\n<ul>\n<li><code>(setq evil-collection-setup-minibuffer t)</code></li>\n</ul></li>\n<li>how to edit properties in org mode?\n<ul>\n<li><code>SPC m o</code></li>\n</ul></li>\n<li>how to see org mode agenda?\n<ul>\n<li><code>SPC o a</code></li>\n</ul></li>\n<li>how to remove icons from\nmu4e?</li>\n<li><code>M-`</code> does menu bar</li>\n<li><code>SPC h w</code> where-is command</li>\n<li><code>S</code> evil-surround</li>\n<li>spell checker</li>\n</ul>\n<h2>org-mode</h2>\n<p><span><a href=\"https://orgmode.org/manual/index.html\">manual</a></span></p>\n<ol>\n<li><p><span><a href=\"https://orgmode.org/manual/The-date_002ftime-prompt.html\">time\nprompt</a></span></p>\n<ul>\n<li><code>-</code> to look at past day, e.g. <code>-sun</code></li>\n</ul></li>\n<li><p><span>bindings</span></p>\n<ol>\n<li><p><span>org mode key bindings</span></p>\n<ul>\n<li><code>M-ret</code> add entry</li>\n<li><code>M-S-ret</code> todo entry</li>\n<li><code>TAB</code> / <code>S-TAB</code>\n<ul>\n<li>NB <code>S-TAB</code> is bound to <code>org-shifttab</code> instead of <code>org-global-cycle</code></li>\n</ul></li>\n<li><code>M-LEFT</code> / <code>M-RIGHT</code> / <code>M-UP</code> /\n<code>M-DOWN</code> / <code>M-S-LEFT</code> / <code>M-S-RIGHT</code> org-meta</li>\n<li><code>RET</code> open link</li>\n</ul></li>\n<li><p><span><a href=\"https://github.com/Somelauw/evil-org-mode?tab=readme-ov-file#keybindings\">evil\norg keybindings</a></span></p>\n<ul>\n<li><code><<</code> / <code>>></code> org-meta</li>\n<li><code>vae</code> / <code>vaR</code></li>\n<li><code>[ h</code> / <code>] h</code></li>\n<li><code>gj</code> / <code>gk</code>\n/ <code>gh</code> / <code>gl</code></li>\n<li><code>S-UP</code> / <code>S-DOWN</code> prev / next item in list</li>\n</ul></li>\n<li><p><span><a href=\"~/.config/emacs/modules/lang/org/config.el#map-map-evil-org-mode-map\">doom\nemacs org mode bindings</a></span></p>\n<ul>\n<li><code>zc</code> / <code>zo</code>\n/ <code>zO</code></li>\n<li><code>SPC m h</code> (<code>SPC m *</code>) / <code>SPC m i</code>\ntoggle heading / item</li>\n<li><code>SPC m d t</code> / org-time-stamp</li>\n<li><code>SPC m s S</code> subtree sort</li>\n<li><code>SPC m s s</code> subtree sparse</li>\n<li><code>SPC m x</code> toggle checkbox <code>SPC u SPC m x</code> add checkbox</li>\n<li><code>SPC m +</code> / <code>S-LEFT</code> / <code>S-RIGHT</code>\ncycle checkboxes</li>\n<li><code>SPC n l</code> store link e.g. in <span><em>email /\nmu4e</em></span></li>\n<li><code>SPC m l l</code> insert link</li>\n<li><code>C-c RET</code> insert heading <code>C-M-RET</code> insert subheading <a href=\"https://github.com/doomemacs/doomemacs/issues/3306\">https://github.com/doomemacs/doomemacs/issues/3306</a></li>\n<li><code>M-S-RET</code> insert todo heading</li>\n<li><code>SPC m t</code> / <code>S-LEFT</code> / <code>S-RIGHT</code>\n<code>TODO</code></li>\n<li><code>SPC m q</code> / <code>C-c C-c</code> (on heading) set tag</li>\n<li><code>C-c \\</code> org-match-sparse-tree on\ntags</li>\n<li><code>SPC m o</code> set property</li>\n<li><code>C-c C-c</code> on property property\naction</li>\n<li><code>C-c .</code> / <code>SPC m d t</code> / <code>SPC m d T</code> org timestamp\n<ul>\n<li><code>SPC u SPC m d t</code> for date time</li>\n</ul></li>\n<li><code>SPC m c</code> clock commands</li>\n<li><code>TAB</code> see drawer</li>\n<li><code>SPC m s r</code> refile <code>SPC m r R</code> refile reverse</li>\n<li><code>SPC X</code> capture</li>\n<li><code>SPC m A</code> archive</li>\n<li><code>SPC m s a</code> archive tag</li>\n<li><code>SPC m a</code> attachment</li>\n<li><code>SPC u 3 TAB</code> show 3 level deep\nheadings</li>\n</ul></li>\n</ol></li>\n<li><p><span>scripting</span></p>\n<pre><code>#+begin_src python\na = [ 1, 2, 3 ]\nreturn a\n#+end_src\n\n#+RESULTS:\n| 1 | 2 | 3 |\n</code></pre>\n<p><span>evaluate with <code>RET</code></span></p>\n<ol>\n<li><p><span>add with <code>org-insert-structure-template</code></span></p></li>\n</ol></li>\n<li><p><span>agenda</span></p>\n<ul>\n<li>how to exclude LOOP todo items from the todo list? <code>org-agenda-filter-by-category</code> / <code>sc</code> / <code>\\</code> on\nline</li>\n<li>how to filter by tag? <code>org-agenda-filter-by-tag</code> / <code>st</code> / <code><</code></li>\n<li><code>gD</code> select time range</li>\n</ul></li>\n<li><p><span>how to do bibtex\ncitations?</span></p>\n<ul>\n<li>biblio doom module</li>\n<li><code>org-cite-insert</code></li>\n<li><code>citar-open-notes</code></li>\n</ul></li>\n<li><p><span><span>O</span> org\nmode: enter on a pdf opens it in evince instead of emacs</span></p></li>\n</ol>\n<h2>latex</h2>\n<p><span>got a project compiling using doom emacs\nlatex module which pulls in AUCTeX</span></p>\n<ol>\n<li><p><span>synctex</span></p>\n<p><span>SPC m v and Ctrl+click in\nevince</span></p></li>\n<li><p><span><span>X</span> figure\nout how to use internal pdf viewer (seems like +latex/viewers isn’t\nrespected)</span></p></li>\n<li><p><span><span>X</span> figure\nout how to get SPC m v working from another tex file (seems like the\nmaster file detection is off)</span></p>\n<p><span><code>TeX-master-file</code></span></p></li>\n<li><p><span><span>X</span> auto\nreload pdf on changes</span></p>\n<p><span><code>auto-revert-mode</code></span></p></li>\n<li><p><span><span>O</span> pdf\nviewer search highlight <a href=\"https://github.com/vedang/pdf-tools/issues/162\">https://github.com/vedang/pdf-tools/issues/162</a></span></p></li>\n<li><p><span><span>X</span> resize\npdf frame to page width</span></p>\n<p><span><a href=\"https://github.com/RyanGibb/doom/blob/bf6cd234a6da944cf03c85274a4bfb0404abaf4a/config.el#L67-L79\">here</a></span></p></li>\n<li><p><span><span>X</span> jump to\nsection in source with <code>SPC s i</code> / <code>imenu</code></span></p></li>\n<li><p><span><span>X</span> how to\ninsert a block? <code>latex-insert-block\n=LaTeX-mark-environment</code> / <code>C-c .</code></span></p></li>\n<li><p><span><span>X</span> how to\nfold section headings?</span></p>\n<p><span><code>outline-minor-mode</code> and <code>zc</code></span></p></li>\n<li><p><span><span>X</span> go to\nlabel</span></p>\n<p><span><code>reftex-goto-label</code></span></p></li>\n</ol>\n<h2>android</h2>\n<p><span><a href=\"http://yuchen-lea.github.io/2024-02-04-android-emacs-with-doom-emacs-en/\">Using\ndoom-emacs in Android Emacs</a></span></p>\n<h2>ledger-mode</h2>\n<ul>\n<li><code>[[</code> / <code>]]</code>\nnext / prev transaction</li>\n<li><code>SPC m a</code> xact</li>\n<li><code>TAB</code> completion</li>\n<li><code>SPC m t</code> clear</li>\n<li><code>SPC m R</code> reconciliation</li>\n<li><code>TAB</code> mark transaction cleared (in\nreconciliation)</li>\n</ul>\n<h2>magit</h2>\n<ul>\n<li><code>SPC g C</code> git clone</li>\n</ul>\n<ol>\n<li><p><span>See log of current buffer file</span></p>\n<ul>\n<li><code>SPC g L</code></li>\n</ul></li>\n<li><p><span>See diff inline</span></p>\n<ul>\n<li><code>L -p s</code></li>\n</ul></li>\n</ol>\n<h2>lsp-mode</h2>\n<ol>\n<li><p><span><span>X</span>\nfigure out how to not watch <code>.gitignore</code>\nfiles</span></p>\n<p><span><a href=\"https://github.com/emacs-lsp/lsp-mode/issues/713#issuecomment-2708157288\">here</a></span></p></li>\n</ol>\n<h2>how to act on all search\nmatches</h2>\n<ul>\n<li>embark-collect (SPC a S)</li>\n</ul>\n<h2>LSP from devshells</h2>\n<ul>\n<li><a href=\"https://discourse.doomemacs.org/t/running-lsp-servers-inside-a-nix-shell/4701/2\">get\nlsp environment from nix devshell</a></li>\n<li>using direnv</li>\n</ul>\n<ol>\n<li><p><span><span>O</span> how to configure this to run?</span></p>\n<ul>\n<li>currently it runs for all files (e.g. markup files in my website\ndirectory, when I only need the Haskell LSP server for editing the\nstatic site generator)</li>\n<li>it also triggers if I add website org file to the agenda list</li>\n</ul></li>\n</ol>\n<h2>shells</h2>\n<ol>\n<li><p><span><code>shell</code>\ndrops you into a very minimal shell</span></p>\n<ul>\n<li>basically just I/O in a buffer, ANSI escape codes and such aren’t\nsupported</li>\n</ul></li>\n<li><p><span><code>shell-command</code></span></p>\n<ul>\n<li>run a shell command in your default shell</li>\n<li>doesn’t support sudo as can’t read from stdin</li>\n</ul></li>\n<li><p><span><code>eshell</code> a\n‘shell-like’ command interpreter implemented in emacs lisp</span></p>\n<ul>\n<li>e.g. an alternative to your system shell</li>\n</ul></li>\n<li><p><span><code>eshell-command</code></span></p>\n<ul>\n<li>runs a command in an <code>eshell</code>, and\nsupports sudo with a prompt for the password</li>\n</ul></li>\n<li><p><span><code>async-shell-command</code> / <code>M-&</code></span></p>\n<ul>\n<li>like shell-command but doesn’t lock emacs while the command is\nrunning and opens a buffer to display the output</li>\n<li>also supports sudo with a prompt for the password</li>\n</ul></li>\n<li><p><span><code>project-<all of these commands</code></span></p>\n<ul>\n<li>runs these shells in the current project root directory, as opposed\nto the current file’s directory</li>\n</ul></li>\n<li><p><span><code>term</code> /\n<code>vterm</code></span></p>\n<ul>\n<li>runs a terminal emulator in emacs</li>\n</ul></li>\n<li><p><span>what do I use?</span></p>\n<ul>\n<li>I’ll default to <code>SPC p &</code> which runs\n<code>projectile-run-async-shell-command-in-root</code>,\nwhich as far as I can tell is basically the same as <code>project-async-shell-command</code>, just because it’s\nthe default in Doom Emacs.</li>\n<li>Though it seems <code>projectile</code> is <a href=\"https://github.com/doomemacs/doomemacs/issues/6291#issuecomment-1097506995\">on\nthe way out</a> in favour of the in-built <code>project</code>.</li>\n</ul></li>\n<li><p><span><span>O</span> how do\nI stop the async shell output splitting to the side and open a new\nwindow instead?</span></p></li>\n<li><p><span><span>O</span>\neshell-command supports completion, but the other shell commands\ndon’t</span></p>\n<p><span><a href=\"https://github.com/szermatt/emacs-bash-completion\">emacs-bash-completion</a>\nmight be something to look at</span></p></li>\n</ol>\n<h2>find a CalDAV calendaring\napplication</h2>\n<ol>\n<li><p><span><span>~</span> <a href=\"https://github.com/dengste/org-caldav\">org-caldav</a></span></p>\n<ul>\n<li><a href=\"https://github.com/dengste/org-caldav/issues/322\">recurrence\nsupport is broken</a></li>\n<li>basically, we need a good CLI caldav client</li>\n<li>the mu to mu4e</li>\n<li>but I don’t want to do it</li>\n</ul></li>\n<li><p><span><span>~</span> <a href=\"https://gitlab.com/hperrey/khalel\">Khalel</a></span></p>\n<ul>\n<li>just imports a selection into an org file, and the org format is\nless expressive in some ways and more expressive in others</li>\n<li>we really need to deal with the iCalendar format directly</li>\n</ul></li>\n<li><p><span><span>X</span> <a href=\"https://github.com/RyanGibb/caledonia\">Caledonia</a></span></p>\n<ul>\n<li>okay, I’ve done it</li>\n</ul></li>\n</ol>",
9 "content_type": "html",
10 "categories": [],
11 "source": "https://ryan.freumh.org/atom.xml"
12}