sqrtminusone.github.io/public/configs/emacs/index.html
2021-10-01 18:59:00 +03:00

5120 lines
379 KiB
HTML

<!DOCTYPE html>
<html lang=""><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Emacs config</title>
<meta name="description" content="Freedom is a state of mind">
<meta name="author" content='SqrtMinusOne'>
<link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous">
<link rel="stylesheet" href="/sass/researcher.min.css">
<link rel="icon" type="image/ico" href="https://sqrtminusone.xyz/favicon.ico">
</head>
<body><div class="container mt-5">
<nav class="navbar navbar-expand-sm flex-column flex-sm-row text-nowrap p-0">
<a class="navbar-brand mx-0 mr-sm-auto" href="https://sqrtminusone.xyz/" title="SqrtMinusOne">
SqrtMinusOne
</a>
<div class="navbar-nav flex-row flex-wrap justify-content-center">
<a class="nav-item nav-link" href="/" title="Index">
Index
</a>
<span class="nav-item navbar-text mx-1">/</span>
<a class="nav-item nav-link" href="/posts/" title="Posts">
Posts
</a>
<span class="nav-item navbar-text mx-1">/</span>
<a class="nav-item nav-link" href="/configs/readme" title="Configs">
Configs
</a>
</div>
</nav>
</div>
<hr>
<div id="content">
<div class="container">
<blockquote>
<p>One day we won&rsquo;t hate one another, no young boy will march to war and I will clean up my Emacs config. But that day isn&rsquo;t today.</p>
</blockquote>
<p>My <a href="https://www.gnu.org/software/emacs/">Emacs</a> configuration.</p>
<p>As with other files in the repo, parts prefixed with (OFF) are not used but kept for historic purposes.</p>
<div class="ox-hugo-toc toc">
<div></div>
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#primary-setup">Primary setup</a>
<ul>
<li><a href="#measure-startup-speed">Measure startup speed</a></li>
<li><a href="#straight-dot-el">straight.el</a></li>
<li><a href="#use-package">use-package</a></li>
<li><a href="#config-variants-and-environment">config variants &amp; environment</a></li>
<li><a href="#performance">Performance</a>
<ul>
<li><a href="#garbage-collection">Garbage collection</a></li>
<li><a href="#run-garbage-collection-when-emacs-is-unfocused">Run garbage collection when Emacs is unfocused</a></li>
<li><a href="#native-compilation">Native compilation</a></li>
</ul>
</li>
<li><a href="#anaconda">Anaconda</a></li>
<li><a href="#custom-file-location">Custom file location</a></li>
<li><a href="#private-config">Private config</a></li>
<li><a href="#no-littering">No littering</a></li>
<li><a href="#prevent-emacs-from-closing">Prevent Emacs from closing</a></li>
</ul>
</li>
<li><a href="#global-editing-configuration">Global editing configuration</a>
<ul>
<li><a href="#general-keybindings-stuff">General keybindings stuff</a>
<ul>
<li><a href="#general-dot-el">general.el</a></li>
<li><a href="#which-key">which-key</a>
<ul>
<li><a href="#dump-keybindings">dump keybindings</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#evil-mode">Evil mode</a>
<ul>
<li><a href="#evil">evil</a></li>
<li><a href="#addons">Addons</a></li>
<li><a href="#evil-collection">evil-collection</a></li>
</ul>
</li>
<li><a href="#more-keybindings">More keybindings</a>
<ul>
<li><a href="#escape-key">Escape key</a></li>
<li><a href="#home-and-end">Home &amp; end</a></li>
<li><a href="#my-leader">My leader</a></li>
<li><a href="#universal-argument">Universal argument</a></li>
<li><a href="#profiler">Profiler</a></li>
<li><a href="#buffer-switching">Buffer switching</a></li>
<li><a href="#buffer-management">Buffer management</a></li>
<li><a href="#xref">xref</a></li>
<li><a href="#folding">Folding</a></li>
<li><a href="#zoom">Zoom</a></li>
</ul>
</li>
<li><a href="#editing-helpers">Editing helpers</a>
<ul>
<li><a href="#visual-fill-column-mode">Visual fill column mode</a></li>
<li><a href="#smartparens">smartparens</a></li>
<li><a href="#aggressive-indent">Aggressive Indent</a></li>
<li><a href="#delete-trailing-whitespace">Delete trailing whitespace</a></li>
<li><a href="#expand-region">Expand region</a></li>
</ul>
</li>
<li><a href="#various-settings">Various settings</a>
<ul>
<li><a href="#tabs">Tabs</a></li>
<li><a href="#scrolling-config">Scrolling config</a></li>
<li><a href="#clipboard">Clipboard</a></li>
<li><a href="#backups">Backups</a></li>
</ul>
</li>
<li><a href="#undo-tree">Undo Tree</a></li>
<li><a href="#help">Help</a></li>
<li><a href="#ivy-counsel-swiper">Ivy, counsel, swiper</a>
<ul>
<li><a href="#ivy-rich">ivy-rich</a></li>
<li><a href="#prescient">prescient</a></li>
<li><a href="#keybindings">Keybindings</a></li>
</ul>
</li>
<li><a href="#off--helm"><span class="org-todo done OFF">OFF</span> (OFF) Helm</a></li>
<li><a href="#treemacs">Treemacs</a>
<ul>
<li><a href="#helper-functions">Helper functions</a></li>
<li><a href="#custom-icons">Custom icons</a></li>
</ul>
</li>
<li><a href="#projectile">Projectile</a></li>
<li><a href="#company">Company</a></li>
<li><a href="#git-and-magit">Git &amp; Magit</a></li>
<li><a href="#editorconfig">Editorconfig</a></li>
<li><a href="#snippets">Snippets</a></li>
<li><a href="#time-trackers">Time trackers</a>
<ul>
<li><a href="#wakatime">WakaTime</a></li>
<li><a href="#activitywatch">ActivityWatch</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ui">UI</a>
<ul>
<li><a href="#general-ui-and-gui-settings">General UI &amp; GUI Settings</a></li>
<li><a href="#theme-and-global-stuff">Theme &amp; global stuff</a>
<ul>
<li><a href="#custom-theme">Custom theme</a></li>
<li><a href="#font">Font</a></li>
</ul>
</li>
<li><a href="#custom-frame-title">Custom frame title</a></li>
<li><a href="#perspective-dot-el">perspective.el</a>
<ul>
<li><a href="#some-functions">Some functions</a></li>
</ul>
</li>
<li><a href="#off--tab-bar"><span class="org-todo done OFF">OFF</span> (OFF) Tab bar</a>
<ul>
<li><a href="#setup">Setup</a></li>
<li><a href="#my-title">My title</a></li>
</ul>
</li>
<li><a href="#modeline">Modeline</a></li>
<li><a href="#font-stuff">Font stuff</a>
<ul>
<li><a href="#emojis">Emojis</a></li>
<li><a href="#ligatures">Ligatures</a></li>
<li><a href="#icons">Icons</a></li>
<li><a href="#highlight-todo">Highlight todo</a></li>
</ul>
</li>
<li><a href="#text-highlight-improvements">Text highlight improvements</a></li>
</ul>
</li>
<li><a href="#dired">Dired</a>
<ul>
<li><a href="#basic-config-and-keybindings">Basic config &amp; keybindings</a></li>
<li><a href="#addons">Addons</a></li>
<li><a href="#subdirectories">Subdirectories</a></li>
<li><a href="#tramp">TRAMP</a></li>
<li><a href="#bookmarks">Bookmarks</a></li>
</ul>
</li>
<li><a href="#shells">Shells</a>
<ul>
<li><a href="#vterm">vterm</a>
<ul>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#subterminal">Subterminal</a></li>
<li><a href="#dired-integration">Dired integration</a></li>
<li><a href="#with-editor-integration">With-editor integration</a></li>
</ul>
</li>
<li><a href="#eshell">Eshell</a></li>
</ul>
</li>
<li><a href="#org-mode">Org Mode</a>
<ul>
<li><a href="#installation-and-basic-settings">Installation &amp; basic settings</a>
<ul>
<li><a href="#encryption">Encryption</a></li>
<li><a href="#org-contrib">org-contrib</a></li>
</ul>
</li>
<li><a href="#integration-with-evil">Integration with evil</a></li>
<li><a href="#literate-programing">Literate programing</a>
<ul>
<li><a href="#python-and-jupyter">Python &amp; Jupyter</a></li>
<li><a href="#hy">Hy</a></li>
<li><a href="#view-html-in-browser">View HTML in browser</a></li>
<li><a href="#plantuml">PlantUML</a></li>
<li><a href="#setup">Setup</a></li>
<li><a href="#managing-jupyter-kernels">Managing Jupyter kernels</a></li>
<li><a href="#do-not-wrap-the-output-in-emacs-jupyter">Do not wrap the output in emacs-jupyter</a></li>
<li><a href="#wrap-source-code-output">Wrap source code output</a></li>
</ul>
</li>
<li><a href="#productivity-and-knowledge-management">Productivity &amp; Knowledge management</a>
<ul>
<li><a href="#capture-templates-and-various-settings">Capture templates &amp; various settings</a></li>
<li><a href="#custom-agendas">Custom agendas</a></li>
<li><a href="#org-ql">org-ql</a></li>
<li><a href="#review-workflow">Review workflow</a>
<ul>
<li><a href="#data-from-git-and-org-roam">Data from git &amp; org-roam</a></li>
<li><a href="#data-from-org-journal">Data from org-journal</a></li>
<li><a href="#data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</a></li>
<li><a href="#capture-template">Capture template</a></li>
</ul>
</li>
<li><a href="#org-journal">Org Journal</a></li>
<li><a href="#org-roam">Org Roam</a>
<ul>
<li><a href="#org-roam-ui">org-roam-ui</a></li>
<li><a href="#org-roam-protocol">org-roam-protocol</a></li>
</ul>
</li>
<li><a href="#org-ref">org-ref</a></li>
<li><a href="#org-roam-bibtex">org-roam-bibtex</a></li>
</ul>
</li>
<li><a href="#ui">UI</a>
<ul>
<li><a href="#off--instant-equations-preview"><span class="org-todo done OFF">OFF</span> (OFF) Instant equations preview</a></li>
<li><a href="#latex-fragments">LaTeX fragments</a></li>
<li><a href="#better-headers">Better headers</a></li>
<li><a href="#org-agenda-icons">Org Agenda Icons</a></li>
</ul>
</li>
<li><a href="#export">Export</a>
<ul>
<li><a href="#general-settings">General settings</a></li>
<li><a href="#hugo">Hugo</a></li>
<li><a href="#jupyter-notebook">Jupyter Notebook</a></li>
<li><a href="#html-export">Html export</a></li>
<li><a href="#latex">LaTeX</a></li>
</ul>
</li>
<li><a href="#keybindings-and-stuff">Keybindings &amp; stuff</a>
<ul>
<li><a href="#copy-a-link">Copy a link</a></li>
</ul>
</li>
<li><a href="#presentations">Presentations</a></li>
<li><a href="#tools">Tools</a>
<ul>
<li><a href="#toc">TOC</a></li>
<li><a href="#screenshots">Screenshots</a></li>
</ul>
</li>
<li><a href="#system-configuration">System configuration</a>
<ul>
<li><a href="#tables-for-guix-dependencies">Tables for Guix Dependencies</a></li>
<li><a href="#noweb-evaluations">Noweb evaluations</a></li>
<li><a href="#yadm-hook">yadm hook</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#off--eaf"><span class="org-todo done OFF">OFF</span> (OFF) EAF</a>
<ul>
<li><a href="#installation">Installation</a></li>
<li><a href="#config">Config</a></li>
</ul>
</li>
<li><a href="#programming">Programming</a>
<ul>
<li><a href="#general-setup">General setup</a>
<ul>
<li><a href="#lsp">LSP</a>
<ul>
<li><a href="#setup">Setup</a></li>
<li><a href="#integrations">Integrations</a></li>
<li><a href="#keybindings">Keybindings</a></li>
</ul>
</li>
<li><a href="#flycheck">Flycheck</a></li>
<li><a href="#tree-sitter">Tree Sitter</a></li>
<li><a href="#off--dap"><span class="org-todo done OFF">OFF</span> (OFF) DAP</a></li>
<li><a href="#off--tabnine"><span class="org-todo done OFF">OFF</span> (OFF) TabNine</a></li>
<li><a href="#off--code-compass"><span class="org-todo done OFF">OFF</span> (OFF) Code Compass</a>
<ul>
<li><a href="#dependencies">Dependencies</a></li>
<li><a href="#plugin">Plugin</a></li>
</ul>
</li>
<li><a href="#reformatter">Reformatter</a></li>
<li><a href="#general-additional-config">General additional config</a></li>
</ul>
</li>
<li><a href="#web-development">Web development</a>
<ul>
<li><a href="#emmet">Emmet</a></li>
<li><a href="#prettier">Prettier</a></li>
<li><a href="#typescript">TypeScript</a></li>
<li><a href="#javascript">JavaScript</a></li>
<li><a href="#jest">Jest</a></li>
<li><a href="#web-mode">web-mode</a></li>
<li><a href="#off--vue-dot-js"><span class="org-todo done OFF">OFF</span> (OFF) Vue.js</a>
<ul>
<li><a href="#mmm-mode-fix">mmm-mode fix</a></li>
</ul>
</li>
<li><a href="#off--svelte"><span class="org-todo done OFF">OFF</span> (OFF) Svelte</a></li>
<li><a href="#scss">SCSS</a></li>
<li><a href="#php">PHP</a></li>
</ul>
</li>
<li><a href="#latex">LaTeX</a>
<ul>
<li><a href="#auctex">AUCTeX</a></li>
<li><a href="#bibtex">BibTeX</a></li>
<li><a href="#import-dot-sty">Import *.sty</a></li>
<li><a href="#snippets">Snippets</a>
<ul>
<li><a href="#greek-letters">Greek letters</a></li>
<li><a href="#english-letters">English letters</a></li>
<li><a href="#math-symbols">Math symbols</a></li>
<li><a href="#section-snippets">Section snippets</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#other-markup-languages">Other markup languages</a>
<ul>
<li><a href="#markdown">Markdown</a></li>
<li><a href="#plantuml">PlantUML</a></li>
<li><a href="#languagetool">LanguageTool</a></li>
</ul>
</li>
<li><a href="#lisp">Lisp</a>
<ul>
<li><a href="#meta-lisp">Meta Lisp</a></li>
<li><a href="#emacs-lisp">Emacs Lisp</a>
<ul>
<li><a href="#package-lint">Package Lint</a></li>
<li><a href="#general-settings">General settings</a></li>
</ul>
</li>
<li><a href="#common-lisp">Common lisp</a>
<ul>
<li><a href="#slime">SLIME</a></li>
<li><a href="#general-settings">General settings</a></li>
</ul>
</li>
<li><a href="#clojure">Clojure</a></li>
<li><a href="#hy">Hy</a></li>
<li><a href="#scheme">Scheme</a></li>
<li><a href="#clips">CLIPS</a></li>
</ul>
</li>
<li><a href="#python">Python</a>
<ul>
<li><a href="#pipenv">pipenv</a></li>
<li><a href="#yapf">yapf</a></li>
<li><a href="#isort">isort</a></li>
<li><a href="#sphinx-doc">sphinx-doc</a></li>
<li><a href="#pytest">pytest</a>
<ul>
<li><a href="#fix-comint-buffer-width">Fix comint buffer width</a></li>
</ul>
</li>
<li><a href="#code-cells">code-cells</a></li>
<li><a href="#tensorboard">tensorboard</a></li>
</ul>
</li>
<li><a href="#java">Java</a></li>
<li><a href="#go">Go</a></li>
<li><a href="#dot-net">.NET</a>
<ul>
<li><a href="#c">C#</a></li>
<li><a href="#msbuild">MSBuild</a></li>
</ul>
</li>
<li><a href="#fish">fish</a></li>
<li><a href="#sh">sh</a></li>
<li><a href="#haskell">Haskell</a></li>
<li><a href="#lua">Lua</a></li>
<li><a href="#json">JSON</a></li>
<li><a href="#sql">SQL</a></li>
<li><a href="#yaml">YAML</a></li>
<li><a href="#dot-env">.env</a></li>
<li><a href="#csv">CSV</a></li>
<li><a href="#off--pdf"><span class="org-todo done OFF">OFF</span> (OFF) PDF</a></li>
<li><a href="#docker">Docker</a></li>
</ul>
</li>
<li><a href="#apps-and-misc">Apps &amp; Misc</a>
<ul>
<li><a href="#managing-dotfiles">Managing dotfiles</a>
<ul>
<li><a href="#open-emacs-config">Open Emacs config</a></li>
<li><a href="#open-magit-for-yadm">Open Magit for yadm</a></li>
<li><a href="#open-a-dotfile">Open a dotfile</a></li>
</ul>
</li>
<li><a href="#internet-and-multimedia">Internet &amp; Multimedia</a>
<ul>
<li><a href="#notmuch">Notmuch</a></li>
<li><a href="#elfeed">Elfeed</a>
<ul>
<li><a href="#some-additions">Some additions</a></li>
<li><a href="#youtube-and-emms">YouTube &amp; EMMS</a></li>
</ul>
</li>
<li><a href="#emms">EMMS</a>
<ul>
<li><a href="#mpd">MPD</a></li>
<li><a href="#mpv">MPV</a></li>
<li><a href="#cache-cleanup">Cache cleanup</a></li>
<li><a href="#fetching-lyrics">Fetching lyrics</a></li>
<li><a href="#some-keybindings">Some keybindings</a></li>
<li><a href="#emms-and-mpd-fixes">EMMS &amp; mpd Fixes</a></li>
</ul>
</li>
<li><a href="#eww">EWW</a></li>
<li><a href="#erc">ERC</a></li>
<li><a href="#google-translate">Google Translate</a></li>
</ul>
</li>
<li><a href="#reading-documentation">Reading documentation</a>
<ul>
<li><a href="#tldr">tldr</a></li>
<li><a href="#man-and-info">man &amp; info</a></li>
<li><a href="#devdocs-dot-io">devdocs.io</a></li>
</ul>
</li>
<li><a href="#utilities">Utilities</a>
<ul>
<li><a href="#pass">pass</a></li>
<li><a href="#docker">Docker</a></li>
<li><a href="#progidy">Progidy</a></li>
<li><a href="#screenshot-dot-el">screenshot.el</a></li>
<li><a href="#proced">proced</a></li>
<li><a href="#guix">Guix</a></li>
</ul>
</li>
<li><a href="#productivity">Productivity</a>
<ul>
<li><a href="#pomidor">Pomidor</a></li>
<li><a href="#calendar">Calendar</a></li>
</ul>
</li>
<li><a href="#fun">Fun</a>
<ul>
<li><a href="#discord-integration">Discord integration</a></li>
<li><a href="#snow">Snow</a></li>
<li><a href="#zone">Zone</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#guix-settings">Guix settings</a></li>
</ul>
</div>
<!--endtoc-->
<h2 id="primary-setup">Primary setup</h2>
<h3 id="measure-startup-speed">Measure startup speed</h3>
<p>A small function to print out the loading time and number of GCs during the loading. Can be useful as a point of data for optimizing Emacs startup time.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;emacs-startup-hook</span>
(lambda ()
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">&#34;*** Emacs loaded in %s with %d garbage collections.&#34;</span>
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;%.2f seconds&#34;</span>
(<span style="color:#a6e22e">float-time</span>
(<span style="color:#a6e22e">time-subtract</span> after-init-time before-init-time)))
gcs-done)))
<span style="color:#75715e">;; (setq use-package-verbose t)</span>
</code></pre></div><h3 id="straight-dot-el">straight.el</h3>
<p>Straight.el is my Emacs package manager of choice. Its advantages &amp; disadvantages over other options are listed pretty thoroughly in the README file in the repo.</p>
<p>The following is a straight.el bootstrap script.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/raxod502/straight.el">straight.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defvar bootstrap-version)
(let ((bootstrap-file
(<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;straight/repos/straight.el/bootstrap.el&#34;</span> user-emacs-directory))
(bootstrap-version <span style="color:#ae81ff">5</span>))
(unless (<span style="color:#a6e22e">file-exists-p</span> bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
<span style="color:#e6db74">&#34;https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el&#34;</span>
<span style="color:#e6db74">&#39;silent</span> <span style="color:#e6db74">&#39;inhibit-cookies</span>)
(<span style="color:#a6e22e">goto-char</span> (<span style="color:#a6e22e">point-max</span>))
(eval-print-last-sexp)))
(<span style="color:#a6e22e">load</span> bootstrap-file <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#39;nomessage</span>))
</code></pre></div><h3 id="use-package">use-package</h3>
<p>A macro to simplify package specification &amp; configuration. Integrates with straight.el.</p>
<p>Set <code>use-package-verbose</code> to <code>t</code> to print out individual package loading time.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/jwiegley/use-package">use-package repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(straight-use-package <span style="color:#e6db74">&#39;use-package</span>)
(eval-when-compile (require <span style="color:#e6db74">&#39;use-package</span>))
<span style="color:#75715e">;; (setq use-package-verbose t)</span>
</code></pre></div><h3 id="config-variants-and-environment">config variants &amp; environment</h3>
<p>The following variable is true when my machine is not powerful enough for some resource-heavy packages.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/lowpower (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">&#34;azure&#34;</span>))
</code></pre></div><p>The following is true if Emacs is meant to be used with TRAMP over slow ssh.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/slow-ssh
(or
(string= (getenv <span style="color:#e6db74">&#34;IS_TRAMP&#34;</span>) <span style="color:#e6db74">&#34;true&#34;</span>)
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">&#34;dev-digital&#34;</span>)))
</code></pre></div><p>The following is true is Emacs is ran on a remote server where I don&rsquo;t need stuff like my org workflow</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/remote-server
(or (string= (getenv <span style="color:#e6db74">&#34;IS_REMOTE&#34;</span>) <span style="color:#e6db74">&#34;true&#34;</span>)
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">&#34;dev-digital&#34;</span>)))
</code></pre></div><p>And the following is true if Emacs is run from termux on Android.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/is-termux (string-match-p (rx (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">&#34;com.termux&#34;</span> (<span style="color:#a6e22e">*</span> nonl)) (getenv <span style="color:#e6db74">&#34;HOME&#34;</span>)))
</code></pre></div><p>Also, I sometimes need to know if a program is running inside Emacs (say, inside a terminal emulator). To do that, I set the following environment variable:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setenv <span style="color:#e6db74">&#34;IS_EMACS&#34;</span> <span style="color:#e6db74">&#34;true&#34;</span>)
</code></pre></div><p>Finally, I want to have a minimal Emacs config for debugging purposes. This has just straight.el, use-packages and evil.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;&lt;minimal&gt;&gt;
</code></pre></div><p>To launch Emacs with this config, run</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">emacs -q -l ~/.emacs.d/init-minimal.el
</code></pre></div><h3 id="performance">Performance</h3>
<h4 id="garbage-collection">Garbage collection</h4>
<p>Just setting <code>gc-cons-treshold</code> to a larger value.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq gc-cons-threshold <span style="color:#ae81ff">80000000</span>)
(setq read-process-output-max (<span style="color:#a6e22e">*</span> <span style="color:#ae81ff">1024</span> <span style="color:#ae81ff">1024</span>))
</code></pre></div><h4 id="run-garbage-collection-when-emacs-is-unfocused">Run garbage collection when Emacs is unfocused</h4>
<p>Run GC when Emacs loses focus. <del>Time will tell if that&rsquo;s a good idea.</del></p>
<p>Some time has passed, and I still don&rsquo;t know if there is any quantifiable advantage to this, but it doesn&rsquo;t hurt.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;emacs-startup-hook</span>
(lambda ()
(if (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;after-focus-change-function</span>)
(add-function :after after-focus-change-function
(lambda ()
(unless (frame-focus-state)
(<span style="color:#a6e22e">garbage-collect</span>))))
(add-hook <span style="color:#e6db74">&#39;after-focus-change-function</span> <span style="color:#e6db74">&#39;garbage-collect</span>))))
</code></pre></div><h4 id="native-compilation">Native compilation</h4>
<p>Set number of jobs to 1 on low-power machines</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(when my/lowpower
(setq comp-async-jobs-number <span style="color:#ae81ff">1</span>))
</code></pre></div><h3 id="anaconda">Anaconda</h3>
<p><a href="https://www.anaconda.com/">Anaconda</a> is a free package and environment manager. I currently use it to manage multiple versions of Python and Node.js</p>
<p>The following code uses the conda package to activate the base environment on startup if Emacs is launched outside the environment.</p>
<p>Also, some strange things are happening if vterm is launched with conda activated from Emacs, so I advise <code>conda-env-activate</code> to set an auxililary environment variable.</p>
<p>References:</p>
<ul>
<li><a href="https://docs.anaconda.com/">Anaconda docs</a></li>
<li><a href="https://github.com/necaris/conda.el">conda.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package conda
:straight <span style="color:#66d9ef">t</span>
:if (executable-find <span style="color:#e6db74">&#34;conda&#34;</span>)
:config
(setq conda-anaconda-home (string-replace <span style="color:#e6db74">&#34;/bin/conda&#34;</span> <span style="color:#e6db74">&#34;&#34;</span> (executable-find <span style="color:#e6db74">&#34;conda&#34;</span>)))
(setq conda-env-home-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~/.conda/&#34;</span>))
(setq conda-env-subdirectory <span style="color:#e6db74">&#34;envs&#34;</span>)
(setenv <span style="color:#e6db74">&#34;INIT_CONDA&#34;</span> <span style="color:#e6db74">&#34;true&#34;</span>)
(advice-add <span style="color:#e6db74">&#39;conda-env-activate</span> :after
(lambda (<span style="color:#66d9ef">&amp;rest</span> _) (setenv <span style="color:#e6db74">&#34;EMACS_CONDA_ENV&#34;</span> conda-env-current-name)))
(unless (getenv <span style="color:#e6db74">&#34;CONDA_DEFAULT_ENV&#34;</span>)
(conda-env-activate <span style="color:#e6db74">&#34;general&#34;</span>)))
</code></pre></div><h3 id="custom-file-location">Custom file location</h3>
<p>By default, custom writes stuff to <code>init.el</code>, which is somewhat annoying. The following makes a separate file <code>custom.el</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq custom-file (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">&#34;custom.el&#34;</span>))
(<span style="color:#a6e22e">load</span> custom-file <span style="color:#e6db74">&#39;noerror</span>)
</code></pre></div><h3 id="private-config">Private config</h3>
<p>I have some variables which I don&rsquo;t commit to the repo, e.g. my current location. They are stored in <code>private.el</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(let ((private-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;private.el&#34;</span> user-emacs-directory)))
(when (<span style="color:#a6e22e">file-exists-p</span> private-file)
(load-file private-file)))
</code></pre></div><h3 id="no-littering">No littering</h3>
<p>By default emacs and its packages create a lot files in <code>.emacs.d</code> and in other places. <a href="https://github.com/emacscollective/no-littering">no-littering</a> is a collective effort to redirect all of this to two folders in <code>user-emacs-directory</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package no-littering
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h3 id="prevent-emacs-from-closing">Prevent Emacs from closing</h3>
<p>This adds a confirmation to avoid accidental Emacs closing.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq confirm-kill-emacs <span style="color:#e6db74">&#39;y-or-n-p</span>)
</code></pre></div><h2 id="global-editing-configuration">Global editing configuration</h2>
<h3 id="general-keybindings-stuff">General keybindings stuff</h3>
<h4 id="general-dot-el">general.el</h4>
<p>general.el provides a convenient interface to manage Emacs keybindings.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/noctuid/general.el">general.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package general
:straight <span style="color:#66d9ef">t</span>
:config
(general-evil-setup))
</code></pre></div><h4 id="which-key">which-key</h4>
<p>A package that displays the available keybindings in a popup.</p>
<p>Pretty useful, as Emacs seems to have more keybindings than I can remember at any given point.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/justbur/emacs-which-key">which-key repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package which-key
:config
(setq which-key-idle-delay (if my/lowpower <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">0.3</span>))
(setq which-key-popup-type <span style="color:#e6db74">&#39;frame</span>)
(which-key-mode)
(which-key-setup-side-window-bottom)
(set-face-attribute <span style="color:#e6db74">&#39;which-key-local-map-description-face</span> <span style="color:#66d9ef">nil</span>
:weight <span style="color:#e6db74">&#39;bold</span>)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h5 id="dump-keybindings">dump keybindings</h5>
<p>A function to dump keybindings starting with a prefix to a buffer in tree-like form.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dump-bindings-recursive (prefix <span style="color:#66d9ef">&amp;optional</span> level)
(dolist (key (which-key--get-bindings (kbd prefix)))
(when level
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">make-string</span> level <span style="color:#e6db74">? </span>)))
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#&#39;format</span> <span style="color:#e6db74">&#34;%s%s%s\n&#34;</span> key))
(when (string-match-p
(rx bos <span style="color:#e6db74">&#34;+&#34;</span> (<span style="color:#a6e22e">*</span> nonl))
(<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">elt</span> key <span style="color:#ae81ff">2</span>)))
(my/dump-bindings-recursive
(<span style="color:#a6e22e">concat</span> prefix <span style="color:#e6db74">&#34; &#34;</span> (<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">car</span> key)))
(<span style="color:#a6e22e">+</span> <span style="color:#ae81ff">2</span> (or level <span style="color:#ae81ff">0</span>))))))
(defun my/dump-bindings (prefix)
<span style="color:#e6db74">&#34;Dump keybindings starting with PREFIX in tree-like form.&#34;</span>
(interactive <span style="color:#e6db74">&#34;sPrefix: &#34;</span>)
(with-current-buffer (<span style="color:#a6e22e">get-buffer-create</span> <span style="color:#e6db74">&#34;bindings&#34;</span>)
(<span style="color:#a6e22e">point-max</span>)
(<span style="color:#a6e22e">erase-buffer</span>)
(save-excursion
(my/dump-bindings-recursive prefix)))
(switch-to-buffer-other-window <span style="color:#e6db74">&#34;bindings&#34;</span>))
</code></pre></div><h3 id="evil-mode">Evil mode</h3>
<p>A whole ecosystem of packages that emulates the main features of Vim. Probably the best vim emulator out there.</p>
<p>The only problem is that the package name makes it hard to google anything by just typing &ldquo;evil&rdquo;.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/emacs-evil/evil">evil repo</a></li>
<li><a href="https://www.youtube.com/watch?v=JWD1Fpdd4Pc">(YouTube) Evil Mode: Or, How I Learned to Stop Worrying and Love Emacs</a></li>
</ul>
<h4 id="evil">evil</h4>
<p>Basic evil configuration.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil
:straight <span style="color:#66d9ef">t</span>
:init
(setq evil-want-integration <span style="color:#66d9ef">t</span>)
(setq evil-want-C-u-scroll <span style="color:#66d9ef">t</span>)
(setq evil-want-keybinding <span style="color:#66d9ef">nil</span>)
:config
(evil-mode <span style="color:#ae81ff">1</span>)
(setq evil-search-module <span style="color:#e6db74">&#39;evil-search</span>)
(setq evil-split-window-below <span style="color:#66d9ef">t</span>)
(setq evil-vsplit-window-right <span style="color:#66d9ef">t</span>)
<span style="color:#75715e">;; (setq evil-respect-visual-line-mode t)</span>
(evil-set-undo-system <span style="color:#e6db74">&#39;undo-tree</span>)
<span style="color:#75715e">;; (add-to-list &#39;evil-emacs-state-modes &#39;dired-mode)</span>
)
</code></pre></div><h4 id="addons">Addons</h4>
<p><a href="https://github.com/emacs-evil/evil-surround">evil-surround</a> emulates one of my favorite vim plugins, surround.vim. Adds a lot of parentheses management options.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-surround
:straight <span style="color:#66d9ef">t</span>
:after evil
:config
(global-evil-surround-mode <span style="color:#ae81ff">1</span>))
</code></pre></div><p><a href="https://github.com/linktohack/evil-commentary">evil-commentary</a> emulates commentary.vim.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-commentary
:straight <span style="color:#66d9ef">t</span>
:after evil
:config
(evil-commentary-mode))
</code></pre></div><p><a href="https://github.com/blorbx/evil-quickscope">evil-quickscope</a> emulates quickscope.vim. It highlights the important target characters for f, F, t, T keys.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-quickscope
:straight <span style="color:#66d9ef">t</span>
:after evil
:config
:hook ((prog-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
(LaTeX-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
(org-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)))
</code></pre></div><p><a href="https://github.com/cofi/evil-numbers">evil-numbers</a> allows incrementing and decrementing numbers at the point.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-numbers
:straight <span style="color:#66d9ef">t</span>
:commands (evil-numbers/inc-at-pt evil-numbers/dec-at-pt)
:init
(general-nmap
<span style="color:#e6db74">&#34;g+&#34;</span> <span style="color:#e6db74">&#39;evil-numbers/inc-at-pt</span>
<span style="color:#e6db74">&#34;g-&#34;</span> <span style="color:#e6db74">&#39;evil-numbers/dec-at-pt</span>))
</code></pre></div><p><a href="https://github.com/edkolev/evil-lion">evil-lion</a> provides alignment operators, somewhat similar to vim-easyalign.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-lion
:straight <span style="color:#66d9ef">t</span>
:config
(setq evil-lion-left-align-key (kbd <span style="color:#e6db74">&#34;g a&#34;</span>))
(setq evil-lion-right-align-key (kbd <span style="color:#e6db74">&#34;g A&#34;</span>))
(evil-lion-mode))
</code></pre></div><p><a href="https://github.com/redguardtoo/evil-matchit">evil-matchit</a> makes &ldquo;%&rdquo; to match things like tags.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-matchit
:straight <span style="color:#66d9ef">t</span>
:config
(global-evil-matchit-mode <span style="color:#ae81ff">1</span>))
</code></pre></div><h4 id="evil-collection">evil-collection</h4>
<p><a href="https://github.com/emacs-evil/evil-collection">evil-collection</a> is a package that provides evil bindings for a lot of different packages. One can see the whole list in the <a href="https://github.com/emacs-evil/evil-collection/tree/master/modes">modes</a> folder.</p>
<p>I don&rsquo;t enable the entire package, just the modes I need.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-collection
:straight <span style="color:#66d9ef">t</span>
:after evil
:config
(evil-collection-init
<span style="color:#f92672">&#39;</span>(eww
devdocs
proced
emms
pass
calendar
dired
debug
guix
calc
docker
ibuffer
geiser
pdf
info
elfeed
edebug
bookmark
company
vterm
flycheck
profiler
cider
explain-pause-mode
notmuch
custom
xref
eshell
helpful
compile
comint
git-timemachine
magit
prodigy
slime)))
</code></pre></div><h3 id="more-keybindings">More keybindings</h3>
<p>The main keybindings setup is positioned after evil mode to take the latter into account.</p>
<h4 id="escape-key">Escape key</h4>
<p>Use the escape key instead of <code>C-g</code> whenever possible.</p>
<p>I must have copied it from somewhere, but as I googled to find out the source, I discovered quite a number of variations of the following code over time. I wonder if Richard Dawkins was inspired by something like this a few decades ago.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun minibuffer-keyboard-quit ()
<span style="color:#e6db74">&#34;Abort recursive edit.
</span><span style="color:#e6db74">In Delete Selection mode, if the mark is active, just deactivate it;
</span><span style="color:#e6db74">then it takes a second \\[keyboard-quit] to abort the minibuffer.&#34;</span>
(interactive)
(if (and delete-selection-mode transient-mark-mode mark-active)
(setq deactivate-mark <span style="color:#66d9ef">t</span>)
(when (<span style="color:#a6e22e">get-buffer</span> <span style="color:#e6db74">&#34;*Completions*&#34;</span>) (delete-windows-on <span style="color:#e6db74">&#34;*Completions*&#34;</span>))
(<span style="color:#a6e22e">abort-recursive-edit</span>)))
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(normal visual global)
[escape] <span style="color:#e6db74">&#39;keyboard-quit</span>)
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(minibuffer-local-map
minibuffer-local-ns-map
minibuffer-local-completion-map
minibuffer-local-must-match-map
minibuffer-local-isearch-map)
[escape] <span style="color:#e6db74">&#39;minibuffer-keyboard-quit</span>)
</code></pre></div><h4 id="home-and-end">Home &amp; end</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-def :states <span style="color:#f92672">&#39;</span>(normal <span style="color:#a6e22e">insert</span> visual)
<span style="color:#e6db74">&#34;&lt;home&gt;&#34;</span> <span style="color:#e6db74">&#39;beginning-of-line</span>
<span style="color:#e6db74">&#34;&lt;end&gt;&#34;</span> <span style="color:#e6db74">&#39;end-of-line</span>)
</code></pre></div><h4 id="my-leader">My leader</h4>
<p>Using the <code>SPC</code> key as a leader key, like in Doom Emacs or Spacemacs.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-create-definer my-leader-def
:keymaps <span style="color:#e6db74">&#39;override</span>
:prefix <span style="color:#e6db74">&#34;SPC&#34;</span>
:states <span style="color:#f92672">&#39;</span>(normal motion emacs))
(general-def :states <span style="color:#f92672">&#39;</span>(normal motion emacs) <span style="color:#e6db74">&#34;SPC&#34;</span> <span style="color:#66d9ef">nil</span>)
(my-leader-def <span style="color:#e6db74">&#34;?&#34;</span> <span style="color:#e6db74">&#39;which-key-show-top-level</span>)
(my-leader-def <span style="color:#e6db74">&#34;E&#34;</span> <span style="color:#e6db74">&#39;eval-expression</span>)
</code></pre></div><p><code>general.el</code> has a nice integration with which-key, so I use this fact to show more descriptive annotations for certain groups of keybindings (the default one is <code>prefix</code>).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;apps&#34;</span>))
</code></pre></div><h4 id="universal-argument">Universal argument</h4>
<p>Change the universal argument to <code>M-u</code>. I use <code>C-u</code> to scroll up, as I&rsquo;m used to from vim.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-def
:keymaps <span style="color:#e6db74">&#39;universal-argument-map</span>
<span style="color:#e6db74">&#34;M-u&#34;</span> <span style="color:#e6db74">&#39;universal-argument-more</span>)
(general-def
:keymaps <span style="color:#e6db74">&#39;override</span>
:states <span style="color:#f92672">&#39;</span>(normal motion emacs <span style="color:#a6e22e">insert</span> visual)
<span style="color:#e6db74">&#34;M-u&#34;</span> <span style="color:#e6db74">&#39;universal-argument</span>)
</code></pre></div><h4 id="profiler">Profiler</h4>
<p>The built-in profiler is a magnificent tool to troubleshoot performance issues.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;P&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;profiler&#34;</span>)
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;profiler-start</span>
<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#39;profiler-stop</span>
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#39;profiler-report</span>)
</code></pre></div><h4 id="buffer-switching">Buffer switching</h4>
<p>Some keybindings I used in vim to switch buffers and can&rsquo;t let go of.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-define-key
:keymaps <span style="color:#e6db74">&#39;override</span>
<span style="color:#e6db74">&#34;C-&lt;right&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-right</span>
<span style="color:#e6db74">&#34;C-&lt;left&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-left</span>
<span style="color:#e6db74">&#34;C-&lt;up&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-up</span>
<span style="color:#e6db74">&#34;C-&lt;down&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-down</span>
<span style="color:#e6db74">&#34;C-h&#34;</span> <span style="color:#e6db74">&#39;evil-window-left</span>
<span style="color:#e6db74">&#34;C-l&#34;</span> <span style="color:#e6db74">&#39;evil-window-right</span>
<span style="color:#e6db74">&#34;C-k&#34;</span> <span style="color:#e6db74">&#39;evil-window-up</span>
<span style="color:#e6db74">&#34;C-j&#34;</span> <span style="color:#e6db74">&#39;evil-window-down</span>
<span style="color:#e6db74">&#34;C-x h&#34;</span> <span style="color:#e6db74">&#39;previous-buffer</span>
<span style="color:#e6db74">&#34;C-x l&#34;</span> <span style="color:#e6db74">&#39;next-buffer</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;evil-window-map</span>
<span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#e6db74">&#39;kill-buffer-and-window</span>
<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#39;kill-current-buffer</span>)
</code></pre></div><p>And winner-mode to keep the history of window states.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(winner-mode <span style="color:#ae81ff">1</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;evil-window-map</span>
<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;winner-undo</span>
<span style="color:#e6db74">&#34;U&#34;</span> <span style="color:#e6db74">&#39;winner-redo</span>)
</code></pre></div><h4 id="buffer-management">Buffer management</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;b&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;buffers&#34;</span>)
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#f92672">&#39;</span>((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
:which-key <span style="color:#e6db74">&#34;*scratch*&#34;</span>)
<span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#f92672">&#39;</span>((lambda () (interactive) (persp-switch-to-buffer <span style="color:#e6db74">&#34;*Messages*&#34;</span>))
:which-key <span style="color:#e6db74">&#34;*Messages*&#34;</span>)
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;next-buffer</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;previous-buffer</span>
<span style="color:#e6db74">&#34;k&#34;</span> <span style="color:#e6db74">&#39;kill-buffer</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;persp-ivy-switch-buffer</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;revert-buffer</span>
<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;ibuffer</span>)
</code></pre></div><h4 id="xref">xref</h4>
<p>Some keybindings for xref and go to definition.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-nmap
<span style="color:#e6db74">&#34;gD&#34;</span> <span style="color:#e6db74">&#39;xref-find-definitions-other-window</span>
<span style="color:#e6db74">&#34;gr&#34;</span> <span style="color:#e6db74">&#39;xref-find-references</span>
<span style="color:#e6db74">&#34;gd&#34;</span> <span style="color:#e6db74">&#39;evil-goto-definition</span>)
(my-leader-def
<span style="color:#e6db74">&#34;fx&#34;</span> <span style="color:#e6db74">&#39;xref-find-apropos</span>)
</code></pre></div><h4 id="folding">Folding</h4>
<p>There are multiple ways to fold text in Emacs.</p>
<p>The most versatile is the built-in <code>hs-minor-mode</code>, which seems to work out of the box for Lisps, C-like languages and Python. <code>outline-minor-mode</code> works for org-mode, LaTeX and the like. There is a 3rd-party solution <a href="https://github.com/elp-revive/origami.el">origami.el</a>, but I don&rsquo;t use it at the moment.</p>
<p>Evil does a pretty good job of uniting these two in the set of vim-like keybindings. I was using <code>SPC</code> in vim, but as now this isn&rsquo;t an option, I set <code>TAB</code> to toggle folding.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-nmap :keymaps <span style="color:#f92672">&#39;</span>(hs-minor-mode-map outline-minor-mode-map)
<span style="color:#e6db74">&#34;ze&#34;</span> <span style="color:#e6db74">&#39;hs-hide-level</span>
<span style="color:#e6db74">&#34;TAB&#34;</span> <span style="color:#e6db74">&#39;evil-toggle-fold</span>)
</code></pre></div><h4 id="zoom">Zoom</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/zoom-in ()
<span style="color:#e6db74">&#34;Increase font size by 10 points&#34;</span>
(interactive)
(set-face-attribute <span style="color:#e6db74">&#39;default</span> <span style="color:#66d9ef">nil</span>
:height
(<span style="color:#a6e22e">+</span> (face-attribute <span style="color:#e6db74">&#39;default</span> :height) <span style="color:#ae81ff">10</span>)))
(defun my/zoom-out ()
<span style="color:#e6db74">&#34;Decrease font size by 10 points&#34;</span>
(interactive)
(set-face-attribute <span style="color:#e6db74">&#39;default</span> <span style="color:#66d9ef">nil</span>
:height
(<span style="color:#a6e22e">-</span> (face-attribute <span style="color:#e6db74">&#39;default</span> :height) <span style="color:#ae81ff">10</span>)))
<span style="color:#75715e">;; change font size, interactively</span>
(global-set-key (kbd <span style="color:#e6db74">&#34;C-+&#34;</span>) <span style="color:#e6db74">&#39;my/zoom-in</span>)
(global-set-key (kbd <span style="color:#e6db74">&#34;C-=&#34;</span>) <span style="color:#e6db74">&#39;my/zoom-out</span>)
</code></pre></div><h3 id="editing-helpers">Editing helpers</h3>
<h4 id="visual-fill-column-mode">Visual fill column mode</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package visual-fill-column
:straight <span style="color:#66d9ef">t</span>
:config
(add-hook <span style="color:#e6db74">&#39;visual-fill-column-mode-hook</span>
(lambda () (setq visual-fill-column-center-text <span style="color:#66d9ef">t</span>))))
</code></pre></div><h4 id="smartparens">smartparens</h4>
<p>A minor mode to deal with pairs. Its functionality overlaps with evil-surround, but smartparens provides the most comfortable way to do stuff like automatically insert pairs.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/Fuco1/smartparens">smartparens repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package smartparens
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="aggressive-indent">Aggressive Indent</h4>
<p>A package to keep the code intended.</p>
<p>Doesn&rsquo;t work too well with js ecosystem, because the LSP-based indentation is rather slow but nice for Lisps.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/Malabarba/aggressive-indent-mode">aggressive-indent-mode repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package aggressive-indent
:commands (aggressive-indent-mode)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="delete-trailing-whitespace">Delete trailing whitespace</h4>
<p>Delete trailing whitespace on save, unless in particular modes where trailing whitespace is important, like Markdown.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/trailing-whitespace-modes <span style="color:#f92672">&#39;</span>(markdown-mode))
(require <span style="color:#e6db74">&#39;cl-extra</span>)
(add-hook <span style="color:#e6db74">&#39;before-save-hook</span>
(lambda ()
(unless (cl-some <span style="color:#a6e22e">#&#39;</span>derived-mode-p my/trailing-whitespace-modes)
(delete-trailing-whitespace))))
</code></pre></div><h4 id="expand-region">Expand region</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package expand-region
:straight <span style="color:#66d9ef">t</span>
:commands (er/expand-region)
:init
(general-nmap <span style="color:#e6db74">&#34;+&#34;</span> <span style="color:#e6db74">&#39;er/expand-region</span>))
</code></pre></div><h3 id="various-settings">Various settings</h3>
<h4 id="tabs">Tabs</h4>
<p>Some default settings to manage tabs.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq tab-always-indent <span style="color:#66d9ef">nil</span>)
(setq-default default-tab-width <span style="color:#ae81ff">4</span>)
(setq-default tab-width <span style="color:#ae81ff">4</span>)
(setq-default evil-indent-convert-tabs <span style="color:#66d9ef">nil</span>)
(setq-default indent-tabs-mode <span style="color:#66d9ef">nil</span>)
(setq-default tab-width <span style="color:#ae81ff">4</span>)
(setq-default evil-shift-round <span style="color:#66d9ef">nil</span>)
</code></pre></div><h4 id="scrolling-config">Scrolling config</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq scroll-conservatively scroll-margin)
(setq scroll-step <span style="color:#ae81ff">1</span>)
(setq scroll-preserve-screen-position <span style="color:#66d9ef">t</span>)
(setq scroll-error-top-bottom <span style="color:#66d9ef">t</span>)
(setq mouse-wheel-progressive-speed <span style="color:#66d9ef">nil</span>)
(setq mouse-wheel-inhibit-click-time <span style="color:#66d9ef">nil</span>)
</code></pre></div><h4 id="clipboard">Clipboard</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq select-enable-clipboard <span style="color:#66d9ef">t</span>)
(setq mouse-yank-at-point <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="backups">Backups</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq backup-inhibited <span style="color:#66d9ef">t</span>)
(setq auto-save-default <span style="color:#66d9ef">nil</span>)
</code></pre></div><h3 id="undo-tree">Undo Tree</h3>
<p>Replaces Emacs build-in sequential undo system with a tree-based one. Probably one of the greatest features of Emacs as a text editor.</p>
<p>References:</p>
<ul>
<li><a href="https://www.emacswiki.org/emacs/UndoTree">UndoTree on EmacsWiki</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package undo-tree
:straight <span style="color:#66d9ef">t</span>
:config
(global-undo-tree-mode)
(setq undo-tree-visualizer-diff <span style="color:#66d9ef">t</span>)
(setq undo-tree-visualizer-timestamps <span style="color:#66d9ef">t</span>)
(my-leader-def <span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;undo-tree-visualize</span>)
(<span style="color:#a6e22e">fset</span> <span style="color:#e6db74">&#39;undo-auto-amalgamate</span> <span style="color:#e6db74">&#39;ignore</span>)
(setq undo-limit <span style="color:#ae81ff">6710886400</span>)
(setq undo-strong-limit <span style="color:#ae81ff">100663296</span>)
(setq undo-outer-limit <span style="color:#ae81ff">1006632960</span>))
</code></pre></div><h3 id="help">Help</h3>
<p><a href="https://github.com/Wilfred/helpful">helpful</a> package improves the <code>*help*</code> buffer.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package helpful
:straight <span style="color:#66d9ef">t</span>
:commands (helpful-callable
helpful-variable
helpful-key
helpful-macro
helpful-function
helpful-command))
</code></pre></div><p>As I use <code>C-h</code> to switch buffers, I moved the help to <code>SPC-h</code> with the code below. Of course, I didn&rsquo;t type it all by hand.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;h&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;help&#34;</span>)
<span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;view-order-manuals</span>
<span style="color:#e6db74">&#34;.&#34;</span> <span style="color:#e6db74">&#39;display-local-help</span>
<span style="color:#e6db74">&#34;?&#34;</span> <span style="color:#e6db74">&#39;help-for-help</span>
<span style="color:#e6db74">&#34;C&#34;</span> <span style="color:#e6db74">&#39;describe-coding-system</span>
<span style="color:#e6db74">&#34;F&#34;</span> <span style="color:#e6db74">&#39;Info-goto-emacs-command-node</span>
<span style="color:#e6db74">&#34;I&#34;</span> <span style="color:#e6db74">&#39;describe-input-method</span>
<span style="color:#e6db74">&#34;K&#34;</span> <span style="color:#e6db74">&#39;Info-goto-emacs-key-command-node</span>
<span style="color:#e6db74">&#34;L&#34;</span> <span style="color:#e6db74">&#39;describe-language-environment</span>
<span style="color:#e6db74">&#34;P&#34;</span> <span style="color:#e6db74">&#39;describe-package</span>
<span style="color:#e6db74">&#34;S&#34;</span> <span style="color:#e6db74">&#39;info-lookup-symbol</span>
<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#e6db74">&#39;helm-apropos</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;describe-bindings</span>
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;describe-key-briefly</span>
<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#39;apropos-documentation</span>
<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#39;view-echo-area-messages</span>
<span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#e6db74">&#39;helpful-function</span>
<span style="color:#e6db74">&#34;g&#34;</span> <span style="color:#e6db74">&#39;describe-gnu-project</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;view-hello-file</span>
<span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#e6db74">&#39;info</span>
<span style="color:#e6db74">&#34;k&#34;</span> <span style="color:#e6db74">&#39;helpful-key</span>
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;view-lossage</span>
<span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#e6db74">&#39;describe-mode</span>
<span style="color:#e6db74">&#34;n&#34;</span> <span style="color:#e6db74">&#39;view-emacs-news</span>
<span style="color:#e6db74">&#34;o&#34;</span> <span style="color:#e6db74">&#39;describe-symbol</span>
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#39;finder-by-keyword</span>
<span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#39;help-quit</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;info-emacs-manual</span>
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;describe-syntax</span>
<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#39;help-with-tutorial</span>
<span style="color:#e6db74">&#34;v&#34;</span> <span style="color:#e6db74">&#39;helpful-variable</span>
<span style="color:#e6db74">&#34;w&#34;</span> <span style="color:#e6db74">&#39;where-is</span>
<span style="color:#e6db74">&#34;&lt;f1&gt;&#34;</span> <span style="color:#e6db74">&#39;help-for-help</span>)
</code></pre></div><h3 id="ivy-counsel-swiper">Ivy, counsel, swiper</h3>
<p>Minibuffer completion tools for Emacs.</p>
<p>References:</p>
<ul>
<li><a href="https://oremacs.com/swiper/">repo</a></li>
<li><a href="https://oremacs.com/swiper/">User Manual</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy
:straight <span style="color:#66d9ef">t</span>
:config
(setq ivy-use-virtual-buffers <span style="color:#66d9ef">t</span>)
(ivy-mode))
(use-package counsel
:straight <span style="color:#66d9ef">t</span>
:after ivy
:config
(counsel-mode))
(use-package swiper
:defer <span style="color:#66d9ef">t</span>
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="ivy-rich">ivy-rich</h4>
<p><a href="https://github.com/Yevgnen/ivy-rich">ivy-rich</a> provides a more informative interface for ivy.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy-rich
:straight <span style="color:#66d9ef">t</span>
:after ivy
:config
(ivy-rich-mode <span style="color:#ae81ff">1</span>)
(<span style="color:#a6e22e">setcdr</span> (<span style="color:#a6e22e">assq</span> <span style="color:#66d9ef">t</span> ivy-format-functions-alist) <span style="color:#a6e22e">#&#39;</span>ivy-format-function-line))
</code></pre></div><h4 id="prescient">prescient</h4>
<p>A package that enhances sorting &amp; filtering of candidates. <code>ivy-prescient</code> adds integration with Ivy.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/raxod502/prescient.el">prescient.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy-prescient
:straight <span style="color:#66d9ef">t</span>
:after counsel
:config
(ivy-prescient-mode <span style="color:#ae81ff">+1</span>)
(setq ivy-prescient-retain-classic-highlighting <span style="color:#66d9ef">t</span>)
(prescient-persist-mode <span style="color:#ae81ff">1</span>)
(setq ivy-prescient-sort-commands
<span style="color:#f92672">&#39;</span>(:not swiper
swiper-isearch
ivy-switch-buffer
<span style="color:#75715e">;; ivy-resume</span>
<span style="color:#75715e">;; ivy--restore-session</span>
lsp-ivy-workspace-symbol
counsel-grep
<span style="color:#75715e">;; counsel-find-file</span>
counsel-git-grep
counsel-rg
counsel-ag
counsel-ack
counsel-fzf
counsel-pt
counsel-imenu
counsel-yank-pop
counsel-recentf
counsel-buffer-or-recentf
proced-filter-interactive
proced-sort-interactive))
<span style="color:#75715e">;; Do not use prescient in find-file</span>
(ivy--alist-set <span style="color:#e6db74">&#39;ivy-sort-functions-alist</span> <span style="color:#a6e22e">#&#39;</span>read-file-name-internal <span style="color:#a6e22e">#&#39;</span>ivy-sort-file-function-default))
</code></pre></div><h4 id="keybindings">Keybindings</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;f&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;various completions&#34;</span>)<span style="color:#f92672">&#39;</span>
<span style="color:#75715e">;; &#34;b&#34; &#39;counsel-switch-buffer</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;persp-ivy-switch-buffer</span>
<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#39;conda-env-activate</span>
<span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#e6db74">&#39;project-find-file</span>
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;counsel-yank-pop</span>
<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#e6db74">&#39;counsel-rg</span>
<span style="color:#e6db74">&#34;A&#34;</span> <span style="color:#e6db74">&#39;counsel-ag</span>)
(general-define-key
:states <span style="color:#f92672">&#39;</span>(<span style="color:#a6e22e">insert</span> normal)
<span style="color:#e6db74">&#34;C-y&#34;</span> <span style="color:#e6db74">&#39;counsel-yank-pop</span>)
(my-leader-def <span style="color:#e6db74">&#34;SPC&#34;</span> <span style="color:#e6db74">&#39;ivy-resume</span>)
(my-leader-def <span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;swiper-isearch</span>
<span style="color:#e6db74">&#34;S&#34;</span> <span style="color:#e6db74">&#39;swiper-all</span>)
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(ivy-minibuffer-map swiper-map)
<span style="color:#e6db74">&#34;M-j&#34;</span> <span style="color:#e6db74">&#39;ivy-next-line</span>
<span style="color:#e6db74">&#34;M-k&#34;</span> <span style="color:#e6db74">&#39;ivy-previous-line</span>
<span style="color:#e6db74">&#34;&lt;C-return&gt;&#34;</span> <span style="color:#e6db74">&#39;ivy-call</span>
<span style="color:#e6db74">&#34;M-RET&#34;</span> <span style="color:#e6db74">&#39;ivy-immediate-done</span>
[escape] <span style="color:#e6db74">&#39;minibuffer-keyboard-quit</span>)
</code></pre></div><h3 id="off--helm"><span class="org-todo done OFF">OFF</span> (OFF) Helm</h3>
<p>Config for the Helm incremental completion framework. I switched to Ivy some time ago, but keep the configuration just in case.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package helm
:init
(require <span style="color:#e6db74">&#39;helm-config</span>)
(setq helm-split-window-in-side-p <span style="color:#66d9ef">t</span>)
(setq helm-move-to-line-cycle-in-source <span style="color:#66d9ef">t</span>)
:straight <span style="color:#66d9ef">t</span>
:config
(helm-mode <span style="color:#ae81ff">1</span>)
(helm-autoresize-mode <span style="color:#ae81ff">1</span>))
(use-package helm-ag
:straight <span style="color:#66d9ef">t</span>)
(use-package helm-rg
:straight <span style="color:#66d9ef">t</span>)
(general-nmap
:keymaps <span style="color:#e6db74">&#39;helm-ag-mode-map</span>
<span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;helm-ag-mode-jump</span>
<span style="color:#e6db74">&#34;M-RET&#34;</span> <span style="color:#e6db74">&#39;helm-ag-mode-jump-other-window</span>)
(general-nmap
:keymaps <span style="color:#e6db74">&#39;helm-occur-mode-map</span>
<span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;helm-occur-mode-goto-line</span>
<span style="color:#e6db74">&#34;M-RET&#34;</span> <span style="color:#e6db74">&#39;helm-occur-mode-goto-line-ow</span>)
(general-define-key <span style="color:#e6db74">&#34;M-x&#34;</span> <span style="color:#e6db74">&#39;helm-M-x</span>)
(my-leader-def
<span style="color:#e6db74">&#34;fb&#34;</span> <span style="color:#e6db74">&#39;helm-buffers-list</span>
<span style="color:#e6db74">&#34;fs&#34;</span> <span style="color:#e6db74">&#39;helm-lsp-workspace-symbol</span>
<span style="color:#e6db74">&#34;fw&#34;</span> <span style="color:#e6db74">&#39;helm-lsp-global-workspace-symbol</span>
<span style="color:#e6db74">&#34;fc&#34;</span> <span style="color:#e6db74">&#39;helm-show-kill-ring</span>
<span style="color:#75715e">;; &#34;fa&#34; &#39;helm-do-ag-project-root</span>
<span style="color:#e6db74">&#34;fm&#34;</span> <span style="color:#e6db74">&#39;helm-bookmarks</span>
<span style="color:#e6db74">&#34;ff&#34;</span> <span style="color:#e6db74">&#39;project-find-file</span>
<span style="color:#e6db74">&#34;fe&#34;</span> <span style="color:#e6db74">&#39;conda-env-activate</span>)
(my-leader-def <span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;helm-occur</span>)
(my-leader-def <span style="color:#e6db74">&#34;SPC&#34;</span> <span style="color:#e6db74">&#39;helm-resume</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;helm-map</span>
<span style="color:#e6db74">&#34;C-j&#34;</span> <span style="color:#e6db74">&#39;helm-next-line</span>
<span style="color:#e6db74">&#34;C-k&#34;</span> <span style="color:#e6db74">&#39;helm-previous-line</span>)
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(helm-find-files-map helm-locate-map)
<span style="color:#e6db74">&#34;C-h&#34;</span> <span style="color:#e6db74">&#39;helm-find-files-up-one-level</span>
<span style="color:#e6db74">&#34;C-l&#34;</span> <span style="color:#e6db74">&#39;helm-execute-persistent-action</span>)
(general-imap
<span style="color:#e6db74">&#34;C-y&#34;</span> <span style="color:#e6db74">&#39;helm-show-kill-ring</span>)
<span style="color:#75715e">;; (general-nmap &#34;C-p&#34; &#39;project-find-file)</span>
</code></pre></div><h3 id="treemacs">Treemacs</h3>
<p><a href="https://github.com/Alexander-Miller/treemacs">Treemacs</a> calls itself a tree layout file explorer, but looks more like a project and workspace management system.</p>
<p>Integrates with evil, magit, projectile and perspective. The latter is particularly great - each perspective can have its own treemacs workspace!</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package treemacs
:straight <span style="color:#66d9ef">t</span>
:commands (treemacs treemacs-switch-workspace treemacs-edit-workspace)
:config
(setq treemacs-follow-mode <span style="color:#66d9ef">nil</span>)
(setq treemacs-follow-after-init <span style="color:#66d9ef">nil</span>)
(setq treemacs-space-between-root-nodes <span style="color:#66d9ef">nil</span>)
(treemacs-git-mode <span style="color:#e6db74">&#39;extended</span>)
(add-to-list <span style="color:#e6db74">&#39;treemacs-pre-file-insert-predicates</span> <span style="color:#a6e22e">#&#39;</span>treemacs-is-file-git-ignored?)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;treemacs-mode-map</span>
[mouse-1] <span style="color:#a6e22e">#&#39;</span>treemacs-single-click-expand-action
<span style="color:#e6db74">&#34;M-l&#34;</span> <span style="color:#a6e22e">#&#39;</span>treemacs-root-down
<span style="color:#e6db74">&#34;M-h&#34;</span> <span style="color:#a6e22e">#&#39;</span>treemacs-root-up))
(use-package treemacs-evil
:after (treemacs evil)
:straight <span style="color:#66d9ef">t</span>)
(use-package treemacs-magit
:after (treemacs magit)
:straight <span style="color:#66d9ef">t</span>)
(use-package treemacs-perspective
:after (treemacs perspective)
:straight <span style="color:#66d9ef">t</span>
:config
(treemacs-set-scope-type <span style="color:#e6db74">&#39;Perspectives</span>))
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(normal override global)
<span style="color:#e6db74">&#34;C-n&#34;</span> <span style="color:#e6db74">&#39;treemacs</span>)
(general-define-key
:keymaps <span style="color:#f92672">&#39;</span>(treemacs-mode-map) [mouse-1] <span style="color:#a6e22e">#&#39;</span>treemacs-single-click-expand-action)
(my-leader-def
:infix <span style="color:#e6db74">&#34;t&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;treemacs&#34;</span>)
<span style="color:#e6db74">&#34;w&#34;</span> <span style="color:#e6db74">&#39;treemacs-switch-workspace</span>
<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#39;treemacs-edit-workspaces</span>)
</code></pre></div><h4 id="helper-functions">Helper functions</h4>
<p>Function to open dired and vterm at given nodes.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/treemacs-open-dired ()
<span style="color:#e6db74">&#34;Open dired at given treemacs node&#34;</span>
(interactive)
(let (path (treemacs--prop-at-point :path))
(dired path)))
(defun my/treemacs-open-vterm ()
<span style="color:#e6db74">&#34;Open vterm at given treemacs node&#34;</span>
(interactive)
(let ((default-directory (<span style="color:#a6e22e">file-name-directory</span> (treemacs--prop-at-point :path))))
(vterm)))
(with-eval-after-load <span style="color:#e6db74">&#39;treemacs</span>
(general-define-key
:keymaps <span style="color:#e6db74">&#39;treemacs-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(treemacs)
<span style="color:#e6db74">&#34;gd&#34;</span> <span style="color:#e6db74">&#39;my/treemacs-open-dired</span>
<span style="color:#e6db74">&#34;gt&#34;</span> <span style="color:#e6db74">&#39;my/treemacs-open-vterm</span>
<span style="color:#e6db74">&#34;`&#34;</span> <span style="color:#e6db74">&#39;my/treemacs-open-vterm</span>))
</code></pre></div><h4 id="custom-icons">Custom icons</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (treemacs-define-custom-icon (concat &#34; &#34; (all-the-icons-fileicon &#34;typescript&#34;)) &#34;spec.ts&#34;)</span>
<span style="color:#75715e">;; (setq treemacs-file-extension-regex (rx &#34;.&#34; (or &#34;spec.ts&#34; (+ (not &#34;.&#34;))) eos))</span>
</code></pre></div><h3 id="projectile">Projectile</h3>
<p><a href="https://github.com/bbatsov/projectile">Projectile</a> gives a bunch of useful functions for managing projects, like finding files within a project, fuzzy-find, replace, etc.</p>
<p><code>defadvice</code> is meant to speed projectile up with TRAMP a bit.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package projectile
:straight <span style="color:#66d9ef">t</span>
:config
(projectile-mode <span style="color:#ae81ff">+1</span>)
(setq projectile-project-search-path <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;~/Code&#34;</span> <span style="color:#e6db74">&#34;~/Documents&#34;</span>))
(defadvice projectile-project-root (around ignore-remote first activate)
(unless (file-remote-p default-directory) ad-do-it)))
(use-package counsel-projectile
:after (counsel projectile)
:straight <span style="color:#66d9ef">t</span>)
(use-package treemacs-projectile
:after (treemacs projectile)
:straight <span style="color:#66d9ef">t</span>)
(my-leader-def
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#f92672">&#39;</span>(:keymap projectile-command-map :which-key <span style="color:#e6db74">&#34;projectile&#34;</span>))
(general-nmap <span style="color:#e6db74">&#34;C-p&#34;</span> <span style="color:#e6db74">&#39;counsel-projectile-find-file</span>)
</code></pre></div><h3 id="company">Company</h3>
<p>A completion framework for Emacs.</p>
<p>References:</p>
<ul>
<li><a href="http://company-mode.github.io/">company homepage</a></li>
<li><a href="https://github.com/sebastiencs/company-box">company-box homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package company
:straight <span style="color:#66d9ef">t</span>
:config
(global-company-mode)
(setq company-idle-delay (if my/lowpower <span style="color:#ae81ff">0.5</span> <span style="color:#ae81ff">0.125</span>))
(setq company-dabbrev-downcase <span style="color:#66d9ef">nil</span>)
(setq company-show-numbers <span style="color:#66d9ef">t</span>))
(general-imap <span style="color:#e6db74">&#34;C-SPC&#34;</span> <span style="color:#e6db74">&#39;company-complete</span>)
</code></pre></div><p>A company frontend with nice icons.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package company-box
:straight <span style="color:#66d9ef">t</span>
:if (and (display-graphic-p) (not my/lowpower))
:after (company)
:hook (company-mode <span style="color:#f92672">.</span> company-box-mode))
</code></pre></div><h3 id="git-and-magit">Git &amp; Magit</h3>
<p><a href="https://magit.vc/">Magic</a> is a git interface for Emacs. The closest non-Emacs alternative (sans actual clones) I know is <a href="https://github.com/jesseduffield/lazygit">lazygit</a>, which I used before Emacs.</p>
<p><a href="https://github.com/emacsorphanage/git-gutter">git-gutter</a> is a package which shows git changes for each line (added/changed/deleted lines).</p>
<p><a href="https://github.com/emacsmirror/git-timemachine">git-timemachine</a> allows to visit previous versions of a file.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package magit
:straight <span style="color:#66d9ef">t</span>
:commands (magit-status magit-file-dispatch)
:config
(setq magit-blame-styles
<span style="color:#f92672">&#39;</span>((margin
(margin-format <span style="color:#f92672">.</span> (<span style="color:#e6db74">&#34;%a %A %s&#34;</span>))
(margin-width <span style="color:#f92672">.</span> <span style="color:#ae81ff">42</span>)
(margin-face <span style="color:#f92672">.</span> magit-blame-margin)
(margin-body-face <span style="color:#f92672">.</span> (magit-blame-dimmed)))
(headings
(heading-format <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;%-20a %C %s\n&#34;</span>))
(highlight
(highlight-face <span style="color:#f92672">.</span> magit-blame-highlight))
(lines
(show-lines <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(show-message <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))))
(use-package git-gutter
:straight <span style="color:#66d9ef">t</span>
:if (not my/slow-ssh)
:config
(global-git-gutter-mode <span style="color:#ae81ff">+1</span>))
(use-package git-timemachine
:straight <span style="color:#66d9ef">t</span>
:commands (git-timemachine))
(my-leader-def
<span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#e6db74">&#39;magit</span>
<span style="color:#e6db74">&#34;M&#34;</span> <span style="color:#e6db74">&#39;magit-file-dispatch</span>)
</code></pre></div><h3 id="editorconfig">Editorconfig</h3>
<p>Editorconfig support for Emacs.</p>
<p>References:</p>
<ul>
<li><a href="https://editorconfig.org/">Editorconfig reference</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package editorconfig
:straight <span style="color:#66d9ef">t</span>
:config
(unless my/slow-ssh (editorconfig-mode <span style="color:#ae81ff">1</span>))
(add-to-list <span style="color:#e6db74">&#39;editorconfig-indentation-alist</span>
<span style="color:#f92672">&#39;</span>(emmet-mode emmet-indentation)))
</code></pre></div><h3 id="snippets">Snippets</h3>
<p>A snippet system for Emacs and a collection of pre-built snippets.</p>
<p><code>yasnippet-snippets</code> has to be loaded before <code>yasnippet</code> for user snippets to override the pre-built ones.</p>
<p>References:</p>
<ul>
<li><a href="http://joaotavora.github.io/yasnippet/">yasnippet documentation</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yasnippet-snippets
:straight <span style="color:#66d9ef">t</span>)
(use-package yasnippet
:straight <span style="color:#66d9ef">t</span>
:config
(setq yas-snippet-dirs
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">expand-file-name</span> user-emacs-directory) <span style="color:#e6db74">&#34;snippets&#34;</span>)
yasnippet-snippets-dir))
(setq yas-triggers-in-field <span style="color:#66d9ef">t</span>)
(yas-global-mode <span style="color:#ae81ff">1</span>))
(general-imap <span style="color:#e6db74">&#34;M-TAB&#34;</span> <span style="color:#e6db74">&#39;company-yasnippet</span>)
</code></pre></div><h3 id="time-trackers">Time trackers</h3>
<p>A bunch of time trackers I use.</p>
<p>References:</p>
<ul>
<li><a href="https://wakatime.com">WakaTime</a></li>
<li><a href="https://activitywatch.net/">ActivityWatch</a></li>
</ul>
<h4 id="wakatime">WakaTime</h4>
<p>Before I figure out how to package this for Guix:</p>
<ul>
<li>Clone <a href="https://github.com/wakatime/wakatime-cli">the repo</a></li>
<li>Run <code>go build</code></li>
<li>Copy the binary to the <code>~/bin</code> folder</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package wakatime-mode
:straight (:host github :repo <span style="color:#e6db74">&#34;SqrtMinusOne/wakatime-mode&#34;</span>)
:if (not (or my/is-termux my/remote-server))
:config
(setq wakatime-ignore-exit-codes <span style="color:#f92672">&#39;</span>(<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">102</span>))
(advice-add <span style="color:#e6db74">&#39;wakatime-init</span> :after (lambda () (setq wakatime-cli-path <span style="color:#e6db74">&#34;/home/pavel/bin/wakatime-cli&#34;</span>)))
<span style="color:#75715e">;; (setq wakatime-cli-path (executable-find &#34;wakatime&#34;))</span>
(global-wakatime-mode))
</code></pre></div><h4 id="activitywatch">ActivityWatch</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package request
:straight <span style="color:#66d9ef">t</span>)
(use-package activity-watch-mode
:straight <span style="color:#66d9ef">t</span>
:if (not (or my/is-termux my/remote-server))
:config
(global-activity-watch-mode))
</code></pre></div><h2 id="ui">UI</h2>
<h3 id="general-ui-and-gui-settings">General UI &amp; GUI Settings</h3>
<p>Disable GUI elements</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(unless my/is-termux
(tool-bar-mode <span style="color:#ae81ff">-1</span>)
(menu-bar-mode <span style="color:#ae81ff">-1</span>)
(scroll-bar-mode <span style="color:#ae81ff">-1</span>))
</code></pre></div><p>Transparency. Not setting it now, as I&rsquo;m using <a href="/configs/desktop/">picom</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (set-frame-parameter (selected-frame) &#39;alpha &#39;(90 . 90))</span>
<span style="color:#75715e">;; (add-to-list &#39;default-frame-alist &#39;(alpha . (90 . 90)))</span>
</code></pre></div><p>Prettify symbols. Also not setting it, ligatures seem to be enough for me.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (global-prettify-symbols-mode)</span>
</code></pre></div><p>No start screen</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq inhibit-startup-screen <span style="color:#66d9ef">t</span>)
</code></pre></div><p>Visual bell</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq visible-bell <span style="color:#ae81ff">0</span>)
</code></pre></div><p>y or n instead of yes or no</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defalias <span style="color:#e6db74">&#39;yes-or-no-p</span> <span style="color:#e6db74">&#39;y-or-n-p</span>)
</code></pre></div><p>Hide mouse cursor while typing</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq make-pointer-invisible <span style="color:#66d9ef">t</span>)
</code></pre></div><p>Line numbers. There seems to be a catch with the relative number setting:</p>
<ul>
<li><code>visual</code> doesn&rsquo;t take folding into account but also doesn&rsquo;t take wrapped lines into account (makes multiple numbers for a single wrapped line)</li>
<li><code>relative</code> makes a single number for a wrapped line, but counts folded lines.</li>
</ul>
<p><code>visual</code> option seems to be less of a problem in most cases.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(global-display-line-numbers-mode <span style="color:#ae81ff">1</span>)
(line-number-mode <span style="color:#66d9ef">nil</span>)
(setq display-line-numbers-type <span style="color:#e6db74">&#39;visual</span>)
(column-number-mode)
</code></pre></div><p>Show pairs</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(show-paren-mode <span style="color:#ae81ff">1</span>)
</code></pre></div><p>Word wrapping. These settings aren&rsquo;t too obvious compared to <code>:set wrap</code> from vim:</p>
<ul>
<li><code>word-wrap</code> means just &ldquo;don&rsquo;t split one word between two lines&rdquo;. So, if there isn&rsquo;t enough place to put a word at the end of the line, it will be put on a new one. Run <code>M-x toggle-word-wrap</code> to toggle that.</li>
<li><code>visual-line-mode</code> seems to be a superset of <code>word-wrap</code>. It also enables some editing commands to work on visual lines instead of logical ones, hence the naming.</li>
<li><code>auto-fill-mode</code> does the same as <code>word-wrap</code>, except it actually <strong>edits the buffer</strong> to make lines break in the appropriate places.</li>
<li><code>truncate-lines</code> truncate long lines instted of continuing them. Run <code>M-x toggle-truncate-lines</code> to toggle that. I find that <code>truncate-lines</code> behaves strangely when <code>visual-line-mode</code> is on, so I use one or another.</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq word-wrap <span style="color:#ae81ff">1</span>)
(global-visual-line-mode <span style="color:#ae81ff">1</span>)
</code></pre></div><p>Highlight current line</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(global-hl-line-mode <span style="color:#ae81ff">1</span>)
</code></pre></div><h3 id="theme-and-global-stuff">Theme &amp; global stuff</h3>
<p>Dim inactive buffers.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package auto-dim-other-buffers
:straight <span style="color:#66d9ef">t</span>
:if (display-graphic-p)
:config
(auto-dim-other-buffers-mode <span style="color:#66d9ef">t</span>))
</code></pre></div><p>My colorscheme of choice.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package doom-themes
:straight <span style="color:#66d9ef">t</span>
:if (not my/is-termux)
:config
(setq doom-themes-enable-bold <span style="color:#66d9ef">t</span>
doom-themes-enable-italic <span style="color:#66d9ef">t</span>)
(if my/remote-server
(load-theme <span style="color:#e6db74">&#39;doom-gruvbox</span> <span style="color:#66d9ef">t</span>)
(load-theme <span style="color:#e6db74">&#39;doom-palenight</span> <span style="color:#66d9ef">t</span>))
(doom-themes-visual-bell-config)
(setq doom-themes-treemacs-theme <span style="color:#e6db74">&#34;doom-colors&#34;</span>)
(doom-themes-treemacs-config))
</code></pre></div><h4 id="custom-theme">Custom theme</h4>
<p>A custom theme, dependent on Doom. I set all my custom variables there.</p>
<p>A custom theme is necessary because if one calls <code>custom-set-faces</code> and <code>custom-set-variables</code> in code, whenever a variable is changed and saved in a customize buffer, data from all calls of these functions is saved as well.</p>
<p>Also, a hook allows me to change doom-theme more or less at will, although I do that only to switch to a light theme once in a blue moon.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(unless my/is-termux
(deftheme my-theme)
(defun my/update-my-theme (<span style="color:#66d9ef">&amp;rest</span> _)
(custom-theme-set-faces
<span style="color:#e6db74">&#39;my-theme</span>
<span style="color:#f92672">`</span>(tab-bar-tab ((<span style="color:#66d9ef">t</span> (
:background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;bg</span>)
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>)
:underline <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>)))))
<span style="color:#f92672">`</span>(org-block ((<span style="color:#66d9ef">t</span> (:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">&#39;bg</span>) <span style="color:#ae81ff">3</span>)))))
<span style="color:#f92672">`</span>(org-block-begin-line ((<span style="color:#66d9ef">t</span> (
:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">&#39;bg</span>) <span style="color:#ae81ff">3</span>)
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;grey</span>)))))
<span style="color:#f92672">`</span>(auto-dim-other-buffers-face ((<span style="color:#66d9ef">t</span> (:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">&#39;bg</span>) <span style="color:#ae81ff">3</span>)))))
<span style="color:#f92672">`</span>(aweshell-alert-buffer-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;red</span>) :weight bold))))
<span style="color:#f92672">`</span>(aweshell-alert-command-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>) :weight bold))))
<span style="color:#f92672">`</span>(epe-pipeline-delimiter-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;green</span>)))))
<span style="color:#f92672">`</span>(epe-pipeline-host-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;blue</span>)))))
<span style="color:#f92672">`</span>(epe-pipeline-time-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>)))))
<span style="color:#f92672">`</span>(epe-pipeline-user-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;red</span>)))))
<span style="color:#f92672">`</span>(elfeed-search-tag-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>)))))
<span style="color:#f92672">`</span>(notmuch-wash-cited-text ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;yellow</span>))))))
(custom-theme-set-variables
<span style="color:#e6db74">&#39;my-theme</span>
<span style="color:#f92672">`</span>(aweshell-invalid-command-color <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;red</span>))
<span style="color:#f92672">`</span>(aweshell-valid-command-color <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">&#39;green</span>)))
(enable-theme <span style="color:#e6db74">&#39;my-theme</span>))
(advice-add <span style="color:#e6db74">&#39;load-theme</span> :after <span style="color:#a6e22e">#&#39;</span>my/update-my-theme)
(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">&#39;doom-color</span>)
(my/update-my-theme)))
</code></pre></div><h4 id="font">Font</h4>
<p>To install a font, download the font and unpack it into the <code>.local/share/fonts</code> directory. Create one if it doesn&rsquo;t exist.</p>
<p>As I use nerd fonts elsewhere, I use one in Emacs as well.</p>
<p>References:</p>
<ul>
<li><a href="https://nerdfonts.com">nerd fonts homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(set-frame-font <span style="color:#e6db74">&#34;JetBrainsMono Nerd Font 10&#34;</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)
</code></pre></div><p>To make the icons work (e.g. in the Doom Modeline), run <code>M-x all-the-icons-install-fonts</code>. The package definition is somewhere later in the config.</p>
<h3 id="custom-frame-title">Custom frame title</h3>
<p>Title format, which looks something like <code>emacs:project@hostname</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq-default frame-title-format
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;&#34;</span>
<span style="color:#e6db74">&#34;emacs&#34;</span>
(:eval
(let ((project-name (projectile-project-name)))
(if (not (string= <span style="color:#e6db74">&#34;-&#34;</span> project-name))
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;:%s@%s&#34;</span> project-name (<span style="color:#a6e22e">system-name</span>))
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;@%s&#34;</span> (<span style="color:#a6e22e">system-name</span>)))))))
</code></pre></div><h3 id="perspective-dot-el">perspective.el</h3>
<p><a href="https://github.com/nex3/perspective-el">perspective.el</a> is a package which provides gives Emacs capacities to group buffers into &ldquo;perspectives&rdquo;, which are like workspaces in tiling WMs.</p>
<p>An advantage over <code>tab-bar.el</code> is that <code>perspective.el</code> has better capacities for managing buffers, e.g. gives an ibuffer-like interface inside a perspective.</p>
<p>However, I don&rsquo;t like that list of workspaces is displayed inside the modeline rather than in an actual bar on the top of the frame. I may look into that later.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package perspective
:straight <span style="color:#66d9ef">t</span>
:init
<span style="color:#75715e">;; (setq persp-show-modestring &#39;header)</span>
(setq persp-sort <span style="color:#e6db74">&#39;created</span>)
:config
(persp-mode)
(my-leader-def <span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#f92672">&#39;</span>(:keymap perspective-map :which-key <span style="color:#e6db74">&#34;perspective&#34;</span>))
(general-define-key
:keymaps <span style="color:#e6db74">&#39;override</span>
:states <span style="color:#f92672">&#39;</span>(normal emacs)
<span style="color:#e6db74">&#34;gt&#34;</span> <span style="color:#e6db74">&#39;persp-next</span>
<span style="color:#e6db74">&#34;gT&#34;</span> <span style="color:#e6db74">&#39;persp-prev</span>
<span style="color:#e6db74">&#34;gn&#34;</span> <span style="color:#e6db74">&#39;persp-switch</span>
<span style="color:#e6db74">&#34;gN&#34;</span> <span style="color:#e6db74">&#39;persp-kill</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;perspective-map</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;persp-ivy-switch-buffer</span>
<span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#e6db74">&#39;persp-ivy-switch-buffer</span>
<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;persp-ibuffer</span>))
</code></pre></div><h4 id="some-functions">Some functions</h4>
<p>Move the current buffer to a perspective and switch to it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/persp-move-window-and-switch ()
(interactive)
(let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
(<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#&#39;</span>persp-switch)
(persp-set-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
(switch-to-buffer buffer)))
</code></pre></div><p>Copy the current buffer to a perspective and switch to it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/persp-copy-window-and-switch ()
(interactive)
(let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
(<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#&#39;</span>persp-switch)
(persp-add-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
(switch-to-buffer buffer)))
</code></pre></div><p>Add keybindings to the default map.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;perspective</span>
(general-define-key
:keymaps <span style="color:#e6db74">&#39;perspective-map</span>
<span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/persp-move-window-and-switch
<span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/persp-copy-window-and-switch))
</code></pre></div><h3 id="off--tab-bar"><span class="org-todo done OFF">OFF</span> (OFF) Tab bar</h3>
<p><del>I rely rather heavily on tab-bar in my workflow. I have a suspicion I&rsquo;m not using it the intended way, but that works for me.</del></p>
<p>For now switched to perspective.el, so the following block is not tangled.</p>
<h4 id="setup">Setup</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-define-key
:keymaps <span style="color:#e6db74">&#39;override</span>
:states <span style="color:#f92672">&#39;</span>(normal emacs)
<span style="color:#e6db74">&#34;gt&#34;</span> <span style="color:#e6db74">&#39;tab-bar-switch-to-next-tab</span>
<span style="color:#e6db74">&#34;gT&#34;</span> <span style="color:#e6db74">&#39;tab-bar-switch-to-prev-tab</span>
<span style="color:#e6db74">&#34;gn&#34;</span> <span style="color:#e6db74">&#39;tab-bar-new-tab</span>)
(setq tab-bar-show <span style="color:#ae81ff">1</span>)
(setq tab-bar-tab-hints <span style="color:#66d9ef">t</span>)
(setq tab-bar-tab-name-function <span style="color:#e6db74">&#39;tab-bar-tab-name-current-with-count</span>)
<span style="color:#75715e">;; Tabs</span>
(general-nmap <span style="color:#e6db74">&#34;gn&#34;</span> <span style="color:#e6db74">&#39;tab-new</span>)
(general-nmap <span style="color:#e6db74">&#34;gN&#34;</span> <span style="color:#e6db74">&#39;tab-close</span>)
</code></pre></div><h4 id="my-title">My title</h4>
<p>Prepend tab name with the shortened projectile project title</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/project-title-separators <span style="color:#e6db74">&#34;[-_ ]&#34;</span>)
(setq my/project-names-override-alist
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;.password-store&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;pass&#34;</span>)))
(defun my/shorten-project-name-elem (elem crop)
(if (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;^\\[.*\\]$&#34;</span> elem)
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;[&#34;</span>
(my/shorten-project-name-elem (<span style="color:#a6e22e">substring</span> elem <span style="color:#ae81ff">1</span> (<span style="color:#a6e22e">-</span> (<span style="color:#a6e22e">length</span> elem) <span style="color:#ae81ff">1</span>)) crop)
<span style="color:#e6db74">&#34;]&#34;</span>)
(let* ((prefix (<span style="color:#a6e22e">car</span> (s-match my/project-title-separators elem)))
(rest
(<span style="color:#a6e22e">substring</span>
(if prefix
(<span style="color:#a6e22e">substring</span> elem (<span style="color:#a6e22e">length</span> prefix))
elem)
<span style="color:#ae81ff">0</span> (if crop <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">nil</span>))))
(<span style="color:#a6e22e">concat</span> prefix rest))))
(defun my/shorten-project-name (project-name)
(or
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> project-name my/project-names-override-alist))
(let ((elems (s-slice-at my/project-title-separators project-name)))
(<span style="color:#a6e22e">concat</span>
(<span style="color:#a6e22e">apply</span>
<span style="color:#a6e22e">#&#39;concat</span>
(cl-mapcar (lambda (elem) (my/shorten-project-name-elem elem <span style="color:#66d9ef">t</span>)) (butlast elems)))
(my/shorten-project-name-elem (<span style="color:#a6e22e">car</span> (last elems)) <span style="color:#66d9ef">nil</span>)))))
(defun my/tab-bar-name-function ()
(let ((project-name (projectile-project-name)))
(if (string= <span style="color:#e6db74">&#34;-&#34;</span> project-name)
(tab-bar-tab-name-current-with-count)
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;[&#34;</span> (my/shorten-project-name project-name) <span style="color:#e6db74">&#34;] &#34;</span>
(replace-regexp-in-string <span style="color:#e6db74">&#34;&lt;.*&gt;&#34;</span> <span style="color:#e6db74">&#34;&#34;</span> (tab-bar-tab-name-current-with-count))))))
(setq tab-bar-tab-name-function <span style="color:#a6e22e">#&#39;</span>my/tab-bar-name-function)
</code></pre></div><h3 id="modeline">Modeline</h3>
<p>A modeline from Doom Emacs.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/seagle0128/doom-modeline">Doom Modeline</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package doom-modeline
:straight <span style="color:#66d9ef">t</span>
:init
(setq doom-modeline-env-enable-python <span style="color:#66d9ef">nil</span>)
(setq doom-modeline-env-enable-go <span style="color:#66d9ef">nil</span>)
:config
(doom-modeline-mode <span style="color:#ae81ff">1</span>)
(setq doom-modeline-minor-modes <span style="color:#66d9ef">nil</span>)
(setq doom-modeline-buffer-state-icon <span style="color:#66d9ef">nil</span>))
</code></pre></div><h3 id="font-stuff">Font stuff</h3>
<h4 id="emojis">Emojis</h4>
<table>
<thead>
<tr>
<th>Note</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO</td>
<td>Figure out how to display emojis without prettify symbols</td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package emojify
:straight <span style="color:#66d9ef">t</span>
:if (and (display-graphic-p) (not (or my/lowpower my/is-termux)))
:hook (after-init <span style="color:#f92672">.</span> global-emojify-mode))
</code></pre></div><h4 id="ligatures">Ligatures</h4>
<p>Ligature setup for the JetBrainsMono font.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ligature
:straight (:host github :repo <span style="color:#e6db74">&#34;mickeynp/ligature.el&#34;</span>)
:if (display-graphic-p)
:config
(ligature-set-ligatures
<span style="color:#f92672">&#39;</span>(
typescript-mode
js2-mode
vue-mode
svelte-mode
scss-mode
php-mode
python-mode
js-mode
markdown-mode
clojure-mode
go-mode
sh-mode
haskell-mode
web-mode)
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;--&#34;</span> <span style="color:#e6db74">&#34;---&#34;</span> <span style="color:#e6db74">&#34;==&#34;</span> <span style="color:#e6db74">&#34;===&#34;</span> <span style="color:#e6db74">&#34;!=&#34;</span> <span style="color:#e6db74">&#34;!==&#34;</span> <span style="color:#e6db74">&#34;=!=&#34;</span> <span style="color:#e6db74">&#34;=:=&#34;</span> <span style="color:#e6db74">&#34;=/=&#34;</span> <span style="color:#e6db74">&#34;&lt;=&#34;</span>
<span style="color:#e6db74">&#34;&gt;=&#34;</span> <span style="color:#e6db74">&#34;&amp;&amp;&#34;</span> <span style="color:#e6db74">&#34;&amp;&amp;&amp;&#34;</span> <span style="color:#e6db74">&#34;&amp;=&#34;</span> <span style="color:#e6db74">&#34;++&#34;</span> <span style="color:#e6db74">&#34;+++&#34;</span> <span style="color:#e6db74">&#34;***&#34;</span> <span style="color:#e6db74">&#34;;;&#34;</span> <span style="color:#e6db74">&#34;!!&#34;</span> <span style="color:#e6db74">&#34;??&#34;</span>
<span style="color:#e6db74">&#34;?:&#34;</span> <span style="color:#e6db74">&#34;?.&#34;</span> <span style="color:#e6db74">&#34;?=&#34;</span> <span style="color:#e6db74">&#34;&lt;:&#34;</span> <span style="color:#e6db74">&#34;:&lt;&#34;</span> <span style="color:#e6db74">&#34;:&gt;&#34;</span> <span style="color:#e6db74">&#34;&gt;:&#34;</span> <span style="color:#e6db74">&#34;&lt;&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;&lt;&lt;&#34;</span> <span style="color:#e6db74">&#34;&gt;&gt;&gt;&#34;</span>
<span style="color:#e6db74">&#34;&lt;&lt;&#34;</span> <span style="color:#e6db74">&#34;&gt;&gt;&#34;</span> <span style="color:#e6db74">&#34;||&#34;</span> <span style="color:#e6db74">&#34;-|&#34;</span> <span style="color:#e6db74">&#34;_|_&#34;</span> <span style="color:#e6db74">&#34;|-&#34;</span> <span style="color:#e6db74">&#34;||-&#34;</span> <span style="color:#e6db74">&#34;|=&#34;</span> <span style="color:#e6db74">&#34;||=&#34;</span> <span style="color:#e6db74">&#34;##&#34;</span>
<span style="color:#e6db74">&#34;###&#34;</span> <span style="color:#e6db74">&#34;####&#34;</span> <span style="color:#e6db74">&#34;#{&#34;</span> <span style="color:#e6db74">&#34;#[&#34;</span> <span style="color:#e6db74">&#34;]#&#34;</span> <span style="color:#e6db74">&#34;#(&#34;</span> <span style="color:#e6db74">&#34;#?&#34;</span> <span style="color:#e6db74">&#34;#_&#34;</span> <span style="color:#e6db74">&#34;#_(&#34;</span> <span style="color:#e6db74">&#34;#:&#34;</span>
<span style="color:#e6db74">&#34;#!&#34;</span> <span style="color:#e6db74">&#34;#=&#34;</span> <span style="color:#e6db74">&#34;^=&#34;</span> <span style="color:#e6db74">&#34;&lt;$&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;$&#34;</span> <span style="color:#e6db74">&#34;$&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;+&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;+&#34;</span> <span style="color:#e6db74">&#34;+&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;*&gt;&#34;</span>
<span style="color:#e6db74">&#34;&lt;*&#34;</span> <span style="color:#e6db74">&#34;*&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;/&#34;</span> <span style="color:#e6db74">&#34;&lt;/&gt;&#34;</span> <span style="color:#e6db74">&#34;/&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;!--&#34;</span> <span style="color:#e6db74">&#34;&lt;#--&#34;</span> <span style="color:#e6db74">&#34;--&gt;&#34;</span> <span style="color:#e6db74">&#34;-&gt;&#34;</span> <span style="color:#e6db74">&#34;-&gt;&gt;&#34;</span>
<span style="color:#e6db74">&#34;&lt;&lt;-&#34;</span> <span style="color:#e6db74">&#34;&lt;-&#34;</span> <span style="color:#e6db74">&#34;&lt;=&lt;&#34;</span> <span style="color:#e6db74">&#34;=&lt;&lt;&#34;</span> <span style="color:#e6db74">&#34;&lt;&lt;=&#34;</span> <span style="color:#e6db74">&#34;&lt;==&#34;</span> <span style="color:#e6db74">&#34;&lt;=&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;==&gt;&#34;</span> <span style="color:#e6db74">&#34;==&gt;&#34;</span> <span style="color:#e6db74">&#34;=&gt;&#34;</span>
<span style="color:#e6db74">&#34;=&gt;&gt;&#34;</span> <span style="color:#e6db74">&#34;&gt;=&gt;&#34;</span> <span style="color:#e6db74">&#34;&gt;&gt;=&#34;</span> <span style="color:#e6db74">&#34;&gt;&gt;-&#34;</span> <span style="color:#e6db74">&#34;&gt;-&#34;</span> <span style="color:#e6db74">&#34;&gt;--&#34;</span> <span style="color:#e6db74">&#34;-&lt;&#34;</span> <span style="color:#e6db74">&#34;-&lt;&lt;&#34;</span> <span style="color:#e6db74">&#34;&gt;-&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;-&lt;&#34;</span>
<span style="color:#e6db74">&#34;&lt;-|&#34;</span> <span style="color:#e6db74">&#34;&lt;=|&#34;</span> <span style="color:#e6db74">&#34;|=&gt;&#34;</span> <span style="color:#e6db74">&#34;|-&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;-&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;~~&#34;</span> <span style="color:#e6db74">&#34;&lt;~&#34;</span> <span style="color:#e6db74">&#34;&lt;~&gt;&#34;</span> <span style="color:#e6db74">&#34;~~&#34;</span> <span style="color:#e6db74">&#34;~~&gt;&#34;</span>
<span style="color:#e6db74">&#34;~&gt;&#34;</span> <span style="color:#e6db74">&#34;~-&#34;</span> <span style="color:#e6db74">&#34;-~&#34;</span> <span style="color:#e6db74">&#34;~@&#34;</span> <span style="color:#e6db74">&#34;[||]&#34;</span> <span style="color:#e6db74">&#34;|]&#34;</span> <span style="color:#e6db74">&#34;[|&#34;</span> <span style="color:#e6db74">&#34;|}&#34;</span> <span style="color:#e6db74">&#34;{|&#34;</span> <span style="color:#e6db74">&#34;[&lt;&#34;</span>
<span style="color:#e6db74">&#34;&gt;]&#34;</span> <span style="color:#e6db74">&#34;|&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;|&#34;</span> <span style="color:#e6db74">&#34;||&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;||&#34;</span> <span style="color:#e6db74">&#34;|||&gt;&#34;</span> <span style="color:#e6db74">&#34;&lt;|||&#34;</span> <span style="color:#e6db74">&#34;&lt;|&gt;&#34;</span> <span style="color:#e6db74">&#34;...&#34;</span> <span style="color:#e6db74">&#34;..&#34;</span>
<span style="color:#e6db74">&#34;.=&#34;</span> <span style="color:#e6db74">&#34;.-&#34;</span> <span style="color:#e6db74">&#34;..&lt;&#34;</span> <span style="color:#e6db74">&#34;.?&#34;</span> <span style="color:#e6db74">&#34;::&#34;</span> <span style="color:#e6db74">&#34;:::&#34;</span> <span style="color:#e6db74">&#34;:=&#34;</span> <span style="color:#e6db74">&#34;::=&#34;</span> <span style="color:#e6db74">&#34;:?&#34;</span> <span style="color:#e6db74">&#34;:?&gt;&#34;</span>
<span style="color:#e6db74">&#34;//&#34;</span> <span style="color:#e6db74">&#34;///&#34;</span> <span style="color:#e6db74">&#34;/*&#34;</span> <span style="color:#e6db74">&#34;*/&#34;</span> <span style="color:#e6db74">&#34;/=&#34;</span> <span style="color:#e6db74">&#34;//=&#34;</span> <span style="color:#e6db74">&#34;/==&#34;</span> <span style="color:#e6db74">&#34;@_&#34;</span> <span style="color:#e6db74">&#34;__&#34;</span>))
(global-ligature-mode <span style="color:#66d9ef">t</span>))
</code></pre></div><h4 id="icons">Icons</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package all-the-icons
:if (display-graphic-p)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="highlight-todo">Highlight todo</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hl-todo
:hook (prog-mode <span style="color:#f92672">.</span> hl-todo-mode)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h3 id="text-highlight-improvements">Text highlight improvements</h3>
<p>Highlight indent guides.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package highlight-indent-guides
:straight <span style="color:#66d9ef">t</span>
:if (not (or my/lowpower my/remote-server))
:hook (
(prog-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
(vue-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
(LaTeX-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode))
:config
(setq highlight-indent-guides-method <span style="color:#e6db74">&#39;bitmap</span>)
(setq highlight-indent-guides-bitmap-function <span style="color:#e6db74">&#39;highlight-indent-guides--bitmap-line</span>))
</code></pre></div><p>Rainbow parentheses.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package rainbow-delimiters
:straight <span style="color:#66d9ef">t</span>
:if (not my/lowpower)
:hook ((prog-mode <span style="color:#f92672">.</span> rainbow-delimiters-mode))
<span style="color:#75715e">;; :commands (rainbow-delimiters-mode)</span>
<span style="color:#75715e">;; :init</span>
<span style="color:#75715e">;; (add-hook &#39;prog-mode-hook</span>
<span style="color:#75715e">;; (lambda ()</span>
<span style="color:#75715e">;; (unless (org-in-src-block-p)</span>
<span style="color:#75715e">;; (rainbow-delimiters-mode))))</span>
)
</code></pre></div><p>Highlight colors</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package rainbow-mode
:commands (rainbow-mode)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h2 id="dired">Dired</h2>
<p>Dired is a built-in file manager. I use it as my primary file manager, hence the top level of config.</p>
<h3 id="basic-config-and-keybindings">Basic config &amp; keybindings</h3>
<p>My config mostly follows ranger&rsquo;s and vifm&rsquo;s keybindings which I&rsquo;m used to.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired
:ensure <span style="color:#66d9ef">nil</span>
:custom ((dired-listing-switches <span style="color:#e6db74">&#34;-alh --group-directories-first&#34;</span>))
:commands (dired)
:config
(setq dired-dwim-target <span style="color:#66d9ef">t</span>)
(setq wdired-allow-to-change-permissions <span style="color:#66d9ef">t</span>)
(setq wdired-create-parent-directories <span style="color:#66d9ef">t</span>)
(setq dired-recursive-copies <span style="color:#e6db74">&#39;always</span>)
(setq dired-recursive-deletes <span style="color:#e6db74">&#39;always</span>)
(setq dired-kill-when-opening-new-dired-buffer <span style="color:#66d9ef">t</span>)
(add-hook <span style="color:#e6db74">&#39;dired-mode-hook</span>
(lambda ()
(setq truncate-lines <span style="color:#66d9ef">t</span>)
(visual-line-mode <span style="color:#66d9ef">nil</span>)))
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;dired-mode-map</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;dired-up-directory</span>
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;dired-find-file</span>
<span style="color:#e6db74">&#34;=&#34;</span> <span style="color:#e6db74">&#39;dired-narrow</span>
<span style="color:#e6db74">&#34;-&#34;</span> <span style="color:#e6db74">&#39;dired-create-empty-file</span>
<span style="color:#e6db74">&#34;~&#34;</span> <span style="color:#e6db74">&#39;vterm</span>
<span style="color:#e6db74">&#34;&lt;left&gt;&#34;</span> <span style="color:#e6db74">&#39;dired-up-directory</span>
<span style="color:#e6db74">&#34;&lt;right&gt;&#34;</span> <span style="color:#e6db74">&#39;dired-find-file</span>
<span style="color:#e6db74">&#34;M-&lt;return&gt;&#34;</span> <span style="color:#e6db74">&#39;dired-open-xdg</span>))
(defun my/dired-home ()
<span style="color:#e6db74">&#34;Open dired at $HOME&#34;</span>
(interactive)
(dired (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~&#34;</span>)))
(my-leader-def
<span style="color:#e6db74">&#34;ad&#34;</span> <span style="color:#a6e22e">#&#39;</span>dired
<span style="color:#e6db74">&#34;aD&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/dired-home)
</code></pre></div><h3 id="addons">Addons</h3>
<p>I used to use <a href="https://www.emacswiki.org/emacs/DiredPlus">dired+</a>, which provides a lot of extensions for dired functionality, but it also creates some new problems, so I opt out of it. Fortunately, the one feature I want from this package - adding more colors to dired buffers - is available as a separate package</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package diredfl
:straight <span style="color:#66d9ef">t</span>
:after dired
:config
(diredfl-global-mode <span style="color:#ae81ff">1</span>))
</code></pre></div><p><del>Reuse the current dired buffer instead of spamming new ones.</del> Looks like not neccesary with Emacs 28.1</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-single
:after dired
:disabled
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><p>Display icons for files.</p>
<table>
<thead>
<tr>
<th>Note</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ACHTUNG</strong></td>
<td>This plugin is slow as hell with TRAMP or in <code>gnu/store</code></td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package all-the-icons-dired
:straight <span style="color:#66d9ef">t</span>
:if (not (or my/lowpower my/slow-ssh (not (display-graphic-p))))
:hook (dired-mode <span style="color:#f92672">.</span> (lambda ()
(unless (string-match-p <span style="color:#e6db74">&#34;/gnu/store&#34;</span> default-directory)
(all-the-icons-dired-mode))))
:config
(advice-add <span style="color:#e6db74">&#39;dired-add-entry</span> :around <span style="color:#a6e22e">#&#39;</span>all-the-icons-dired--refresh-advice)
(advice-add <span style="color:#e6db74">&#39;dired-remove-entry</span> :around <span style="color:#a6e22e">#&#39;</span>all-the-icons-dired--refresh-advice)
(advice-add <span style="color:#e6db74">&#39;dired-kill-subdir</span> :around <span style="color:#a6e22e">#&#39;</span>all-the-icons-dired--refresh-advice))
</code></pre></div><p>Provides stuff like <code>dired-open-xdg</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-open
:straight <span style="color:#66d9ef">t</span>
:commands (dired-open-xdg))
</code></pre></div><p>vifm-like filter</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-narrow
:straight <span style="color:#66d9ef">t</span>
:commands (dired-narrow)
:config
(general-define-key
:keymaps <span style="color:#e6db74">&#39;dired-narrow-map</span>
[escape] <span style="color:#e6db74">&#39;keyboard-quit</span>))
</code></pre></div><p>Display git info, such as the last commit for file and stuff. It&rsquo;s pretty useful but also slows down Dired a bit, hence I don&rsquo;t turn it out by default.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-git-info
:straight <span style="color:#66d9ef">t</span>
:after dired
:if (not my/slow-ssh)
:config
(general-define-key
:keymap <span style="color:#e6db74">&#39;dired-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(normal emacs)
<span style="color:#e6db74">&#34;)&#34;</span> <span style="color:#e6db74">&#39;dired-git-info-mode</span>))
</code></pre></div><h3 id="subdirectories">Subdirectories</h3>
<p>Subdirectories are one of the interesting features of Dired. It allows displaying multiple folders on the same window.</p>
<p>I add my own keybindings and some extra functionality.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dired-open-this-subdir ()
(interactive)
(dired (dired-current-directory)))
(defun my/dired-kill-all-subdirs ()
(interactive)
(let ((dir dired-directory))
(<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
(dired dir)))
(with-eval-after-load <span style="color:#e6db74">&#39;dired</span>
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;dired-mode-map</span>
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#66d9ef">nil</span>
<span style="color:#e6db74">&#34;ss&#34;</span> <span style="color:#e6db74">&#39;dired-maybe-insert-subdir</span>
<span style="color:#e6db74">&#34;sl&#34;</span> <span style="color:#e6db74">&#39;dired-maybe-insert-subdir</span>
<span style="color:#e6db74">&#34;sq&#34;</span> <span style="color:#e6db74">&#39;dired-kill-subdir</span>
<span style="color:#e6db74">&#34;sk&#34;</span> <span style="color:#e6db74">&#39;dired-prev-subdir</span>
<span style="color:#e6db74">&#34;sj&#34;</span> <span style="color:#e6db74">&#39;dired-next-subdir</span>
<span style="color:#e6db74">&#34;sS&#34;</span> <span style="color:#e6db74">&#39;my/dired-open-this-subdir</span>
<span style="color:#e6db74">&#34;sQ&#34;</span> <span style="color:#e6db74">&#39;my/dired-kill-all-subdirs</span>
(kbd <span style="color:#e6db74">&#34;TAB&#34;</span>) <span style="color:#e6db74">&#39;dired-hide-subdir</span>))
</code></pre></div><h3 id="tramp">TRAMP</h3>
<p>TRAMP is a package that provides remote editing capacities. It is particularly useful for remote server management.</p>
<p>One of the reasons why TRAMP may be slow is that some plugins do too many requests to the filesystem. To debug these issues, set the following variable to 6:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq tramp-verbose <span style="color:#ae81ff">1</span>)
</code></pre></div><p>To check if a file is remote, you can use <code>file-remote-p</code>. E.g. <code>(file-remote-p default-directory)</code> for a current buffer. The problem with this approach is that it&rsquo;s rather awkward to add these checks in every hook, especially for global modes, so for now, I just set an environment variable for Emacs which disables these modes.</p>
<p>So far I have found the following problematic plugins:</p>
<table>
<thead>
<tr>
<th>Plugin</th>
<th>Note</th>
<th>Solution</th>
</tr>
</thead>
<tbody>
<tr>
<td>editorconfig</td>
<td>looks for .editorconfig in the file tree</td>
<td>do not enable globally</td>
</tr>
<tr>
<td>all-the-icons-dired</td>
<td>runs test on every file in the directory</td>
<td>disable</td>
</tr>
<tr>
<td>projectile</td>
<td>looks for .git, .svn, etc</td>
<td>advice <code>projectile-file-name</code></td>
</tr>
<tr>
<td>lsp</td>
<td>does a whole lot of stuff</td>
<td>disable</td>
</tr>
<tr>
<td>git-gutter</td>
<td>runs git</td>
<td>disable</td>
</tr>
<tr>
<td>vterm</td>
<td>no proper TRAMP integration</td>
<td>use eshell or shell</td>
</tr>
</tbody>
</table>
<p>At any rate, it&rsquo;s usable, although not perfect.</p>
<p>Some other optimization settings:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq remote-file-name-inhibit-cache <span style="color:#66d9ef">nil</span>)
(setq vc-ignore-dir-regexp
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;\\(%s\\)\\|\\(%s\\)&#34;</span>
vc-ignore-dir-regexp
tramp-file-name-regexp))
</code></pre></div><p>Set the default shell to <code>bin/bash</code> for TRAMP or on a remote server.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(when (or my/remote-server my/slow-ssh)
(setq explicit-shell-file-name <span style="color:#e6db74">&#34;/bin/bash&#34;</span>))
</code></pre></div><p>Also, here is a hack to make TRAMP find <code>ls</code> on Guix:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;tramp</span>
(setq tramp-remote-path
(<span style="color:#a6e22e">append</span> tramp-remote-path
<span style="color:#f92672">&#39;</span>(tramp-own-remote-path))))
</code></pre></div><h3 id="bookmarks">Bookmarks</h3>
<p>A simple bookmark list for Dired, mainly to use with TRAMP. I may look into a proper bookmarking system later.</p>
<p>Bookmarks are listed in the <a href=".emacs.d/dired-bookmarks.el">dired-bookmarks.el</a> file, which looks like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">(setq my/dired-bookmarks
&#39;((&#34;sudo&#34; . &#34;/sudo::/&#34;)))
</code></pre></div><p>The file itself is encrypted with yadm.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dired-bookmark-open ()
(interactive)
(unless (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;my/dired-bookmarks</span>)
(<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">&#34;dired-bookmarks&#34;</span>)))
(let ((bookmarks
(<span style="color:#a6e22e">mapcar</span>
(lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;%-30s %s&#34;</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
my/dired-bookmarks)))
(dired
(<span style="color:#a6e22e">cdr</span>
(<span style="color:#a6e22e">assoc</span>
(<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">&#34;Dired: &#34;</span> bookmarks <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#34;^&#34;</span>)
bookmarks)))))
</code></pre></div><h2 id="shells">Shells</h2>
<h3 id="vterm">vterm</h3>
<p>My terminal emulator of choice.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/akermu/emacs-libvterm">emacs-libvterm repo</a></li>
</ul>
<h4 id="configuration">Configuration</h4>
<p>I use the package from the Guix repository to avoid building libvterm.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package vterm
<span style="color:#75715e">;; :straight t</span>
:commands (vterm vterm-other-window)
:config
(setq vterm-kill-buffer-on-exit <span style="color:#66d9ef">t</span>)
(add-hook <span style="color:#e6db74">&#39;vterm-mode-hook</span>
(lambda ()
(setq-local global-display-line-numbers-mode <span style="color:#66d9ef">nil</span>)
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
(advice-add <span style="color:#e6db74">&#39;evil-collection-vterm-insert</span>
:before (lambda (<span style="color:#66d9ef">&amp;rest</span> args)
(ignore-errors
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#&#39;</span>vterm-reset-cursor-point args))))
(general-define-key
:keymaps <span style="color:#e6db74">&#39;vterm-mode-map</span>
<span style="color:#e6db74">&#34;M-q&#34;</span> <span style="color:#e6db74">&#39;vterm-send-escape</span>
<span style="color:#e6db74">&#34;C-h&#34;</span> <span style="color:#e6db74">&#39;evil-window-left</span>
<span style="color:#e6db74">&#34;C-l&#34;</span> <span style="color:#e6db74">&#39;evil-window-right</span>
<span style="color:#e6db74">&#34;C-k&#34;</span> <span style="color:#e6db74">&#39;evil-window-up</span>
<span style="color:#e6db74">&#34;C-j&#34;</span> <span style="color:#e6db74">&#39;evil-window-down</span>
<span style="color:#e6db74">&#34;C-&lt;right&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-right</span>
<span style="color:#e6db74">&#34;C-&lt;left&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-left</span>
<span style="color:#e6db74">&#34;C-&lt;up&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-up</span>
<span style="color:#e6db74">&#34;C-&lt;down&gt;&#34;</span> <span style="color:#e6db74">&#39;evil-window-down</span>
<span style="color:#e6db74">&#34;M-&lt;left&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-send-left</span>
<span style="color:#e6db74">&#34;M-&lt;right&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-send-right</span>
<span style="color:#e6db74">&#34;M-&lt;up&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-send-up</span>
<span style="color:#e6db74">&#34;M-&lt;down&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-send-down</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;vterm-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(normal <span style="color:#a6e22e">insert</span>)
<span style="color:#e6db74">&#34;&lt;home&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-beginning-of-line</span>
<span style="color:#e6db74">&#34;&lt;end&gt;&#34;</span> <span style="color:#e6db74">&#39;vterm-end-of-line</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;vterm-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(<span style="color:#a6e22e">insert</span>)
<span style="color:#e6db74">&#34;C-r&#34;</span> <span style="color:#e6db74">&#39;vterm-send-C-r</span>
<span style="color:#e6db74">&#34;C-k&#34;</span> <span style="color:#e6db74">&#39;vterm-send-C-k</span>
<span style="color:#e6db74">&#34;C-j&#34;</span> <span style="color:#e6db74">&#39;vterm-send-C-j</span>
<span style="color:#e6db74">&#34;M-l&#34;</span> <span style="color:#e6db74">&#39;vterm-send-right</span>
<span style="color:#e6db74">&#34;M-h&#34;</span> <span style="color:#e6db74">&#39;vterm-send-left</span>
<span style="color:#e6db74">&#34;M-k&#34;</span> <span style="color:#e6db74">&#39;vterm-send-up</span>
<span style="color:#e6db74">&#34;M-j&#34;</span> <span style="color:#e6db74">&#39;vterm-send-down</span>))
</code></pre></div><h4 id="subterminal">Subterminal</h4>
<p>Open a terminal in the lower third of the frame with the <code>`</code> key.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-to-list <span style="color:#e6db74">&#39;display-buffer-alist</span>
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span><span style="color:#e6db74">&#34;vterm-subterminal.*&#34;</span>
(display-buffer-reuse-window
display-buffer-in-side-window)
(side <span style="color:#f92672">.</span> bottom)
(reusable-frames <span style="color:#f92672">.</span> visible)
(window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>)))
(defun my/toggle-vterm-subteminal ()
<span style="color:#e6db74">&#34;Toogle subteminal.&#34;</span>
(interactive)
(let
((vterm-window
(seq-find
(lambda (window)
(<span style="color:#a6e22e">string-match</span>
<span style="color:#e6db74">&#34;vterm-subterminal.*&#34;</span>
(<span style="color:#a6e22e">buffer-name</span> (<span style="color:#a6e22e">window-buffer</span> window))))
(<span style="color:#a6e22e">window-list</span>))))
(if vterm-window
(if (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">get-buffer-window</span> (<span style="color:#a6e22e">current-buffer</span>)) vterm-window)
(<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
(<span style="color:#a6e22e">select-window</span> vterm-window))
(vterm-other-window <span style="color:#e6db74">&#34;vterm-subterminal&#34;</span>))))
(unless my/slow-ssh
(general-nmap <span style="color:#e6db74">&#34;`&#34;</span> <span style="color:#e6db74">&#39;my/toggle-vterm-subteminal</span>)
(general-nmap <span style="color:#e6db74">&#34;~&#34;</span> <span style="color:#e6db74">&#39;vterm</span>))
</code></pre></div><h4 id="dired-integration">Dired integration</h4>
<p>A function to get pwd for vterm. Couldn&rsquo;t find a built-in function for some reason, but this seems to be working fine:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/vterm-get-pwd ()
(if vterm--process
(file-truename (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;/proc/%d/cwd&#34;</span> (<span style="color:#a6e22e">process-id</span> vterm--process)))
default-directory))
</code></pre></div><p>Now we can open dired for vterm pwd:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/vterm-dired-other-window ()
<span style="color:#e6db74">&#34;Open dired in vterm pwd in other window&#34;</span>
(interactive)
(dired-other-window (my/vterm-get-pwd)))
(defun my/vterm-dired-replace ()
<span style="color:#e6db74">&#34;Replace vterm with dired&#34;</span>
(interactive)
(let ((pwd (my/vterm-get-pwd)))
(<span style="color:#a6e22e">kill-process</span> vterm--process)
(dired pwd)))
</code></pre></div><p>The second function is particularly handy because that way I can alternate between vterm and dired.</p>
<p>Keybindings:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;vterm</span>
(general-define-key
:keymaps <span style="color:#e6db74">&#39;vterm-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(normal)
<span style="color:#e6db74">&#34;gd&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/vterm-dired-other-window
<span style="color:#e6db74">&#34;gD&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/vterm-dired-replace))
</code></pre></div><h4 id="with-editor-integration">With-editor integration</h4>
<p>A package used by Magit to use the current Emacs instance as the <code>$EDITOR</code>.</p>
<p>That is, with the help of <a href="/configs/console/">this function</a>, I can just write <code>e &lt;filename&gt;</code>, edit the file, and then return to the same vterm buffer. No more running vim inside Emacs.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package with-editor
:straight <span style="color:#66d9ef">t</span>
:after (vterm)
:config
(add-hook <span style="color:#e6db74">&#39;vterm-mode-hook</span> <span style="color:#e6db74">&#39;with-editor-export-editor</span>))
</code></pre></div><h3 id="eshell">Eshell</h3>
<p>A shell written in Emacs lisp. I don&rsquo;t use it as of now, but keep the config just in case.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/configure-eshell ()
(add-hook <span style="color:#e6db74">&#39;eshell-pre-command-hook</span> <span style="color:#e6db74">&#39;eshell-save-some-history</span>)
(add-to-list <span style="color:#e6db74">&#39;eshell-output-filter-functions</span> <span style="color:#e6db74">&#39;eshell-truncate-buffer</span>)
(setq eshell-history-size <span style="color:#ae81ff">10000</span>)
(setq eshell-hist-ingnoredups <span style="color:#66d9ef">t</span>)
(setq eshell-buffer-maximum-lines <span style="color:#ae81ff">10000</span>)
(evil-define-key <span style="color:#f92672">&#39;</span>(normal <span style="color:#a6e22e">insert</span> visual) eshell-mode-map (kbd <span style="color:#e6db74">&#34;&lt;home&gt;&#34;</span>) <span style="color:#e6db74">&#39;eshell-bol</span>)
(evil-define-key <span style="color:#f92672">&#39;</span>(normal <span style="color:#a6e22e">insert</span> visual) eshell-mode-map (kbd <span style="color:#e6db74">&#34;C-r&#34;</span>) <span style="color:#e6db74">&#39;counsel-esh-history</span>)
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;eshell-mode-map</span>
(kbd <span style="color:#e6db74">&#34;C-h&#34;</span>) <span style="color:#e6db74">&#39;evil-window-left</span>
(kbd <span style="color:#e6db74">&#34;C-l&#34;</span>) <span style="color:#e6db74">&#39;evil-window-right</span>
(kbd <span style="color:#e6db74">&#34;C-k&#34;</span>) <span style="color:#e6db74">&#39;evil-window-up</span>
(kbd <span style="color:#e6db74">&#34;C-j&#34;</span>) <span style="color:#e6db74">&#39;evil-window-down</span>))
(use-package eshell
:ensure <span style="color:#66d9ef">nil</span>
:after evil-collection
:commands (eshell)
:config
(add-hook <span style="color:#e6db74">&#39;eshell-first-time-mode-hook</span> <span style="color:#e6db74">&#39;my/configure-eshell</span> <span style="color:#ae81ff">90</span>)
(when my/slow-ssh
(add-hook <span style="color:#e6db74">&#39;eshell-mode-hook</span>
(lambda ()
(setq-local company-idle-delay <span style="color:#ae81ff">1000</span>))))
(setq eshell-banner-message <span style="color:#e6db74">&#34;&#34;</span>))
(use-package aweshell
:straight (:repo <span style="color:#e6db74">&#34;manateelazycat/aweshell&#34;</span> :host github)
:after eshell
:config
(setq eshell-highlight-prompt <span style="color:#66d9ef">nil</span>)
(setq eshell-prompt-function <span style="color:#e6db74">&#39;epe-theme-pipeline</span>))
(use-package eshell-info-banner
:defer <span style="color:#66d9ef">t</span>
:if (not my/slow-ssh)
:straight (eshell-info-banner :type git
:host github
:repo <span style="color:#e6db74">&#34;phundrak/eshell-info-banner.el&#34;</span>)
:hook (eshell-banner-load <span style="color:#f92672">.</span> eshell-info-banner-update-banner))
(when my/slow-ssh
(general-nmap <span style="color:#e6db74">&#34;`&#34;</span> <span style="color:#e6db74">&#39;aweshell-dedicated-toggle</span>)
(general-nmap <span style="color:#e6db74">&#34;~&#34;</span> <span style="color:#e6db74">&#39;eshell</span>))
</code></pre></div><h2 id="org-mode">Org Mode</h2>
<p>The best feature of Emacs. Just after every other best feature of Emacs, probably.</p>
<p>References:</p>
<ul>
<li><a href="https://orgmode.org/">Org Mode homepage</a></li>
<li><a href="https://orgmode.org/manual/">Manual</a></li>
</ul>
<h3 id="installation-and-basic-settings">Installation &amp; basic settings</h3>
<p>Use the built-in org mode.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org
:straight <span style="color:#66d9ef">t</span>
:if (not my/remote-server)
:defer <span style="color:#66d9ef">t</span>
:config
(setq org-startup-indented <span style="color:#66d9ef">t</span>)
(setq org-return-follows-link <span style="color:#66d9ef">t</span>)
(setq org-src-tab-acts-natively <span style="color:#66d9ef">nil</span>)
(add-hook <span style="color:#e6db74">&#39;org-mode-hook</span> <span style="color:#e6db74">&#39;smartparens-mode</span>)
(add-hook <span style="color:#e6db74">&#39;org-agenda-mode-hook</span>
(lambda ()
(visual-line-mode <span style="color:#ae81ff">-1</span>)
(toggle-truncate-lines <span style="color:#ae81ff">1</span>)
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
(add-hook <span style="color:#e6db74">&#39;org-mode-hook</span>
(lambda ()
(rainbow-delimiters-mode <span style="color:#ae81ff">-1</span>)))
&lt;&lt;org-crypt-setup&gt;&gt;
(unless my/is-termux
&lt;&lt;org-lang-setup&gt;&gt;)
&lt;&lt;org-ui-setup&gt;&gt;
&lt;&lt;org-keys-setup&gt;&gt;
&lt;&lt;org-productivity-setup&gt;&gt;)
</code></pre></div><h4 id="encryption">Encryption</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(require <span style="color:#e6db74">&#39;org-crypt</span>)
(org-crypt-use-before-save-magic)
(setq org-tags-exclude-from-inheritance (quote (<span style="color:#e6db74">&#34;crypt&#34;</span>)))
(setq org-crypt-key <span style="color:#e6db74">&#34;C1EC867E478472439CC82410DE004F32AFA00205&#34;</span>)
</code></pre></div><h4 id="org-contrib">org-contrib</h4>
<p><code>org-contrib</code> is a package with various additions to Org. I use the following:</p>
<ul>
<li><code>ox-extra</code> - extensions for org export</li>
<li><code>ol-notmuch</code> - integration with notmuch</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-contrib
:straight (org-contrib
:type git
:host <span style="color:#66d9ef">nil</span>
:repo <span style="color:#e6db74">&#34;https://git.sr.ht/~bzg/org-contrib&#34;</span>
:build <span style="color:#66d9ef">t</span>)
:after (org)
:config
(require <span style="color:#e6db74">&#39;ox-extra</span>)
(require <span style="color:#e6db74">&#39;ol-notmuch</span>)
(ox-extras-activate <span style="color:#f92672">&#39;</span>(latex-header-blocks ignore-headlines)))
</code></pre></div><h3 id="integration-with-evil">Integration with evil</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-org
:straight <span style="color:#66d9ef">t</span>
:hook (org-mode <span style="color:#f92672">.</span> evil-org-mode)
:config
(add-hook <span style="color:#e6db74">&#39;evil-org-mode-hook</span>
(lambda ()
(evil-org-set-key-theme <span style="color:#f92672">&#39;</span>(navigation <span style="color:#a6e22e">insert</span> textobjects additional calendar todo))))
(add-to-list <span style="color:#e6db74">&#39;evil-emacs-state-modes</span> <span style="color:#e6db74">&#39;org-agenda-mode</span>)
(require <span style="color:#e6db74">&#39;evil-org-agenda</span>)
(evil-org-agenda-set-keys))
</code></pre></div><h3 id="literate-programing">Literate programing</h3>
<h4 id="python-and-jupyter">Python &amp; Jupyter</h4>
<p>Use jupyter kernels for Org Mode.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/nnicandro/emacs-jupyter">emacs-jupyter repo</a></li>
<li><a href="https://github.com/jkitchin/scimax/blob/master/scimax.org">SCIMAX manual</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package jupyter
:straight <span style="color:#66d9ef">t</span>
:if (not my/is-termux)
:init
(my-leader-def <span style="color:#e6db74">&#34;ar&#34;</span> <span style="color:#e6db74">&#39;jupyter-run-repl</span>))
</code></pre></div><p>Refresh kernelspecs.</p>
<p>Kernelspecs by default are hashed, so even switching Anaconda environments doesn&rsquo;t change the kernel (i.e. kernel from the first environment is run after the switch to the second one).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jupyter-refresh-kernelspecs ()
<span style="color:#e6db74">&#34;Refresh Jupyter kernelspecs&#34;</span>
(interactive)
(jupyter-available-kernelspecs <span style="color:#66d9ef">t</span>))
</code></pre></div><p>Also, if some kernel wasn&rsquo;t present at the moment of the load of <code>emacs-jupyter</code>, it won&rsquo;t be added to the <code>org-src-lang-modes</code> list. E.g. I have Hy kernel installed in a separate Anaconda environment, so if Emacs hasn&rsquo;t been launched in this environment, I wouldn&rsquo;t be able to use <code>hy</code> in org-src blocks.</p>
<p>Fortunately, <code>emacs-jupyter</code> provides a function for that problem as well.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jupyter-refesh-langs ()
<span style="color:#e6db74">&#34;Refresh Jupyter languages&#34;</span>
(interactive)
(org-babel-jupyter-aliases-from-kernelspecs <span style="color:#66d9ef">t</span>))
</code></pre></div><h4 id="hy">Hy</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ob-hy
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="view-html-in-browser">View HTML in browser</h4>
<p>Open HTML in the <code>begin_export</code> block with xdg-open.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-view-html-tmp-dir <span style="color:#e6db74">&#34;/tmp/org-html-preview/&#34;</span>)
(use-package f
:straight <span style="color:#66d9ef">t</span>)
(defun my/org-view-html ()
(interactive)
(let ((elem (org-element-at-point))
(temp-file-path (<span style="color:#a6e22e">concat</span> my/org-view-html-tmp-dir (<span style="color:#a6e22e">number-to-string</span> (<span style="color:#a6e22e">random</span> (<span style="color:#a6e22e">expt</span> <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">32</span>))) <span style="color:#e6db74">&#34;.html&#34;</span>)))
(cond
((not (<span style="color:#a6e22e">eq</span> <span style="color:#e6db74">&#39;export-block</span> (<span style="color:#a6e22e">car</span> elem)))
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">&#34;Not in an export block!&#34;</span>))
((not (<span style="color:#a6e22e">string-equal</span> (<span style="color:#a6e22e">plist-get</span> (<span style="color:#a6e22e">car</span> (<span style="color:#a6e22e">cdr</span> elem)) :type) <span style="color:#e6db74">&#34;HTML&#34;</span>))
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">&#34;Export block is not HTML!&#34;</span>))
(<span style="color:#66d9ef">t</span> (progn
(f-mkdir my/org-view-html-tmp-dir)
(f-write (<span style="color:#a6e22e">plist-get</span> (<span style="color:#a6e22e">car</span> (<span style="color:#a6e22e">cdr</span> elem)) :value) <span style="color:#e6db74">&#39;utf-8</span> temp-file-path)
(<span style="color:#a6e22e">start-process</span> <span style="color:#e6db74">&#34;org-html-preview&#34;</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#34;xdg-open&#34;</span> temp-file-path))))))
</code></pre></div><h4 id="plantuml">PlantUML</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-plantuml-executable-path <span style="color:#e6db74">&#34;/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml&#34;</span>)
(setq org-plantuml-exec-mode <span style="color:#e6db74">&#39;plantuml</span>)
(add-to-list <span style="color:#e6db74">&#39;org-src-lang-modes</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;plantuml&#34;</span> <span style="color:#f92672">.</span> plantuml))
</code></pre></div><h4 id="setup">Setup</h4>
<p>Enable languages</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(org-babel-do-load-languages
<span style="color:#e6db74">&#39;org-babel-load-languages</span>
<span style="color:#f92672">&#39;</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(python <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(sql <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
<span style="color:#75715e">;; (typescript .t)</span>
(hy <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(plantuml <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(octave <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(jupyter <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
(add-hook <span style="color:#e6db74">&#39;org-babel-after-execute-hook</span> <span style="color:#e6db74">&#39;org-redisplay-inline-images</span>)
</code></pre></div><p>Use Jupyter block instead of built-in Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(org-babel-jupyter-override-src-block <span style="color:#e6db74">&#34;python&#34;</span>)
(org-babel-jupyter-override-src-block <span style="color:#e6db74">&#34;hy&#34;</span>)
</code></pre></div><p>Turn of some minor modes in source blocks.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;org-src-mode-hook</span>
(lambda ()
<span style="color:#75715e">;; (hs-minor-mode -1)</span>
<span style="color:#75715e">;; (electric-indent-local-mode -1)</span>
<span style="color:#75715e">;; (rainbow-delimiters-mode -1)</span>
(highlight-indent-guides-mode <span style="color:#ae81ff">-1</span>)))
</code></pre></div><p>Async code blocks evaluations. Jupyter blocks have a built-in async, so they are set as ignored.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ob-async
:straight <span style="color:#66d9ef">t</span>
:after (org)
:config
(setq ob-async-no-async-languages-alist <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;python&#34;</span> <span style="color:#e6db74">&#34;hy&#34;</span> <span style="color:#e6db74">&#34;jupyter-python&#34;</span> <span style="color:#e6db74">&#34;jupyter-octave&#34;</span>)))
</code></pre></div><h4 id="managing-jupyter-kernels">Managing Jupyter kernels</h4>
<p>Functions for managing local Jupyter kernels.</p>
<p><code>my/insert-jupyter-kernel</code> inserts a path to an active Jupyter kernel to the buffer. Useful to quickly write a header like:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">#+PROPERTY: header-args:python :session &lt;path-to-kernel&gt;
</code></pre></div><p><code>my/jupyter-connect-repl</code> opens a <code>emacs-jupyter</code> REPL, connected to an active kernel. <code>my/jupyter-qtconsole</code> runs a standalone Jupyter QtConsole.</p>
<p>Requirements: <code>ss</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/jupyter-runtime-folder (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~/.local/share/jupyter/runtime&#34;</span>))
(defun my/get-open-ports ()
(<span style="color:#a6e22e">mapcar</span>
<span style="color:#a6e22e">#&#39;string-to-number</span>
(split-string (shell-command-to-string <span style="color:#e6db74">&#34;ss -tulpnH | awk &#39;{print $5}&#39; | sed -e &#39;s/.*://&#39;&#34;</span>) <span style="color:#e6db74">&#34;\n&#34;</span>)))
(defun my/list-jupyter-kernel-files ()
(<span style="color:#a6e22e">mapcar</span>
(lambda (file) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">car</span> file) (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assq</span> <span style="color:#e6db74">&#39;shell_port</span> (json-read-file (<span style="color:#a6e22e">car</span> file))))))
(<span style="color:#a6e22e">sort</span>
(<span style="color:#a6e22e">directory-files-and-attributes</span> my/jupyter-runtime-folder <span style="color:#66d9ef">t</span> <span style="color:#e6db74">&#34;.*kernel.*json$&#34;</span>)
(lambda (x y) (not (<span style="color:#a6e22e">time-less-p</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">6</span> x) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">6</span> y)))))))
(defun my/select-jupyter-kernel ()
(let ((ports (my/get-open-ports))
(files (my/list-jupyter-kernel-files)))
(<span style="color:#a6e22e">completing-read</span>
<span style="color:#e6db74">&#34;Jupyter kernels: &#34;</span>
(seq-filter
(lambda (file)
(<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports))
files))))
(defun my/insert-jupyter-kernel ()
<span style="color:#e6db74">&#34;Insert a path to an active Jupyter kernel into the buffer&#34;</span>
(interactive)
(<span style="color:#a6e22e">insert</span> (my/select-jupyter-kernel)))
(defun my/jupyter-connect-repl ()
<span style="color:#e6db74">&#34;Open an emacs-jupyter REPL, connected to a Jupyter kernel&#34;</span>
(interactive)
(jupyter-connect-repl (my/select-jupyter-kernel) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>))
(defun my/jupyter-qtconsole ()
<span style="color:#e6db74">&#34;Open Jupyter QtConsole, connected to a Jupyter kernel&#34;</span>
(interactive)
(<span style="color:#a6e22e">start-process</span> <span style="color:#e6db74">&#34;jupyter-qtconsole&#34;</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#34;setsid&#34;</span> <span style="color:#e6db74">&#34;jupyter&#34;</span> <span style="color:#e6db74">&#34;qtconsole&#34;</span> <span style="color:#e6db74">&#34;--existing&#34;</span>
(<span style="color:#a6e22e">file-name-nondirectory</span> (my/select-jupyter-kernel))))
</code></pre></div><p>I&rsquo;ve also noticed that there are JSON files left in the runtime folder whenever the kernel isn&rsquo;t stopped correctly. So here is a cleanup function.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jupyter-cleanup-kernels ()
(interactive)
(let* ((ports (my/get-open-ports))
(files (my/list-jupyter-kernel-files))
(to-delete (seq-filter
(lambda (file)
(not (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports)))
files)))
(when (and (length&gt; to-delete <span style="color:#ae81ff">0</span>)
(y-or-n-p (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;Delete %d files?&#34;</span> (<span style="color:#a6e22e">length</span> to-delete))))
(dolist (file to-delete)
(<span style="color:#a6e22e">delete-file</span> (<span style="color:#a6e22e">car</span> file))))))
</code></pre></div><h4 id="do-not-wrap-the-output-in-emacs-jupyter">Do not wrap the output in emacs-jupyter</h4>
<p>Emacs-jupyter has its own insertion mechanisms, which always prepends output statements with <code>:</code>. That is not desirable in cases where a kernel supports only plain output, e.g. calysto_hy kernel.</p>
<p>So there we have a minor mode that overrides this behavior.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jupyter-org-scalar (value)
(cond
((<span style="color:#a6e22e">stringp</span> value) value)
(<span style="color:#66d9ef">t</span> (jupyter-org-scalar value))))
(define-minor-mode my/emacs-jupyter-raw-output
<span style="color:#e6db74">&#34;Make emacs-jupyter do raw output&#34;</span>)
(defun my/jupyter-org-scalar-around (fun value)
(if my/emacs-jupyter-raw-output
(my/jupyter-org-scalar value)
(<span style="color:#a6e22e">funcall</span> fun value)))
(advice-add <span style="color:#e6db74">&#39;jupyter-org-scalar</span> :around <span style="color:#a6e22e">#&#39;</span>my/jupyter-org-scalar-around)
</code></pre></div><h4 id="wrap-source-code-output">Wrap source code output</h4>
<p>A function to remove :RESULTS: drawer from the results. Once again, necessary because emacs-jupyter doesn&rsquo;t seem to respect :results raw.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-strip-results (data)
(replace-regexp-in-string <span style="color:#e6db74">&#34;:\\(RESULTS\\|END\\):\n&#34;</span> <span style="color:#e6db74">&#34;&#34;</span> data))
</code></pre></div><p>And an all-in-one function to:</p>
<ul>
<li>prepend <code>#+NAME:</code> and <code>#+CAPTION:</code> to the source block output. Useful if the output is an image.</li>
<li>strip :RESULTS: drawer from the output, if necessary</li>
<li>wrap results in the <code>src</code> block</li>
</ul>
<p>As for now, looks sufficient to format source code outputs to get a tolerable LaTeX.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-caption-wrap (data <span style="color:#66d9ef">&amp;optional</span> name caption attrs strip-drawer src-wrap)
(let* ((data-s (if (and strip-drawer (not (string-empty-p strip-drawer)))
(my/org-strip-results data)
data))
(drawer-start (if (string-match-p <span style="color:#e6db74">&#34;^:RESULTS:.*&#34;</span> data-s) <span style="color:#ae81ff">10</span> <span style="color:#ae81ff">0</span>)))
(<span style="color:#a6e22e">concat</span>
(<span style="color:#a6e22e">substring</span> data-s <span style="color:#ae81ff">0</span> drawer-start)
(and name (not (string-empty-p name)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;#+NAME:&#34;</span> name <span style="color:#e6db74">&#34;\n&#34;</span>))
(and caption (not (string-empty-p caption)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;#+CAPTION:&#34;</span> caption <span style="color:#e6db74">&#34;\n&#34;</span>))
(and attrs (not (string-empty-p attrs)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;#+ATTR_LATEX:&#34;</span> attrs <span style="color:#e6db74">&#34;\n&#34;</span>))
(if (and src-wrap (not (string-empty-p src-wrap)))
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;#+begin_src &#34;</span> src-wrap <span style="color:#e6db74">&#34;\n&#34;</span>
(<span style="color:#a6e22e">substring</span> data-s drawer-start)
(when (not (string-match-p <span style="color:#e6db74">&#34;.*\n&#34;</span> data-s)) <span style="color:#e6db74">&#34;\n&#34;</span>)
<span style="color:#e6db74">&#34;#+end_src&#34;</span>)
(<span style="color:#a6e22e">substring</span> data-s drawer-start)))))
</code></pre></div><p>To use, add the following snippet to the org file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">#+NAME: out_wrap
#+begin_src emacs-lisp :var data=&#34;&#34; caption=&#34;&#34; name=&#34;&#34; attrs=&#34;&#34; strip-drawer=&#34;&#34; src-wrap=&#34;&#34; :tangle no :exports none
(my/org-caption-wrap data name caption attrs strip-drawer src-wrap)
#+end_src
</code></pre></div><p>Example usage:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">:post out_wrap(name=&#34;fig:chart&#34;, caption=&#34;График&#34;, data=*this*)
</code></pre></div><h3 id="productivity-and-knowledge-management">Productivity &amp; Knowledge management</h3>
<p>My ongoing effort to get a productivity setup in Org.</p>
<p>Some inspiration:</p>
<ul>
<li><a href="https://www.labri.fr/perso/nrougier/GTD/index.html">Nicolas P. Rougier. Get Things Done with Emacs</a></li>
<li><a href="https://blog.jethro.dev/posts/org%5Fmode%5Fworkflow%5Fpreview/">Jetro Kuan. Org-mode Workflow</a></li>
<li><a href="https://www.alexeyshmalko.com/how-i-note/">Alexey Shmalko: How I note</a></li>
<li><a href="https://rgoswami.me/posts/org-note-workflow/">Rohit Goswami: An Orgmode Note Workflow</a></li>
</ul>
<p>Used files</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~/Documents/org-mode&#34;</span>))
(setq org-agenda-files <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;inbox.org&#34;</span> <span style="color:#e6db74">&#34;projects.org&#34;</span> <span style="color:#e6db74">&#34;work.org&#34;</span> <span style="color:#e6db74">&#34;sem-11.org&#34;</span> <span style="color:#e6db74">&#34;life.org&#34;</span>))
<span style="color:#75715e">;; (setq org-default-notes-file (concat org-directory &#34;/notes.org&#34;))</span>
</code></pre></div><p>Hotkeys</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;o&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;org-mode&#34;</span>)
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;org-capture</span>
<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#e6db74">&#39;org-agenda</span>)
</code></pre></div><p>Refile targets</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-refile-targets
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;projects.org&#34;</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)
(<span style="color:#e6db74">&#34;work.org&#34;</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)
(<span style="color:#e6db74">&#34;sem-11.org&#34;</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">3</span>)
(<span style="color:#e6db74">&#34;life.org&#34;</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)))
(setq org-refile-use-outline-path <span style="color:#e6db74">&#39;file</span>)
(setq org-outline-path-complete-in-steps <span style="color:#66d9ef">nil</span>)
</code></pre></div><h4 id="capture-templates-and-various-settings">Capture templates &amp; various settings</h4>
<p>Settings for Org capture mode. The goal here is to have a non-disruptive process to capture various ideas.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-capture-templates
<span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#e6db74">&#34;Inbox&#34;</span> entry (file <span style="color:#e6db74">&#34;inbox.org&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;* TODO %?\n&#34;</span>
<span style="color:#e6db74">&#34;/Entered on/ %U&#34;</span>))
(<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#34;email&#34;</span> entry (file <span style="color:#e6db74">&#34;inbox.org&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;* TODO %:from %:subject \n&#34;</span>
<span style="color:#e6db74">&#34;/Entered on/ %U\n&#34;</span>
<span style="color:#e6db74">&#34;/Received on/ %:date-timestamp-inactive\n&#34;</span>
<span style="color:#e6db74">&#34;%a\n&#34;</span>))
(<span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#e6db74">&#34;elfeed&#34;</span> entry (file <span style="color:#e6db74">&#34;inbox.org&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;* TODO %:elfeed-entry-title\n&#34;</span>
<span style="color:#e6db74">&#34;/Entered on/ %U\n&#34;</span>
<span style="color:#e6db74">&#34;%a\n&#34;</span>))))
</code></pre></div><p>Effort estimation</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-to-list <span style="color:#e6db74">&#39;org-global-properties</span>
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;Effort_ALL&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;0 0:05 0:10 0:15 0:30 0:45 1:00 2:00 4:00&#34;</span>))
</code></pre></div><p>Log DONE time</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-log-done <span style="color:#e6db74">&#39;time</span>)
</code></pre></div><h4 id="custom-agendas">Custom agendas</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-scheduled-get-time ()
(let ((scheduled (org-get-scheduled-time (<span style="color:#a6e22e">point</span>))))
(if scheduled
(<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">&#34;%Y-%m-%d&#34;</span> scheduled)
<span style="color:#e6db74">&#34;&#34;</span>)))
(setq org-agenda-custom-commands
<span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#34;My outline&#34;</span>
((agenda <span style="color:#e6db74">&#34;&#34;</span>)
(todo <span style="color:#e6db74">&#34;NEXT&#34;</span>
((org-agenda-prefix-format <span style="color:#e6db74">&#34; %i %-12:c [%e] &#34;</span>)
(org-agenda-overriding-header <span style="color:#e6db74">&#34;Next tasks&#34;</span>)))
(tags-todo <span style="color:#e6db74">&#34;inbox&#34;</span>
((org-agenda-overriding-header <span style="color:#e6db74">&#34;Inbox&#34;</span>)
(org-agenda-prefix-format <span style="color:#e6db74">&#34; %i %-12:c&#34;</span>)
(org-agenda-hide-tags-regexp <span style="color:#e6db74">&#34;.&#34;</span>)))
(tags-todo <span style="color:#e6db74">&#34;+waitlist+SCHEDULED&lt;=\&#34;&lt;+14d&gt;\&#34;&#34;</span>
((org-agenda-overriding-header <span style="color:#e6db74">&#34;Waitlist&#34;</span>)
(org-agenda-hide-tags-regexp <span style="color:#e6db74">&#34;waitlist&#34;</span>)
(org-agenda-prefix-format <span style="color:#e6db74">&#34; %i %-12:c %-12(my/org-scheduled-get-time)&#34;</span>)))))
(<span style="color:#e6db74">&#34;tp&#34;</span> <span style="color:#e6db74">&#34;Personal tasks&#34;</span>
((tags-todo <span style="color:#e6db74">&#34;personal&#34;</span>
((org-agenda-prefix-format <span style="color:#e6db74">&#34; %i %-12:c [%e] &#34;</span>)))))))
</code></pre></div><h4 id="org-ql">org-ql</h4>
<p><a href="https://github.com/alphapapa/org-ql">org-ql</a> is a package to query the org files. I&rsquo;m using it in my review workflow, perhaps later I&rsquo;ll find another usecases.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-ql
:straight (:fetcher github
:repo <span style="color:#e6db74">&#34;alphapapa/org-ql&#34;</span>
:files (:defaults (:exclude <span style="color:#e6db74">&#34;helm-org-ql.el&#34;</span>))))
</code></pre></div><h4 id="review-workflow">Review workflow</h4>
<p>My take on a review workflow. As a baseline, I want to have a template that lists the important changes since the last review and other basic information. I&rsquo;m doing reviews regularly, but the time intervals still may vary, hence this flexibility.</p>
<h5 id="data-from-git-and-org-roam">Data from git &amp; org-roam</h5>
<p>First, as I have <a href="/configs/console/">autocommit</a> set up in my org directory, here is a handy function to get an alist of changed files of a form <code>(status . path)</code>. In principle, the <code>rev</code> parameter can be a commit, tag, etc but here I&rsquo;m interested in a form like <code>@{2021-08-30}</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/git-diff-status
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;A&#34;</span> <span style="color:#f92672">.</span> added)
(<span style="color:#e6db74">&#34;C&#34;</span> <span style="color:#f92672">.</span> copied)
(<span style="color:#e6db74">&#34;D&#34;</span> <span style="color:#f92672">.</span> deleted)
(<span style="color:#e6db74">&#34;M&#34;</span> <span style="color:#f92672">.</span> modified)
(<span style="color:#e6db74">&#34;R&#34;</span> <span style="color:#f92672">.</span> renamed)
(<span style="color:#e6db74">&#34;T&#34;</span> <span style="color:#f92672">.</span> type-changed)
(<span style="color:#e6db74">&#34;U&#34;</span> <span style="color:#f92672">.</span> unmerged)))
(defun my/get-files-status (rev)
(let ((files (shell-command-to-string (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;git diff --name-status &#34;</span> rev))))
(<span style="color:#a6e22e">mapcar</span>
(lambda (file)
(let ((elems (split-string file <span style="color:#e6db74">&#34;\t&#34;</span>)))
(<span style="color:#a6e22e">cons</span>
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> (<span style="color:#a6e22e">car</span> elems) my/git-diff-status))
(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elems))))
(split-string files <span style="color:#e6db74">&#34;\n&#34;</span> <span style="color:#66d9ef">t</span>))))
</code></pre></div><p>I&rsquo;ll use it to get a list of added and changed Roam files since the last review. Date should have be in a format <code>YYYY-MM-DD</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-changed-files-since-date (date)
(let ((default-directory org-directory))
(my/get-files-status (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;@{%s}&#34;</span> date))))
</code></pre></div><p>Now we are ready to format this list to insert it into the capture template.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-roam (rev)
(let* ((changes (my/org-changed-files-since-date rev))
(new-roam
(seq-filter
(lambda (elem)
(and (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">car</span> elem) <span style="color:#e6db74">&#39;added</span>)
(string-match-p (rx bos <span style="color:#e6db74">&#34;roam&#34;</span>) (<span style="color:#a6e22e">cdr</span> elem))))
changes))
(changed-roam
(seq-filter
(lambda (elem)
(and (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">car</span> elem) <span style="color:#e6db74">&#39;modified</span>)
(string-match-p (rx bos <span style="color:#e6db74">&#34;roam&#34;</span>) (<span style="color:#a6e22e">cdr</span> elem))))
changes)))
(<span style="color:#a6e22e">concat</span>
(unless (seq-empty-p new-roam)
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;** New Roam entries \n&#34;</span>
(<span style="color:#a6e22e">mapconcat</span>
(lambda (entry)
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;- [[file:%s][%s]]&#34;</span> (<span style="color:#a6e22e">cdr</span> entry) (<span style="color:#a6e22e">cdr</span> entry)))
new-roam
<span style="color:#e6db74">&#34;\n&#34;</span>)
<span style="color:#e6db74">&#34;\n&#34;</span>))
(unless (seq-empty-p changed-roam)
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;** Changed Roam entries \n&#34;</span>
(<span style="color:#a6e22e">mapconcat</span>
(lambda (entry)
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;- [[file:%s][%s]]&#34;</span> (<span style="color:#a6e22e">cdr</span> entry) (<span style="color:#a6e22e">cdr</span> entry)))
changed-roam
<span style="color:#e6db74">&#34;\n&#34;</span>))))))
</code></pre></div><h5 id="data-from-org-journal">Data from org-journal</h5>
<p>Second, I want to have a list of new jounal entries since the last review.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-journal-entries-since-date (rev-date)
(<span style="color:#a6e22e">mapcar</span>
(lambda (date)
(let ((time (<span style="color:#a6e22e">encode-time</span> (parse-time-string date))))
<span style="color:#f92672">`</span>((file <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(org-journal--get-entry-path time))
(header <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">format-time-string</span> org-journal-date-format time)))))
(seq-filter
(lambda (date) (<span style="color:#a6e22e">string-lessp</span> rev-date date))
(<span style="color:#a6e22e">mapcar</span>
(lambda (date)
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;%04d-%02d-%02dT00:00:00+0300&#34;</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> date) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> date) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> date)))
(org-journal--list-dates)))))
</code></pre></div><p>Format the results:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-journal (rev-date)
(<span style="color:#a6e22e">mapconcat</span>
(lambda (item)
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;- [[file:%s::*%s][%s]]&#34;</span>
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;file</span> item))
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;header</span> item))
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;header</span> item))))
(my/org-journal-entries-since-date rev-date)
<span style="color:#e6db74">&#34;\n&#34;</span>))
</code></pre></div><h5 id="data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</h5>
<p>Third, I want to list some changes in my agenda. This section will change depending on what I&rsquo;m currently working on.</p>
<p>So, here is a list of queries results of which I want to see in the review template. The format is <code>(name date-field order-by-field query)</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-ql-review-queries
<span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;Waitlist&#34;</span> scheduled scheduled
(and
(done)
(tags-inherited <span style="color:#e6db74">&#34;waitlist&#34;</span>)))
(<span style="color:#e6db74">&#34;Personal tasks done&#34;</span> closed <span style="color:#f92672">,</span><span style="color:#66d9ef">nil</span>
(and
(tags-inherited <span style="color:#e6db74">&#34;personal&#34;</span>)
(todo <span style="color:#e6db74">&#34;DONE&#34;</span>)))
(<span style="color:#e6db74">&#34;Attended meetings&#34;</span> closed scheduled
(and
(tags-inherited <span style="color:#e6db74">&#34;meeting&#34;</span>)
(todo <span style="color:#e6db74">&#34;PASSED&#34;</span>)))
(<span style="color:#e6db74">&#34;Done project tasks&#34;</span> closed deadline
(and
(todo <span style="color:#e6db74">&#34;DONE&#34;</span>)
(ancestors
(heading <span style="color:#e6db74">&#34;Tasks&#34;</span>))))))
</code></pre></div><p>The query will be executed like this: <code>(and (date-field :from rev-date) query)</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-exec-ql (saved rev-date)
(let ((query <span style="color:#f92672">`</span>(and
(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> saved) :from <span style="color:#f92672">,</span>rev-date)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">3</span> saved))))
(org-ql-query
:select <span style="color:#a6e22e">#&#39;</span>element
:from (org-agenda-files)
:where query
:order-by (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> saved))))
</code></pre></div><p>Format one element of query result.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-element (elem)
(<span style="color:#a6e22e">concat</span>
(string-pad
(<span style="color:#a6e22e">plist-get</span> (cadr elem) :raw-value)
<span style="color:#ae81ff">40</span>)
(when-let (scheduled (<span style="color:#a6e22e">plist-get</span> (cadr elem) :scheduled))
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34; [SCHEDULED: &#34;</span> (<span style="color:#a6e22e">plist-get</span> (cadr scheduled) :raw-value) <span style="color:#e6db74">&#34;]&#34;</span>))
(when-let (deadline (<span style="color:#a6e22e">plist-get</span> (cadr elem) :deadline))
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34; [DEADLINE: &#34;</span> (<span style="color:#a6e22e">plist-get</span> (cadr deadline) :raw-value) <span style="color:#e6db74">&#34;]&#34;</span>))))
</code></pre></div><p>Execute all the saved queries and format an Org list for the capture template.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-queries (rev-date)
(<span style="color:#a6e22e">mapconcat</span>
(lambda (results)
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;** &#34;</span> (<span style="color:#a6e22e">car</span> results) <span style="color:#e6db74">&#34;\n&#34;</span>
(string-join
(<span style="color:#a6e22e">mapcar</span> (lambda (r) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;- &#34;</span> r)) (<span style="color:#a6e22e">cdr</span> results))
<span style="color:#e6db74">&#34;\n&#34;</span>)
<span style="color:#e6db74">&#34;\n&#34;</span>))
(seq-filter
(lambda (result)
(not (seq-empty-p (<span style="color:#a6e22e">cdr</span> result))))
(<span style="color:#a6e22e">mapcar</span>
(lambda (saved)
(<span style="color:#a6e22e">cons</span>
(<span style="color:#a6e22e">car</span> saved)
(<span style="color:#a6e22e">mapcar</span>
<span style="color:#a6e22e">#&#39;</span>my/org-review-format-element
(my/org-review-exec-ql saved rev-date))))
my/org-ql-review-queries))
<span style="color:#e6db74">&#34;\n&#34;</span>))
</code></pre></div><h5 id="capture-template">Capture template</h5>
<p>Now, we have to put all this together and define a capture template for the review.</p>
<p>I&rsquo;ll use a separate directory for the review files, just like for org-journal and org-roam. The filename will have a format <code>YYYY-MM-DD.org</code>, which will also free me from the effort of storing the last review date somewhere.</p>
<p>If somehow there are no files in the folder, fallback to the current date minus one week.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-review-directory <span style="color:#e6db74">&#34;review&#34;</span>)
(defun my/org-review-get-filename ()
(<span style="color:#a6e22e">concat</span> my/org-review-directory <span style="color:#e6db74">&#34;/&#34;</span> (<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">&#34;%Y-%m-%d.org&#34;</span> (<span style="color:#a6e22e">current-time</span>))))
(defun my/get-last-review-date ()
(<span style="color:#a6e22e">substring</span>
(or
(-max-by
<span style="color:#e6db74">&#39;string-greaterp</span>
(-filter
(lambda (f) (not (or (<span style="color:#a6e22e">string-equal</span> f <span style="color:#e6db74">&#34;.&#34;</span>) (<span style="color:#a6e22e">string-equal</span> f <span style="color:#e6db74">&#34;..&#34;</span>))))
(<span style="color:#a6e22e">directory-files</span> (f-join org-directory my/org-review-directory))))
(<span style="color:#a6e22e">format-time-string</span>
<span style="color:#e6db74">&#34;%Y-%m-%d&#34;</span>
(<span style="color:#a6e22e">time-subtract</span>
(<span style="color:#a6e22e">current-time</span>)
(seconds-to-time (<span style="color:#a6e22e">*</span> <span style="color:#ae81ff">60</span> <span style="color:#ae81ff">60</span> <span style="color:#ae81ff">24</span> <span style="color:#ae81ff">7</span>)))))
<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">10</span>))
</code></pre></div><p>A template looks like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-review-capture-template
<span style="color:#f92672">`</span>(<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#34;Review&#34;</span> plain (file <span style="color:#f92672">,</span>(my/org-review-get-filename))
<span style="color:#f92672">,</span>(string-join
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;#+TITLE: Review %t&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span>
<span style="color:#e6db74">&#34;Last review date: %(org-timestamp-translate (org-timestamp-from-string (format \&#34;&lt;%s&gt;\&#34; (my/get-last-review-date))))&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span>
<span style="color:#e6db74">&#34;* Roam&#34;</span>
<span style="color:#e6db74">&#34;%(my/org-review-format-roam (my/get-last-review-date))&#34;</span>
<span style="color:#e6db74">&#34;* Journal&#34;</span>
<span style="color:#e6db74">&#34;New journal entries:&#34;</span>
<span style="color:#e6db74">&#34;%(my/org-review-format-journal (my/get-last-review-date))&#34;</span>
<span style="color:#e6db74">&#34;* Agenda&#34;</span>
<span style="color:#e6db74">&#34;%(my/org-review-format-queries (my/get-last-review-date))&#34;</span>
<span style="color:#e6db74">&#34;* Thoughts :crypt:&#34;</span>
<span style="color:#e6db74">&#34;%?&#34;</span>)
<span style="color:#e6db74">&#34;\n&#34;</span>)))
(add-to-list <span style="color:#e6db74">&#39;org-capture-templates</span> my/org-review-capture-template <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="org-journal">Org Journal</h4>
<p><a href="https://github.com/bastibe/org-journal">org-journal</a> is a plugin for maintaining a journal in org mode. I want to have its entries separate from my knowledge base.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-journal
:straight <span style="color:#66d9ef">t</span>
:if (not my/remote-server)
:after org
:config
(setq org-journal-dir (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">&#34;/journal&#34;</span>))
(setq org-journal-file-type <span style="color:#e6db74">&#39;weekly</span>)
(setq org-journal-file-format <span style="color:#e6db74">&#34;%Y-%m-%d.org&#34;</span>)
(setq org-journal-date-format <span style="color:#e6db74">&#34;%A, %Y-%m-%d&#34;</span>)
(setq org-journal-enable-encryption <span style="color:#66d9ef">t</span>))
(my-leader-def
:infix <span style="color:#e6db74">&#34;oj&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;org-journal&#34;</span>)
<span style="color:#e6db74">&#34;j&#34;</span> <span style="color:#e6db74">&#39;org-journal-new-entry</span>
<span style="color:#e6db74">&#34;o&#34;</span> <span style="color:#e6db74">&#39;org-journal-open-current-journal-file</span>
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;org-journal-search</span>)
</code></pre></div><p>Also, I want to store some information in the journal as properties of the record. So below is a function which does just that.</p>
<p>As of now, it stores Emacs version, hostname, location and current EMMS track if there is one.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-journal-header ()
(org-set-property <span style="color:#e6db74">&#34;Emacs&#34;</span> emacs-version)
(org-set-property <span style="color:#e6db74">&#34;Hostname&#34;</span> <span style="color:#a6e22e">system-name</span>)
(when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;my/location</span>)
(org-set-property <span style="color:#e6db74">&#34;Location&#34;</span> my/location))
(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">&#39;emms-playlist-current-selected-track</span>)
(let ((track (emms-playlist-current-selected-track)))
(when track
(let ((album (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;info-album</span> track)))
(artist (or (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;info-albumartist</span> track))
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;info-album</span> track))))
(title (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;info-title</span> track)))
(<span style="color:#a6e22e">string</span> <span style="color:#e6db74">&#34;&#34;</span>))
(when artist
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> <span style="color:#e6db74">&#34;[&#34;</span> artist <span style="color:#e6db74">&#34;] &#34;</span>)))
(when album
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> album <span style="color:#e6db74">&#34; - &#34;</span>)))
(when title
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> title)))
(when (<span style="color:#a6e22e">&gt;</span> (<span style="color:#a6e22e">length</span> <span style="color:#a6e22e">string</span>) <span style="color:#ae81ff">0</span>)
(org-set-property <span style="color:#e6db74">&#34;EMMS_Track&#34;</span> <span style="color:#a6e22e">string</span>)))))))
(add-hook <span style="color:#e6db74">&#39;org-journal-after-entry-create-hook</span>
<span style="color:#a6e22e">#&#39;</span>my/set-journal-header)
</code></pre></div><h4 id="org-roam">Org Roam</h4>
<p><a href="https://github.com/org-roam/org-roam">org-roam</a> is a plain-text knowledge database.</p>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>emacs-emacsql-sqlite3</td>
</tr>
<tr>
<td>graphviz</td>
</tr>
</tbody>
</table>
<p>References:</p>
<ul>
<li><a href="https://github.com/org-roam/org-roam/wiki/Hitchhiker%27s-Rough-Guide-to-Org-roam-V2">Hitchhiker&rsquo;s Rough Guide to Org roam V2</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package emacsql-sqlite
:defer <span style="color:#66d9ef">t</span>
:straight (:type built-in))
(use-package org-roam
:straight (:host github :repo <span style="color:#e6db74">&#34;org-roam/org-roam&#34;</span>
:files (:defaults <span style="color:#e6db74">&#34;extensions/*.el&#34;</span>))
:if (not my/remote-server)
:after org
:init
(setq org-roam-directory (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">&#34;/roam&#34;</span>))
(setq org-roam-file-extensions <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;org&#34;</span>))
(setq org-roam-v2-ack <span style="color:#66d9ef">t</span>)
(setq orb-insert-interface <span style="color:#e6db74">&#39;ivy-bibtex</span>)
:config
(org-roam-setup)
(setq org-roam-capture-templates
<span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#34;default&#34;</span> plain <span style="color:#e6db74">&#34;%?&#34;</span>
:if-new (file+head <span style="color:#e6db74">&#34;%&lt;%Y%m%d%H%M%S&gt;-${slug}.org&#34;</span> <span style="color:#e6db74">&#34;#+title: ${title}\n&#34;</span>)
:unnarrowed <span style="color:#66d9ef">t</span>)))
(require <span style="color:#e6db74">&#39;org-roam-protocol</span>))
(my-leader-def
:infix <span style="color:#e6db74">&#34;or&#34;</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;org-roam&#34;</span>)
<span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#e6db74">&#39;org-roam-node-insert</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;org-roam-node-find</span>
<span style="color:#e6db74">&#34;g&#34;</span> <span style="color:#e6db74">&#39;org-roam-graph</span>
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;org-roam-capture</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;org-roam-buffer-toggle</span>)
(with-eval-after-load <span style="color:#e6db74">&#39;org</span>
(my-leader-def
:keymap <span style="color:#e6db74">&#39;org-mode-map</span>
:infix <span style="color:#e6db74">&#34;or&#34;</span>
<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#39;org-roam-tag-add</span>
<span style="color:#e6db74">&#34;T&#34;</span> <span style="color:#e6db74">&#39;org-toam-tag-remove</span>)
(general-define-key
:keymap <span style="color:#e6db74">&#39;org-mode-map</span>
<span style="color:#e6db74">&#34;C-c i&#34;</span> <span style="color:#e6db74">&#39;org-id-get-create</span>
<span style="color:#e6db74">&#34;C-c l o&#34;</span> <span style="color:#e6db74">&#39;org-roam-node-insert</span>))
</code></pre></div><h5 id="org-roam-ui">org-roam-ui</h5>
<p>A browser frontend to visualize a Roam directory in a form of a graph.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-roam-ui
:straight (:host github :repo <span style="color:#e6db74">&#34;org-roam/org-roam-ui&#34;</span> :branch <span style="color:#e6db74">&#34;main&#34;</span> :files (<span style="color:#e6db74">&#34;*.el&#34;</span> <span style="color:#e6db74">&#34;out&#34;</span>))
:after org-roam
<span style="color:#75715e">;; :hook (org-roam . org-roam-ui-mode)</span>
:init
(my-leader-def <span style="color:#e6db74">&#34;oru&#34;</span> <span style="color:#a6e22e">#&#39;</span>org-roam-ui-mode))
</code></pre></div><h5 id="org-roam-protocol">org-roam-protocol</h5>
<p>Open links such as <code>org-protocol://</code> from browser. Run <code>M-x server-start</code> for org-protocol to work.</p>
<pre><code class="language-conf" data-lang="conf">[Desktop Entry]
Name=Org-Protocol
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol
</code></pre><p>Don&rsquo;t forget to run the following after setup:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
</code></pre></div><h4 id="org-ref">org-ref</h4>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO</td>
<td>Figure out how not to load Helm</td>
</tr>
</tbody>
</table>
<p><a href="https://github.com/jkitchin/org-ref">org-ref</a> is a package that provides support for various citations &amp; references in Org mode.</p>
<p>Useful to use BibTeX citations in LaTeX export.</p>
<p>As of now, this package loads Helm on start. To avoid this, I have to exclude Helm from the <code>Package-requires</code> in the <a href=".emacs.d/straight/repos/org-ref/org-ref.el">org-ref.el</a> file. I haven&rsquo;t found a way to do this without modifying the package source yet.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-ref
:straight (:files (:defaults (:exclude <span style="color:#e6db74">&#34;*helm*&#34;</span>)))
:if (not my/remote-server)
:init
(setq org-ref-completion-library <span style="color:#e6db74">&#39;org-ref-ivy-cite</span>)
(setq bibtex-dialect <span style="color:#e6db74">&#39;biblatex</span>)
(setq org-ref-default-bibliography <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;~/Documents/org-mode/bibliography.bib&#34;</span>))
(setq reftex-default-bibliography org-ref-default-bibliography)
(setq bibtex-completion-bibliography org-ref-default-bibliography)
:after (org)
:config
(general-define-key
:keymaps <span style="color:#e6db74">&#39;org-mode-map</span>
:infix <span style="color:#e6db74">&#34;C-c l&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;org-ref&#34;</span>)
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;org-ref-ivy-insert-cite-link</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;org-ref-ivy-insert-ref-link</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;org-ref-cite-hydra/body</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;bibtex-mode-map</span>
<span style="color:#e6db74">&#34;M-RET&#34;</span> <span style="color:#e6db74">&#39;org-ref-bibtex-hydra/body</span>)
(add-to-list <span style="color:#e6db74">&#39;orhc-candidate-formats</span>
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;online&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34; |${=key=}| ${title} ${url}&#34;</span>)))
</code></pre></div><h4 id="org-roam-bibtex">org-roam-bibtex</h4>
<p>Integration with bibtex and org-ref.</p>
<p>There are some problems with org roam v2, so I disabled it as of now. I will probably use another way of managing bibliography notes anyway.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-roam-bibtex
:straight (:host github :repo <span style="color:#e6db74">&#34;org-roam/org-roam-bibtex&#34;</span>)
:after (org-roam org-ref)
:disabled
:config
(org-roam-bibtex-mode))
</code></pre></div><h3 id="ui">UI</h3>
<h4 id="off--instant-equations-preview"><span class="org-todo done OFF">OFF</span> (OFF) Instant equations preview</h4>
<p>Instant math previews for org mode.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/yangsheng6810/org-latex-impatient">org-latex-impatient repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-latex-impatient
:straight (:repo <span style="color:#e6db74">&#34;yangsheng6810/org-latex-impatient&#34;</span>
:branch <span style="color:#e6db74">&#34;master&#34;</span>
:host github)
:hook (org-mode <span style="color:#f92672">.</span> org-latex-impatient-mode)
:disabled
:init
(setq org-latex-impatient-tex2svg-bin
<span style="color:#e6db74">&#34;/home/pavel/Programs/miniconda3/lib/node_modules/mathjax-node-cli/bin/tex2svg&#34;</span>)
(setq org-latex-impatient-scale <span style="color:#ae81ff">1.75</span>)
(setq org-latex-impatient-delay <span style="color:#ae81ff">1</span>)
(setq org-latex-impatient-border-color <span style="color:#e6db74">&#34;#ffffff&#34;</span>))
</code></pre></div><h4 id="latex-fragments">LaTeX fragments</h4>
<p>A function to enable LaTeX native highlighting. Not setting this as default, because it loads LaTeX stuff.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/enable-org-latex ()
(interactive)
(customize-set-variable <span style="color:#e6db74">&#39;org-highlight-latex-and-related</span> <span style="color:#f92672">&#39;</span>(native))
(add-hook <span style="color:#e6db74">&#39;org-mode-hook</span> (lambda () (yas-activate-extra-mode <span style="color:#e6db74">&#39;LaTeX-mode</span>)))
(sp-local-pair <span style="color:#e6db74">&#39;org-mode</span> <span style="color:#e6db74">&#34;$&#34;</span> <span style="color:#e6db74">&#34;$&#34;</span>)
(sp--remove-local-pair <span style="color:#e6db74">&#34;&#39;&#34;</span>))
</code></pre></div><p>Call the function before opening an org file or reopen a buffer after calling the function.</p>
<p>Scale latex fragments preview.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-latex-scale <span style="color:#ae81ff">1.75</span>)
(setq org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
</code></pre></div><p>Also, LaTeX fragments preview tends to break whenever the are custom <code>#+LATEX_HEADER</code> entries. To circumvent this, I add a custom header and modify the <code>org-preview-latex-process-alist</code> variable</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-preview-header <span style="color:#e6db74">&#34;\\documentclass{article}
</span><span style="color:#e6db74">\\usepackage[usenames]{color}
</span><span style="color:#e6db74">\\usepackage{graphicx}
</span><span style="color:#e6db74">\\usepackage{grffile}
</span><span style="color:#e6db74">\\usepackage{longtable}
</span><span style="color:#e6db74">\\usepackage{wrapfig}
</span><span style="color:#e6db74">\\usepackage{rotating}
</span><span style="color:#e6db74">\\usepackage[normalem]{ulem}
</span><span style="color:#e6db74">\\usepackage{amsmath}
</span><span style="color:#e6db74">\\usepackage{textcomp}
</span><span style="color:#e6db74">\\usepackage{amssymb}
</span><span style="color:#e6db74">\\usepackage{capt-of}
</span><span style="color:#e6db74">\\usepackage{hyperref}
</span><span style="color:#e6db74">\\pagestyle{empty}&#34;</span>)
(setq org-preview-latex-process-alist
(<span style="color:#a6e22e">mapcar</span>
(lambda (item)
(<span style="color:#a6e22e">cons</span>
(<span style="color:#a6e22e">car</span> item)
(<span style="color:#a6e22e">plist-put</span> (<span style="color:#a6e22e">cdr</span> item) :latex-header my/latex-preview-header)))
org-preview-latex-process-alist))
</code></pre></div><h4 id="better-headers">Better headers</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-superstar
:straight <span style="color:#66d9ef">t</span>
:hook (org-mode <span style="color:#f92672">.</span> org-superstar-mode))
</code></pre></div><h4 id="org-agenda-icons">Org Agenda Icons</h4>
<p>Categories are broad labels to group agenda items.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(if (not my/lowpower)
(setq org-agenda-category-icon-alist
<span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;inbox&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">&#34;inbox&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
(<span style="color:#e6db74">&#34;work&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">&#34;cog&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
(<span style="color:#e6db74">&#34;education&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-material <span style="color:#e6db74">&#34;build&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
(<span style="color:#e6db74">&#34;personal&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">&#34;music&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
(<span style="color:#e6db74">&#34;misc&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-material <span style="color:#e6db74">&#34;archive&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
<span style="color:#75715e">;; (&#34;lesson&#34; ,(list (all-the-icons-faicon &#34;book&#34;)) nil nil :ascent center)</span>
<span style="color:#75715e">;; (&#34;meeting&#34; ,(list (all-the-icons-material &#34;chat&#34;)) nil nil :ascent center)</span>
<span style="color:#75715e">;; (&#34;event&#34; ,(list (all-the-icons-octicon &#34;clock&#34;)) nil nil :ascent center)</span>
(<span style="color:#e6db74">&#34;.&#34;</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">&#34;circle-o&#34;</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center))))
</code></pre></div><h3 id="export">Export</h3>
<h4 id="general-settings">General settings</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-export-backends <span style="color:#f92672">&#39;</span>(md html latex beamer org))
</code></pre></div><h4 id="hugo">Hugo</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ox-hugo
:straight <span style="color:#66d9ef">t</span>
:after ox)
</code></pre></div><h4 id="jupyter-notebook">Jupyter Notebook</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ox-ipynb
:straight (:host github :repo <span style="color:#e6db74">&#34;jkitchin/ox-ipynb&#34;</span>)
:after ox)
</code></pre></div><h4 id="html-export">Html export</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package htmlize
:straight <span style="color:#66d9ef">t</span>
:after ox
:config
(setq org-html-htmlize-output-type <span style="color:#e6db74">&#39;css</span>))
</code></pre></div><h4 id="latex">LaTeX</h4>
<p>Add a custom LaTeX template without default packages. Packages are indented to be imported with function from <a href="#import-dot-sty">Import *.sty</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/setup-org-latex ()
(setq org-latex-prefer-user-labels <span style="color:#66d9ef">t</span>)
(setq org-latex-compiler <span style="color:#e6db74">&#34;xelatex&#34;</span>) <span style="color:#75715e">;; Probably not necessary</span>
(setq org-latex-pdf-process <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;latexmk -outdir=%o %f&#34;</span>)) <span style="color:#75715e">;; Use latexmk</span>
(setq org-latex-listings <span style="color:#e6db74">&#39;minted</span>) <span style="color:#75715e">;; Use minted to highlight source code</span>
(setq org-latex-minted-options <span style="color:#75715e">;; Some minted options I like</span>
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;breaklines&#34;</span> <span style="color:#e6db74">&#34;true&#34;</span>)
(<span style="color:#e6db74">&#34;tabsize&#34;</span> <span style="color:#e6db74">&#34;4&#34;</span>)
(<span style="color:#e6db74">&#34;autogobble&#34;</span>)
(<span style="color:#e6db74">&#34;linenos&#34;</span>)
(<span style="color:#e6db74">&#34;numbersep&#34;</span> <span style="color:#e6db74">&#34;0.5cm&#34;</span>)
(<span style="color:#e6db74">&#34;xleftmargin&#34;</span> <span style="color:#e6db74">&#34;1cm&#34;</span>)
(<span style="color:#e6db74">&#34;frame&#34;</span> <span style="color:#e6db74">&#34;single&#34;</span>)))
<span style="color:#75715e">;; Use extarticle without the default packages</span>
(add-to-list <span style="color:#e6db74">&#39;org-latex-classes</span>
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;org-plain-extarticle&#34;</span>
<span style="color:#e6db74">&#34;\\documentclass{extarticle}
</span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
</span><span style="color:#e6db74">[PACKAGES]
</span><span style="color:#e6db74">[EXTRA]&#34;</span>
(<span style="color:#e6db74">&#34;\\section{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\section*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\subsection{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsection*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\subsubsection{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsubsection*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\paragraph{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\paragraph*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\subparagraph{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subparagraph*{%s}&#34;</span>)))
<span style="color:#75715e">;; Use beamer without the default packages</span>
(add-to-list <span style="color:#e6db74">&#39;org-latex-classes</span>
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;org-latex-beamer&#34;</span>
<span style="color:#e6db74">&#34;\\documentclass{beamer}
</span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
</span><span style="color:#e6db74">[PACKAGES]
</span><span style="color:#e6db74">[EXTRA]&#34;</span>
(<span style="color:#e6db74">&#34;beamer&#34;</span> <span style="color:#e6db74">&#34;\\documentclass[presentation]{beamer}&#34;</span>
(<span style="color:#e6db74">&#34;\\section{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\section*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\subsection{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsection*{%s}&#34;</span>)
(<span style="color:#e6db74">&#34;\\subsubsection{%s}&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsubsection*{%s}&#34;</span>)))))
<span style="color:#75715e">;; Make sure to eval the function when org-latex-classes list already exists</span>
(with-eval-after-load <span style="color:#e6db74">&#39;ox-latex</span>
(my/setup-org-latex))
</code></pre></div><h3 id="keybindings-and-stuff">Keybindings &amp; stuff</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-define-key
:keymaps <span style="color:#e6db74">&#39;org-mode-map</span>
<span style="color:#e6db74">&#34;C-c d&#34;</span> <span style="color:#e6db74">&#39;org-decrypt-entry</span>
<span style="color:#e6db74">&#34;C-c e&#34;</span> <span style="color:#e6db74">&#39;org-encrypt-entry</span>
<span style="color:#e6db74">&#34;M-p&#34;</span> <span style="color:#e6db74">&#39;org-latex-preview</span>
<span style="color:#e6db74">&#34;M-o&#34;</span> <span style="color:#e6db74">&#39;org-redisplay-inline-images</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;org-mode-map</span>
:states <span style="color:#f92672">&#39;</span>(normal emacs)
<span style="color:#e6db74">&#34;L&#34;</span> <span style="color:#e6db74">&#39;org-shiftright</span>
<span style="color:#e6db74">&#34;H&#34;</span> <span style="color:#e6db74">&#39;org-shiftleft</span>
<span style="color:#e6db74">&#34;S-&lt;next&gt;&#34;</span> <span style="color:#e6db74">&#39;org-next-visible-heading</span>
<span style="color:#e6db74">&#34;S-&lt;prior&gt;&#34;</span> <span style="color:#e6db74">&#39;org-previous-visible-heading</span>
<span style="color:#e6db74">&#34;M-0&#34;</span> <span style="color:#e6db74">&#39;org-next-visible-heading</span>
<span style="color:#e6db74">&#34;M-9&#34;</span> <span style="color:#e6db74">&#39;org-previous-visible-heading</span>
<span style="color:#e6db74">&#34;M-]&#34;</span> <span style="color:#e6db74">&#39;org-babel-next-src-block</span>
<span style="color:#e6db74">&#34;M-[&#34;</span> <span style="color:#e6db74">&#39;org-babel-previous-src-block</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;org-agenda-mode-map</span>
<span style="color:#e6db74">&#34;M-]&#34;</span> <span style="color:#e6db74">&#39;org-agenda-later</span>
<span style="color:#e6db74">&#34;M-[&#34;</span> <span style="color:#e6db74">&#39;org-agenda-earlier</span>)
<span style="color:#75715e">;; (general-imap :keymaps &#39;org-mode-map &#34;RET&#34; &#39;evil-org-return)</span>
(general-nmap :keymaps <span style="color:#e6db74">&#39;org-mode-map</span> <span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;org-ctrl-c-ctrl-c</span>)
<span style="color:#75715e">;; (my-leader-def &#34;aa&#34; &#39;org-agenda)</span>
</code></pre></div><h4 id="copy-a-link">Copy a link</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-link-copy (<span style="color:#66d9ef">&amp;optional</span> arg)
<span style="color:#e6db74">&#34;Extract URL from org-mode link and add it to kill ring.&#34;</span>
(interactive <span style="color:#e6db74">&#34;P&#34;</span>)
(let* ((link (org-element-lineage (org-element-context) <span style="color:#f92672">&#39;</span>(link) <span style="color:#66d9ef">t</span>))
(type (org-element-property :type link))
(url (org-element-property :path link))
(url (<span style="color:#a6e22e">concat</span> type <span style="color:#e6db74">&#34;:&#34;</span> url)))
(kill-new url)
(<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;Copied URL: &#34;</span> url))))
(general-nmap :keymaps <span style="color:#e6db74">&#39;org-mode-map</span>
<span style="color:#e6db74">&#34;C-x C-l&#34;</span> <span style="color:#e6db74">&#39;my/org-link-copy</span>)
</code></pre></div><h3 id="presentations">Presentations</h3>
<p>Doing presentations with <a href="https://github.com/rlister/org-present">org-present</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hide-mode-line
:straight <span style="color:#66d9ef">t</span>
:after (org-present))
(defun my/present-next-with-latex ()
(interactive)
(org-present-next)
(org-latex-preview <span style="color:#f92672">&#39;</span>(<span style="color:#ae81ff">16</span>)))
(defun my/present-prev-with-latex ()
(interactive)
(org-present-prev)
(org-latex-preview <span style="color:#f92672">&#39;</span>(<span style="color:#ae81ff">16</span>)))
(use-package org-present
:straight (:host github :repo <span style="color:#e6db74">&#34;rlister/org-present&#34;</span>)
:if (not my/remote-server)
:commands (org-present)
:config
(general-define-key
:keymaps <span style="color:#e6db74">&#39;org-present-mode-keymap</span>
<span style="color:#e6db74">&#34;&lt;next&gt;&#34;</span> <span style="color:#e6db74">&#39;my/present-next-with-latex</span>
<span style="color:#e6db74">&#34;&lt;prior&gt;&#34;</span> <span style="color:#e6db74">&#39;my/present-prev-with-latex</span>)
(add-hook <span style="color:#e6db74">&#39;org-present-mode-hook</span>
(lambda ()
(blink-cursor-mode <span style="color:#ae81ff">0</span>)
(org-present-big)
<span style="color:#75715e">;; (org-display-inline-images)</span>
(org-present-hide-cursor)
(org-present-read-only)
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)
(hide-mode-line-mode <span style="color:#ae81ff">+1</span>)
(setq-local org-format-latex-options
(<span style="color:#a6e22e">plist-put</span> org-format-latex-options
:scale (<span style="color:#a6e22e">*</span> org-present-text-scale my/org-latex-scale <span style="color:#ae81ff">0.5</span>)))
(org-latex-preview <span style="color:#f92672">&#39;</span>(<span style="color:#ae81ff">16</span>))))
(add-hook <span style="color:#e6db74">&#39;org-present-mode-quit-hook</span>
(lambda ()
(blink-cursor-mode <span style="color:#ae81ff">1</span>)
(org-present-small)
<span style="color:#75715e">;; (org-remove-inline-images)</span>
(org-present-show-cursor)
(org-present-read-write)
(display-line-numbers-mode <span style="color:#ae81ff">1</span>)
(hide-mode-line-mode <span style="color:#ae81ff">0</span>)
(setq-local org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
(org-latex-preview <span style="color:#f92672">&#39;</span>(<span style="color:#ae81ff">64</span>)))))
</code></pre></div><h3 id="tools">Tools</h3>
<p>Various small packages.</p>
<h4 id="toc">TOC</h4>
<p>Make a TOC inside the org file.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/alphapapa/org-make-toc">alphapapa/org-make-toc</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-make-toc
:after (org)
:if (not my/remote-server)
:commands
(org-make-toc
org-make-toc-insert
org-make-toc-set
org-make-toc-at-point)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="screenshots">Screenshots</h4>
<p>A nice package to make screenshots and insert them to the Org document.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-attach-screenshot
:commands (org-attach-screenshot)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h3 id="system-configuration">System configuration</h3>
<p>Functions used across my literate config files.</p>
<h4 id="tables-for-guix-dependencies">Tables for Guix Dependencies</h4>
<p>A function to extract Guix dependencies from the org file.</p>
<ul>
<li>If column name matches <code>[G|g]uix.*dep</code>, its contents will be added to the result.</li>
<li>If <code>CATEGORY</code> is passed, a column with name <code>[C|c]ategory</code> will be used to filter results. That way one file can be used to produce multiple manifests.</li>
<li>If <code>CATEGORY</code> is not passed, entries with non-empty category will be filtered out</li>
<li>If there is a <code>[D|d]isabled</code> column, entries that have a non-empty value in this column will be filtered out.</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/extract-guix-dependencies (<span style="color:#66d9ef">&amp;optional</span> category)
(let ((dependencies <span style="color:#f92672">&#39;</span>()))
(org-table-map-tables
(lambda ()
(let* ((table
(seq-filter
(lambda (q) (not (<span style="color:#a6e22e">eq</span> q <span style="color:#e6db74">&#39;hline</span>)))
(org-table-to-lisp)))
(dep-name-index
(cl-position
<span style="color:#66d9ef">nil</span>
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#&#39;substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
:test (lambda (_ elem)
(string-match-p <span style="color:#e6db74">&#34;[G|g]uix.*dep&#34;</span> elem))))
(category-name-index
(cl-position
<span style="color:#66d9ef">nil</span>
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#&#39;substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
:test (lambda (_ elem)
(string-match-p <span style="color:#e6db74">&#34;.*[C|c]ategory.*&#34;</span> elem))))
(disabled-name-index
(cl-position
<span style="color:#66d9ef">nil</span>
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#&#39;substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
:test (lambda (_ elem)
(string-match-p <span style="color:#e6db74">&#34;.*[D|d]isabled.*&#34;</span> elem)))))
(when dep-name-index
(dolist (elem (<span style="color:#a6e22e">cdr</span> table))
(when
(and
<span style="color:#75715e">;; Category</span>
(or
<span style="color:#75715e">;; Category not set and not present in the table</span>
(and
(or (not category) (string-empty-p category))
(not category-name-index))
<span style="color:#75715e">;; Category is set and present in the table</span>
(and
category-name-index
(not (string-empty-p category))
(string-match-p category (<span style="color:#a6e22e">nth</span> category-name-index elem))))
<span style="color:#75715e">;; Not disabled</span>
(or
(not disabled-name-index)
(string-empty-p (<span style="color:#a6e22e">nth</span> disabled-name-index elem))))
(add-to-list
<span style="color:#e6db74">&#39;dependencies</span>
(<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">nth</span> dep-name-index elem)))))))))
dependencies))
</code></pre></div><p>Now, join the dependencies list to make it compatible with Scheme:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/format-guix-dependencies (<span style="color:#66d9ef">&amp;optional</span> category)
(<span style="color:#a6e22e">mapconcat</span>
(lambda (e) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;\&#34;&#34;</span> e <span style="color:#e6db74">&#34;\&#34;&#34;</span>))
(my/extract-guix-dependencies category)
<span style="color:#e6db74">&#34;\n&#34;</span>))
</code></pre></div><h4 id="noweb-evaluations">Noweb evaluations</h4>
<p>Turn off eval confirmations for configuration files.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-config-files
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;/home/pavel/Emacs.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Desktop.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Console.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Guix.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Mail.org&#34;</span>))
(add-hook <span style="color:#e6db74">&#39;org-mode-hook</span>
(lambda ()
(when (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">buffer-file-name</span>) my/org-config-files)
(setq-local org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>))))
</code></pre></div><h4 id="yadm-hook">yadm hook</h4>
<p>A script to run tangle from CLI.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(require <span style="color:#e6db74">&#39;org</span>)
(org-babel-do-load-languages
<span style="color:#e6db74">&#39;org-babel-load-languages</span>
<span style="color:#f92672">&#39;</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
(shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
<span style="color:#75715e">;; Do not ask to confirm evaluations</span>
(setq org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>)
&lt;&lt;guix-tables&gt;&gt;
<span style="color:#75715e">;; A few dummy modes to avoid being prompted for comment systax</span>
(define-derived-mode fish-mode prog-mode <span style="color:#e6db74">&#34;Fish&#34;</span>
(setq-local comment-start <span style="color:#e6db74">&#34;# &#34;</span>)
(setq-local comment-start-skip <span style="color:#e6db74">&#34;#+[\t ]*&#34;</span>))
(define-derived-mode yaml-mode text-mode <span style="color:#e6db74">&#34;YAML&#34;</span>
(setq-local comment-start <span style="color:#e6db74">&#34;# &#34;</span>)
(setq-local comment-start-skip <span style="color:#e6db74">&#34;#+ *&#34;</span>))
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#&#39;</span>org-babel-tangle-file
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;/home/pavel/Emacs.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Desktop.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Console.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Guix.org&#34;</span>
<span style="color:#e6db74">&#34;/home/pavel/Mail.org&#34;</span>))
</code></pre></div><p>To launch from CLI, run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">emacs -Q --batch -l run-tangle.el
</code></pre></div><p>I have added this line to yadm&rsquo;s <code>post_alt</code> hook, so tangle is run after <code>yadm alt</code></p>
<h2 id="off--eaf"><span class="org-todo done OFF">OFF</span> (OFF) EAF</h2>
<p><a href="https://github.com/manateelazycat/emacs-application-framework">Emacs Application Framework</a> provides a way to integrate PyQt applications with Emacs.</p>
<p>I&rsquo;ve made it work, but don&rsquo;t find any uses cases for me at the moment</p>
<h3 id="installation">Installation</h3>
<p>Requirements: Node &gt;= 14</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">pip install qtconsole markdown qrcode<span style="color:#f92672">[</span>pil<span style="color:#f92672">]</span> PyQt5 PyQtWebEngine
</code></pre></div><h3 id="config">Config</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package eaf
:straight (:host github :repo <span style="color:#e6db74">&#34;manateelazycat/emacs-application-framework&#34;</span> :files (<span style="color:#e6db74">&#34;*&#34;</span>))
:init
(use-package epc :defer <span style="color:#66d9ef">t</span> :straight <span style="color:#66d9ef">t</span>)
(use-package ctable :defer <span style="color:#66d9ef">t</span> :straight <span style="color:#66d9ef">t</span>)
(use-package deferred :defer <span style="color:#66d9ef">t</span> :straight <span style="color:#66d9ef">t</span>)
:config
(require <span style="color:#e6db74">&#39;eaf-evil</span>)
(setq eaf-evil-leader-key <span style="color:#e6db74">&#34;SPC&#34;</span>))
</code></pre></div><h2 id="programming">Programming</h2>
<h3 id="general-setup">General setup</h3>
<h4 id="lsp">LSP</h4>
<p>LSP-mode provides an IDE-like experience for Emacs - real-time diagnostic, code actions, intelligent autocompletion, etc.</p>
<p>References:</p>
<ul>
<li><a href="https://emacs-lsp.github.io/lsp-mode/">lsp-mode homepage</a></li>
</ul>
<h5 id="setup">Setup</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lsp-mode
:straight <span style="color:#66d9ef">t</span>
:if (not (or my/slow-ssh my/is-termux my/remote-server))
:hook (
(typescript-mode <span style="color:#f92672">.</span> lsp)
(vue-mode <span style="color:#f92672">.</span> lsp)
(go-mode <span style="color:#f92672">.</span> lsp)
(svelte-mode <span style="color:#f92672">.</span> lsp)
<span style="color:#75715e">;; (python-mode . lsp)</span>
(json-mode <span style="color:#f92672">.</span> lsp)
(haskell-mode <span style="color:#f92672">.</span> lsp)
(haskell-literate-mode <span style="color:#f92672">.</span> lsp)
(java-mode <span style="color:#f92672">.</span> lsp)
<span style="color:#75715e">;; (csharp-mode . lsp)</span>
)
:commands lsp
:config
(setq lsp-idle-delay <span style="color:#ae81ff">1</span>)
(setq lsp-eslint-server-command <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;node&#34;</span> <span style="color:#e6db74">&#34;/home/pavel/.emacs.d/.cache/lsp/eslint/unzipped/extension/server/out/eslintServer.js&#34;</span> <span style="color:#e6db74">&#34;--stdio&#34;</span>))
(setq lsp-eslint-run <span style="color:#e6db74">&#34;onSave&#34;</span>)
(setq lsp-signature-render-documentation <span style="color:#66d9ef">nil</span>)
<span style="color:#75715e">;; (lsp-headerline-breadcrumb-mode nil)</span>
(setq lsp-headerline-breadcrumb-enable <span style="color:#66d9ef">nil</span>)
(add-to-list <span style="color:#e6db74">&#39;lsp-language-id-configuration</span> <span style="color:#f92672">&#39;</span>(svelte-mode <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;svelte&#34;</span>)))
(use-package lsp-ui
:straight <span style="color:#66d9ef">t</span>
:commands lsp-ui-mode
:config
(setq lsp-ui-doc-delay <span style="color:#ae81ff">2</span>)
(setq lsp-ui-sideline-show-hover <span style="color:#66d9ef">nil</span>))
</code></pre></div><h5 id="integrations">Integrations</h5>
<p>The only integration left now is treemacs.</p>
<p>Origami should&rsquo;ve leveraged LSP folding, but it was too unstable at the moment I tried it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (use-package helm-lsp</span>
<span style="color:#75715e">;; :straight t</span>
<span style="color:#75715e">;; :commands helm-lsp-workspace-symbol)</span>
<span style="color:#75715e">;; (use-package origami</span>
<span style="color:#75715e">;; :straight t</span>
<span style="color:#75715e">;; :hook (prog-mode . origami-mode))</span>
<span style="color:#75715e">;; (use-package lsp-origami</span>
<span style="color:#75715e">;; :straight t</span>
<span style="color:#75715e">;; :config</span>
<span style="color:#75715e">;; (add-hook &#39;lsp-after-open-hook #&#39;lsp-origami-try-enable))</span>
(use-package lsp-treemacs
:after (lsp)
:straight <span style="color:#66d9ef">t</span>
:commands lsp-treemacs-errors-list)
</code></pre></div><h5 id="keybindings">Keybindings</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:infix <span style="color:#e6db74">&#34;l&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;lsp&#34;</span>)
<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#39;lsp-ui-peek-find-definitions</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;lsp-rename</span>
<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;lsp-ui-peek-find-references</span>
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;lsp-ui-find-workspace-symbol</span>
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;lsp-execute-code-action</span>
<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#39;list-flycheck-errors</span>)
</code></pre></div><h4 id="flycheck">Flycheck</h4>
<p>A syntax checking extension for Emacs. Integrates with LSP-mode, but can also use various standalone checkers.</p>
<p>References:</p>
<ul>
<li><a href="https://www.flycheck.org/en/latest/">Flycheck homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package flycheck
:straight <span style="color:#66d9ef">t</span>
:config
(global-flycheck-mode)
(setq flycheck-check-syntax-automatically <span style="color:#f92672">&#39;</span>(save idle-buffer-switch mode-enabled))
<span style="color:#75715e">;; (add-hook &#39;evil-insert-state-exit-hook</span>
<span style="color:#75715e">;; (lambda ()</span>
<span style="color:#75715e">;; (if flycheck-checker</span>
<span style="color:#75715e">;; (flycheck-buffer))</span>
<span style="color:#75715e">;; ))</span>
(advice-add <span style="color:#e6db74">&#39;flycheck-eslint-config-exists-p</span> :override (lambda() <span style="color:#66d9ef">t</span>))
(add-to-list <span style="color:#e6db74">&#39;display-buffer-alist</span>
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx bos <span style="color:#e6db74">&#34;*Flycheck errors*&#34;</span> eos)
(display-buffer-reuse-window
display-buffer-in-side-window)
(side <span style="color:#f92672">.</span> bottom)
(reusable-frames <span style="color:#f92672">.</span> visible)
(window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>))))
</code></pre></div><h4 id="tree-sitter">Tree Sitter</h4>
<p>An incremental code parsing system, constructing a syntax tree at runtime.</p>
<p>Right now it doesn&rsquo;t do much except provide a better syntax highlighting than regexes, but this integration is a rather recent development. There are already some major modes built on top of this thing.</p>
<p>Also, it seems to break if ran from mmm-mode, so there is a small workaround.</p>
<p>References:</p>
<ul>
<li><a href="https://tree-sitter.github.io/tree-sitter/">Tree-sitter library</a></li>
<li><a href="https://ubolonton.github.io/emacs-tree-sitter/">Emacs Tree-sitter</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/tree-sitter-if-not-mmm ()
(when (not (and (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;mmm-temp-buffer-name</span>)
(<span style="color:#a6e22e">string-equal</span> mmm-temp-buffer-name (<span style="color:#a6e22e">buffer-name</span>))))
(tree-sitter-mode)
(tree-sitter-hl-mode)))
(use-package tree-sitter
:straight <span style="color:#66d9ef">t</span>
:if (not my/remote-server)
:hook ((typescript-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
(js-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
(python-mode <span style="color:#f92672">.</span> tree-sitter-mode)
(python-mode <span style="color:#f92672">.</span> tree-sitter-hl-mode)
(csharp-mode <span style="color:#f92672">.</span> tree-sitter-mode)))
(use-package tree-sitter-langs
:straight <span style="color:#66d9ef">t</span>
:after tree-sitter)
</code></pre></div><h4 id="off--dap"><span class="org-todo done OFF">OFF</span> (OFF) DAP</h4>
<p>An Emacs client for Debugger Adapter Protocol.</p>
<p>I don&rsquo;t use it now, because there are debuggers I like more for the technologies I&rsquo;m currently using.</p>
<p>References:</p>
<ul>
<li><a href="https://emacs-lsp.github.io/dap-mode/">dap-mode homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dap-mode
:straight <span style="color:#66d9ef">t</span>
:defer <span style="color:#66d9ef">t</span>
:init
(setq lsp-enable-dap-auto-configure <span style="color:#66d9ef">nil</span>)
:config
(setq dap-ui-variable-length <span style="color:#ae81ff">100</span>)
(require <span style="color:#e6db74">&#39;dap-node</span>)
(dap-node-setup)
(require <span style="color:#e6db74">&#39;dap-chrome</span>)
(dap-chrome-setup)
(require <span style="color:#e6db74">&#39;dap-python</span>)
(dap-mode <span style="color:#ae81ff">1</span>)
(dap-ui-mode <span style="color:#ae81ff">1</span>)
(dap-tooltip-mode <span style="color:#ae81ff">1</span>)
(tooltip-mode <span style="color:#ae81ff">1</span>)
(dap-ui-controls-mode <span style="color:#ae81ff">1</span>))
(my-leader-def
:infix <span style="color:#e6db74">&#34;d&#34;</span>
<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#39;dap-debug</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;dap-breakpoint-toggle</span>
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;dap-breakpoint-condition</span>
<span style="color:#e6db74">&#34;wl&#34;</span> <span style="color:#e6db74">&#39;dap-ui-locals</span>
<span style="color:#e6db74">&#34;wb&#34;</span> <span style="color:#e6db74">&#39;dap-ui-breakpoints</span>
<span style="color:#e6db74">&#34;wr&#34;</span> <span style="color:#e6db74">&#39;dap-ui-repl</span>
<span style="color:#e6db74">&#34;ws&#34;</span> <span style="color:#e6db74">&#39;dap-ui-sessions</span>
<span style="color:#e6db74">&#34;we&#34;</span> <span style="color:#e6db74">&#39;dap-ui-expressions</span>)
(my-leader-def
:infix <span style="color:#e6db74">&#34;d&#34;</span>
:keymaps <span style="color:#e6db74">&#39;dap-mode-map</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;dap-hydra</span>)
(defun my/dap-yank-value-at-point (node)
(interactive (<span style="color:#a6e22e">list</span> (treemacs-node-at-point)))
(kill-new (<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">plist-get</span> (button-get node :item) :value))))
</code></pre></div><h4 id="off--tabnine"><span class="org-todo done OFF">OFF</span> (OFF) TabNine</h4>
<p>A ML-based autocompletion system.</p>
<p>More often than not gives really good results, but is slow as hell &amp; consumes a lot of RAM. Also, LSP-provided completions were more useful in my experience.</p>
<p>References:</p>
<ul>
<li><a href="https://www.tabnine.com/">TabNine Homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package company-tabnine
:straight <span style="color:#66d9ef">t</span>
:if (not my/lowpower)
:after company
:config
(add-to-list <span style="color:#e6db74">&#39;company-backends</span> <span style="color:#a6e22e">#&#39;</span>company-tabnine))
</code></pre></div><h4 id="off--code-compass"><span class="org-todo done OFF">OFF</span> (OFF) Code Compass</h4>
<p>A set of code analyzing tools.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/ag91/code-compass">code-compass repo</a></li>
</ul>
<h5 id="dependencies">Dependencies</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package async
:straight <span style="color:#66d9ef">t</span>)
(use-package dash
:straight <span style="color:#66d9ef">t</span>)
(use-package f
:straight <span style="color:#66d9ef">t</span>)
(use-package s
:straight <span style="color:#66d9ef">t</span>)
(use-package simple-httpd
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h5 id="plugin">Plugin</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package code-compass
:straight (
:repo <span style="color:#e6db74">&#34;ag91/code-compass&#34;</span>
:files (<span style="color:#e6db74">&#34;code-compass.el&#34;</span>)
:branch <span style="color:#e6db74">&#34;main&#34;</span>
))
</code></pre></div><h4 id="reformatter">Reformatter</h4>
<p>A general-purpose package to run formattters on files. While the most popular formatters are already packaged for Emacs, those that aren&rsquo;t can be invoked with this package.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package reformatter
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="general-additional-config">General additional config</h4>
<p>Make smartparens behave the way I like for C-like languages.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-smartparens-indent (mode)
(sp-local-pair mode <span style="color:#e6db74">&#34;{&#34;</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;|| &#34;</span> <span style="color:#e6db74">&#34;SPC&#34;</span>) (<span style="color:#e6db74">&#34;||\n[i]&#34;</span> <span style="color:#e6db74">&#34;RET&#34;</span>)))
(sp-local-pair mode <span style="color:#e6db74">&#34;[&#34;</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;|| &#34;</span> <span style="color:#e6db74">&#34;SPC&#34;</span>) (<span style="color:#e6db74">&#34;||\n[i]&#34;</span> <span style="color:#e6db74">&#34;RET&#34;</span>)))
(sp-local-pair mode <span style="color:#e6db74">&#34;(&#34;</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;|| &#34;</span> <span style="color:#e6db74">&#34;SPC&#34;</span>) (<span style="color:#e6db74">&#34;||\n[i]&#34;</span> <span style="color:#e6db74">&#34;RET&#34;</span>))))
</code></pre></div><p>Override flycheck checker with eslint.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-flycheck-eslint()
<span style="color:#e6db74">&#34;Override flycheck checker with eslint.&#34;</span>
(setq-local lsp-diagnostic-package :none)
(setq-local flycheck-checker <span style="color:#e6db74">&#39;javascript-eslint</span>))
</code></pre></div><h3 id="web-development">Web development</h3>
<p>Configs for various web development technologies I&rsquo;m using.</p>
<h4 id="emmet">Emmet</h4>
<p><a href="https://emmet.io/">Emmet</a> is a toolkit which greatly speeds up typing HTML &amp; CSS.</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO</td>
<td>make expand div[disabled] as <div disabled></div></td>
</tr>
</tbody>
</table>
<p>My bit of config here:</p>
<ul>
<li>makes Emmet activate only in certain mmm-mode submodes.</li>
<li>makes <code>TAB</code> the only key I have to use</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package emmet-mode
:straight <span style="color:#66d9ef">t</span>
:hook ((vue-html-mode <span style="color:#f92672">.</span> emmet-mode)
(svelte-mode <span style="color:#f92672">.</span> emmet-mode)
(web-mode <span style="color:#f92672">.</span> emmet-mode)
(html-mode <span style="color:#f92672">.</span> emmet-mode)
(css-mode <span style="color:#f92672">.</span> emmet-mode)
(scss-mode <span style="color:#f92672">.</span> emmet-mode))
:config
<span style="color:#75715e">;; (setq emmet-indent-after-insert nil)</span>
(setq my/emmet-mmm-submodes <span style="color:#f92672">&#39;</span>(vue-html-mode css-mode))
(defun my/emmet-or-tab (<span style="color:#66d9ef">&amp;optional</span> arg)
(interactive)
(if (and
(<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;mmm-current-submode</span>)
mmm-current-submode
(not (<span style="color:#a6e22e">member</span> mmm-current-submode my/emmet-mmm-submodes)))
(indent-for-tab-command arg)
(or (emmet-expand-line arg)
(emmet-go-to-edit-point <span style="color:#ae81ff">1</span>)
(indent-for-tab-command arg))))
(general-imap :keymaps <span style="color:#e6db74">&#39;emmet-mode-keymap</span>
<span style="color:#e6db74">&#34;TAB&#34;</span> <span style="color:#e6db74">&#39;my/emmet-or-tab</span>
<span style="color:#e6db74">&#34;&lt;backtab&gt;&#34;</span> <span style="color:#e6db74">&#39;emmet-prev-edit-point</span>))
</code></pre></div><h4 id="prettier">Prettier</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package prettier
:commands (prettier-prettify)
:straight <span style="color:#66d9ef">t</span>
:init
(my-leader-def
:keymaps <span style="color:#f92672">&#39;</span>(js-mode-map web-mode-map typescript-mode-map vue-mode-map svelte-mode-map)
<span style="color:#e6db74">&#34;rr&#34;</span> <span style="color:#a6e22e">#&#39;</span>prettier-prettify))
</code></pre></div><h4 id="typescript">TypeScript</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package typescript-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.ts\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;typescript-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;typescript-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>rainbow-delimiters-mode)
(add-hook <span style="color:#e6db74">&#39;typescript-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;typescript-mode</span>))
</code></pre></div><h4 id="javascript">JavaScript</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;js-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;js-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;js-mode</span>)
</code></pre></div><h4 id="jest">Jest</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package jest-test-mode
:straight <span style="color:#66d9ef">t</span>
:hook ((typescript-mode <span style="color:#f92672">.</span> jest-test-mode)
(js-mode <span style="color:#f92672">.</span> jest-test-mode))
:config
(my-leader-def
:keymaps <span style="color:#e6db74">&#39;jest-test-mode-map</span>
:infix <span style="color:#e6db74">&#34;t&#34;</span>
<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#39;jest-test-run-at-point</span>
<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#39;jest-test-run</span>
<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#e6db74">&#39;jest-test-run-all-tests</span>))
</code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jest-test-run-at-point-copy ()
<span style="color:#e6db74">&#34;Run the top level describe block of the current buffer&#39;s point.&#34;</span>
(interactive)
(let ((filename (jest-test-find-file))
(example (jest-test-example-at-point)))
(if (and filename example)
(jest-test-from-project-directory filename
(let ((jest-test-options (seq-concatenate <span style="color:#e6db74">&#39;list</span> jest-test-options (<span style="color:#a6e22e">list</span> <span style="color:#e6db74">&#34;-t&#34;</span> example))))
(kill-new (jest-test-command filename))))
(<span style="color:#a6e22e">message</span> jest-test-not-found-message))))
</code></pre></div><h4 id="web-mode">web-mode</h4>
<p><a href="https://web-mode.org/">web-mode.el</a> is a major mode to edit various web templates.</p>
<p>Trying this one out instead of vue-mode and svelte-mode, because this one seems to have better support for tree-sitter and generally less problems.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package web-mode
:straight <span style="color:#66d9ef">t</span>
:init
(add-to-list <span style="color:#e6db74">&#39;auto-mode-alist</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;\\.svelte\\&#39;&#34;</span> <span style="color:#f92672">.</span> web-mode))
(add-to-list <span style="color:#e6db74">&#39;auto-mode-alist</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;\\.vue\\&#39;&#34;</span> <span style="color:#f92672">.</span> web-mode))
:config
(add-hook <span style="color:#e6db74">&#39;web-mode-hook</span> <span style="color:#e6db74">&#39;smartparens-mode</span>)
(add-hook <span style="color:#e6db74">&#39;web-mode-hook</span> <span style="color:#e6db74">&#39;hs-minor-mode</span>)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;web-mode</span>))
</code></pre></div><p>Hooking this up with lsp.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/web-mode-lsp-extensions
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">&#34;.svelte&#34;</span> eos)
<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">&#34;.vue&#34;</span> eos)))
(defun my/web-mode-lsp ()
(when (seq-some
(lambda (regex) (string-match-p regex (<span style="color:#a6e22e">buffer-name</span>)))
my/web-mode-lsp-extensions)
(lsp-deferred)))
(add-hook <span style="color:#e6db74">&#39;web-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>my/web-mode-lsp)
</code></pre></div><p>Vue settings</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/web-mode-vue-setup ()
(when (string-match-p (rx <span style="color:#e6db74">&#34;.vue&#34;</span> eos) (<span style="color:#a6e22e">buffer-name</span>))
(setq-local web-mode-script-padding <span style="color:#ae81ff">0</span>)))
(add-hook <span style="color:#e6db74">&#39;web-mode-hook</span> <span style="color:#e6db74">&#39;my/web-mode-vue-setup</span>)
</code></pre></div><h4 id="off--vue-dot-js"><span class="org-todo done OFF">OFF</span> (OFF) Vue.js</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package vue-mode
:straight <span style="color:#66d9ef">t</span>
:disabled
:mode <span style="color:#e6db74">&#34;\\.vue\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;vue-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(add-hook <span style="color:#e6db74">&#39;vue-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;vue-mode</span>)
(add-hook <span style="color:#e6db74">&#39;vue-mode-hook</span> (lambda () (set-face-background <span style="color:#e6db74">&#39;mmm-default-submode-face</span> <span style="color:#66d9ef">nil</span>)))
&lt;&lt;override-mmm-mode-func&gt;&gt;)
(with-eval-after-load <span style="color:#e6db74">&#39;editorconfig</span>
(add-to-list <span style="color:#e6db74">&#39;editorconfig-indentation-alist</span>
<span style="color:#f92672">&#39;</span>(vue-mode css-indent-offset
js-indent-level
sgml-basic-offset
ssass-tab-width
typescript-indent-level
emmet-indentation
vue-html-extra-indent)))
</code></pre></div><h5 id="mmm-mode-fix">mmm-mode fix</h5>
<p>References:</p>
<ul>
<li><a href="https://github.com/purcell/mmm-mode/issues/112">mmm-mode issue</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun mmm-syntax-propertize-function (start stop)
(let ((saved-mode mmm-current-submode)
(saved-ovl mmm-current-overlay))
(mmm-save-changed-local-variables
mmm-current-submode mmm-current-overlay)
(unwind-protect
(<span style="color:#a6e22e">mapc</span> (lambda (<span style="color:#a6e22e">elt</span>)
(let* ((mode (<span style="color:#a6e22e">car</span> <span style="color:#a6e22e">elt</span>))
(func (<span style="color:#a6e22e">get</span> mode <span style="color:#e6db74">&#39;mmm-syntax-propertize-function</span>))
(beg (cadr <span style="color:#a6e22e">elt</span>)) (end (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> <span style="color:#a6e22e">elt</span>))
(ovl (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">3</span> <span style="color:#a6e22e">elt</span>))
syntax-ppss-cache
syntax-ppss-last)
(<span style="color:#a6e22e">goto-char</span> beg)
(mmm-set-current-pair mode ovl)
(mmm-set-local-variables mode mmm-current-overlay)
(save-restriction
(if mmm-current-overlay
(<span style="color:#a6e22e">narrow-to-region</span> (<span style="color:#a6e22e">overlay-start</span> mmm-current-overlay)
(<span style="color:#a6e22e">overlay-end</span> mmm-current-overlay))
(<span style="color:#a6e22e">narrow-to-region</span> beg end))
(cond
(func
(<span style="color:#a6e22e">funcall</span> func beg end))
(font-lock-syntactic-keywords
(let ((syntax-propertize-function <span style="color:#66d9ef">nil</span>))
(font-lock-fontify-syntactic-keywords-region beg end))))
(<span style="color:#a6e22e">run-hook-with-args</span> <span style="color:#e6db74">&#39;mmm-after-syntax-propertize-functions</span>
mmm-current-overlay mode beg end))))
(mmm-regions-in start stop))
(mmm-set-current-pair saved-mode saved-ovl)
(mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl))))
</code></pre></div><h4 id="off--svelte"><span class="org-todo done OFF">OFF</span> (OFF) Svelte</h4>
<p>Had some problems with this and tree-sitter. Web-mode seems to be doing better.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package svelte-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.svelte\\&#39;&#34;</span>
:disabled
:config
(add-hook <span style="color:#e6db74">&#39;svelte-mode-hook</span> <span style="color:#e6db74">&#39;my/set-flycheck-eslint</span>)
(add-hook <span style="color:#e6db74">&#39;svelte-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;svelte-mode</span>)
<span style="color:#75715e">;; I have my own Emmet</span>
(setq lsp-svelte-plugin-css-completions-emmet <span style="color:#66d9ef">nil</span>)
(setq lsp-svelte-plugin-html-completions-emmet <span style="color:#66d9ef">nil</span>))
</code></pre></div><h4 id="scss">SCSS</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;scss-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;scss-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;scss-mode</span>)
</code></pre></div><h4 id="php">PHP</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package php-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.php\\&#39;&#34;</span>)
</code></pre></div><h3 id="latex">LaTeX</h3>
<h4 id="auctex">AUCTeX</h4>
<p>The best LaTeX editing environment I&rsquo;ve found so far.</p>
<p>References:</p>
<ul>
<li><a href="https://www.gnu.org/software/auctex/">AUCTeX homepage</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package tex
:straight auctex
:defer <span style="color:#66d9ef">t</span>
:config
(setq-default TeX-auto-save <span style="color:#66d9ef">t</span>)
(setq-default TeX-parse-self <span style="color:#66d9ef">t</span>)
(TeX-PDF-mode)
<span style="color:#75715e">;; Use XeLaTeX &amp; stuff</span>
(setq-default TeX-engine <span style="color:#e6db74">&#39;xetex</span>)
(setq-default TeX-command-extra-options <span style="color:#e6db74">&#34;-shell-escape&#34;</span>)
(setq-default TeX-source-correlate-method <span style="color:#e6db74">&#39;synctex</span>)
(TeX-source-correlate-mode)
(setq-default TeX-source-correlate-start-server <span style="color:#66d9ef">t</span>)
(setq-default LaTeX-math-menu-unicode <span style="color:#66d9ef">t</span>)
(setq-default font-latex-fontify-sectioning <span style="color:#ae81ff">1.3</span>)
<span style="color:#75715e">;; Scale preview for my DPI</span>
(setq-default preview-scale-function <span style="color:#ae81ff">1.4</span>)
(when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;tex--prettify-symbols-alist</span>)
(assoc-delete-all <span style="color:#e6db74">&#34;--&#34;</span> tex--prettify-symbols-alist)
(assoc-delete-all <span style="color:#e6db74">&#34;---&#34;</span> tex--prettify-symbols-alist))
(add-hook <span style="color:#e6db74">&#39;LaTeX-mode-hook</span>
(lambda ()
(TeX-fold-mode <span style="color:#ae81ff">1</span>)
(outline-minor-mode)))
(add-to-list <span style="color:#e6db74">&#39;TeX-view-program-selection</span>
<span style="color:#f92672">&#39;</span>(output-pdf <span style="color:#e6db74">&#34;Zathura&#34;</span>))
<span style="color:#75715e">;; Do not run lsp within templated TeX files</span>
(add-hook <span style="color:#e6db74">&#39;LaTeX-mode-hook</span>
(lambda ()
(unless (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;\.hogan\.tex$&#34;</span> (<span style="color:#a6e22e">buffer-name</span>))
(lsp))
(setq-local lsp-diagnostic-package :none)
(setq-local flycheck-checker <span style="color:#e6db74">&#39;tex-chktex</span>)))
(add-hook <span style="color:#e6db74">&#39;LaTeX-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>rainbow-delimiters-mode)
(add-hook <span style="color:#e6db74">&#39;LaTeX-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;LaTeX-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>prettify-symbols-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;LaTeX-mode</span>)
(require <span style="color:#e6db74">&#39;smartparens-latex</span>)
(general-nmap
:keymaps <span style="color:#f92672">&#39;</span>(LaTeX-mode-map latex-mode-map)
<span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;TeX-command-run-all</span>
<span style="color:#e6db74">&#34;C-c t&#34;</span> <span style="color:#e6db74">&#39;orgtbl-mode</span>)
&lt;&lt;init-greek-latex-snippets&gt;&gt;
&lt;&lt;init-english-latex-snippets&gt;&gt;
&lt;&lt;init-math-latex-snippets&gt;&gt;
&lt;&lt;init-section-latex-snippets&gt;&gt;)
</code></pre></div><h4 id="bibtex">BibTeX</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy-bibtex
:commands (ivy-bibtex)
:straight <span style="color:#66d9ef">t</span>
:init
(my-leader-def <span style="color:#e6db74">&#34;fB&#34;</span> <span style="color:#e6db74">&#39;ivy-bibtex</span>))
(add-hook <span style="color:#e6db74">&#39;bibtex-mode</span> <span style="color:#e6db74">&#39;smartparens-mode</span>)
</code></pre></div><h4 id="import-dot-sty">Import *.sty</h4>
<p>A function to import <code>.sty</code> files to the LaTeX document.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/list-sty ()
(<span style="color:#a6e22e">reverse</span>
(<span style="color:#a6e22e">sort</span>
(seq-filter
(lambda (file) (if (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;.*\.sty$&#34;</span> file) <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">nil</span>))
(<span style="color:#a6e22e">directory-files</span>
(seq-some
(lambda (dir)
(if (and
(f-directory-p dir)
(seq-some
(lambda (file) (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;.*\.sty$&#34;</span> file))
(<span style="color:#a6e22e">directory-files</span> dir))
) dir <span style="color:#66d9ef">nil</span>))
(<span style="color:#a6e22e">list</span> <span style="color:#e6db74">&#34;./styles&#34;</span> <span style="color:#e6db74">&#34;../styles/&#34;</span> <span style="color:#e6db74">&#34;.&#34;</span> <span style="color:#e6db74">&#34;..&#34;</span>)) :full))
(lambda (f1 f2)
(let ((f1b (file-name-base f1))
(f1b (file-name-base f2)))
(cond
((string-match-p <span style="color:#e6db74">&#34;.*BibTex&#34;</span> f1) <span style="color:#66d9ef">t</span>)
((and (string-match-p <span style="color:#e6db74">&#34;.*Locale&#34;</span> f1) (not (string-match-p <span style="color:#e6db74">&#34;.*BibTex&#34;</span> f2))) <span style="color:#66d9ef">t</span>)
((string-match-p <span style="color:#e6db74">&#34;.*Preamble&#34;</span> f2) <span style="color:#66d9ef">t</span>)
(<span style="color:#66d9ef">t</span> (<span style="color:#a6e22e">string-lessp</span> f1 f2))))))))
(defun my/import-sty ()
(interactive)
(<span style="color:#a6e22e">insert</span>
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#&#39;concat</span>
(cl-mapcar
(lambda (file) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;\\usepackage{&#34;</span> (file-name-sans-extension (file-relative-name file default-directory)) <span style="color:#e6db74">&#34;}\n&#34;</span>))
(my/list-sty)))))
(defun my/import-sty-org ()
(interactive)
(<span style="color:#a6e22e">insert</span>
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#&#39;concat</span>
(cl-mapcar
(lambda (file) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;#+LATEX_HEADER: \\usepackage{&#34;</span> (file-name-sans-extension (file-relative-name file default-directory)) <span style="color:#e6db74">&#34;}\n&#34;</span>))
(my/list-sty)))))
</code></pre></div><h4 id="snippets">Snippets</h4>
<table>
<thead>
<tr>
<th>Note</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO</td>
<td>Move yasnippet snippets here? Maybe extract to a separate file?</td>
</tr>
</tbody>
</table>
<h5 id="greek-letters">Greek letters</h5>
<p>Autogenerate snippets for greek letters. I have a few blocks like this because it&rsquo;s faster &amp; more flexible than usual yasnippet snippets.</p>
<p>Noweb points to the AUCTeX config block.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/greek-alphabet
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\alpha&#34;</span>)
(<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\beta&#34;</span> )
(<span style="color:#e6db74">&#34;g&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\gamma&#34;</span>)
(<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\delta&#34;</span>)
(<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\epsilon&#34;</span>)
(<span style="color:#e6db74">&#34;z&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\zeta&#34;</span>)
(<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\eta&#34;</span>)
(<span style="color:#e6db74">&#34;o&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\theta&#34;</span>)
(<span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\iota&#34;</span>)
(<span style="color:#e6db74">&#34;k&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\kappa&#34;</span>)
(<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\lambda&#34;</span>)
(<span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\mu&#34;</span>)
(<span style="color:#e6db74">&#34;n&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\nu&#34;</span>)
(<span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\xi&#34;</span>)
(<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\pi&#34;</span>)
(<span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\rho&#34;</span>)
(<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\sigma&#34;</span>)
(<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\tau&#34;</span>)
(<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\upsilon&#34;</span>)
(<span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\phi&#34;</span>)
(<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\chi&#34;</span>)
(<span style="color:#e6db74">&#34;v&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\psi&#34;</span>)
(<span style="color:#e6db74">&#34;g&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\omega&#34;</span>)))
(setq my/latex-greek-prefix <span style="color:#e6db74">&#34;&#39;&#34;</span>)
<span style="color:#75715e">;; The same for capitalized letters</span>
(dolist (elem my/greek-alphabet)
(let ((key (<span style="color:#a6e22e">car</span> elem))
(value (<span style="color:#a6e22e">cdr</span> elem)))
(when (<span style="color:#a6e22e">string-equal</span> key (<span style="color:#a6e22e">downcase</span> key))
(add-to-list <span style="color:#e6db74">&#39;my/greek-alphabet</span>
(<span style="color:#a6e22e">cons</span>
(<span style="color:#a6e22e">capitalize</span> (<span style="color:#a6e22e">car</span> elem))
(<span style="color:#a6e22e">concat</span>
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> <span style="color:#ae81ff">1</span>)
(<span style="color:#a6e22e">capitalize</span> (<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">2</span>))
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">2</span>)))))))
(yas-define-snippets
<span style="color:#e6db74">&#39;latex-mode</span>
(<span style="color:#a6e22e">mapcar</span>
(lambda (elem)
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-greek-prefix (<span style="color:#a6e22e">car</span> elem)) (<span style="color:#a6e22e">cdr</span> elem) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;Greek letter &#34;</span> (<span style="color:#a6e22e">car</span> elem))))
my/greek-alphabet))
</code></pre></div><h5 id="english-letters">English letters</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/english-alphabet
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;a&#34;</span> <span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#e6db74">&#34;f&#34;</span> <span style="color:#e6db74">&#34;g&#34;</span> <span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#e6db74">&#34;j&#34;</span> <span style="color:#e6db74">&#34;k&#34;</span> <span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#34;m&#34;</span> <span style="color:#e6db74">&#34;n&#34;</span> <span style="color:#e6db74">&#34;o&#34;</span> <span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#34;r&#34;</span> <span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#34;v&#34;</span> <span style="color:#e6db74">&#34;w&#34;</span> <span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#e6db74">&#34;y&#34;</span> <span style="color:#e6db74">&#34;z&#34;</span>))
(dolist (elem my/english-alphabet)
(when (<span style="color:#a6e22e">string-equal</span> elem (<span style="color:#a6e22e">downcase</span> elem))
(add-to-list <span style="color:#e6db74">&#39;my/english-alphabet</span> (<span style="color:#a6e22e">upcase</span> elem))))
(setq my/latex-mathbb-prefix <span style="color:#e6db74">&#34;`&#34;</span>)
(yas-define-snippets
<span style="color:#e6db74">&#39;latex-mode</span>
(<span style="color:#a6e22e">mapcar</span>
(lambda (elem)
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-mathbb-prefix elem) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;\\mathbb{&#34;</span> elem <span style="color:#e6db74">&#34;}&#34;</span>) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;Mathbb letter &#34;</span> elem)))
my/english-alphabet))
</code></pre></div><h5 id="math-symbols">Math symbols</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-math-symbols
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;x&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\times&#34;</span>)
(<span style="color:#e6db74">&#34;.&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\cdot&#34;</span>)
(<span style="color:#e6db74">&#34;v&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\forall&#34;</span>)
(<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\sum_{$1}^{$2}$0&#34;</span>)
(<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\prod_{$1}^{$2}$0&#34;</span>)
(<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\partial&#34;</span>)
(<span style="color:#e6db74">&#34;e&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\exists&#34;</span>)
(<span style="color:#e6db74">&#34;i&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\int_{$1}^{$2}$0&#34;</span>)
(<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\cap&#34;</span>)
(<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\cup&#34;</span>)
(<span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\emptyset&#34;</span>)
(<span style="color:#e6db74">&#34;^&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\widehat{$1}$0&#34;</span>)
(<span style="color:#e6db74">&#34;_&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\overline{$1}$0&#34;</span>)
(<span style="color:#e6db74">&#34;~&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\sim&#34;</span>)
(<span style="color:#e6db74">&#34;|&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\mid&#34;</span>)
(<span style="color:#e6db74">&#34;_|&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\perp&#34;</span>)))
(setq my/latex-math-prefix <span style="color:#e6db74">&#34;;&#34;</span>)
(yas-define-snippets
<span style="color:#e6db74">&#39;latex-mode</span>
(<span style="color:#a6e22e">mapcar</span>
(lambda (elem)
(let ((key (<span style="color:#a6e22e">car</span> elem))
(value (<span style="color:#a6e22e">cdr</span> elem)))
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-math-prefix key) value (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;Math symbol &#34;</span> value))))
my/latex-math-symbols))
</code></pre></div><h5 id="section-snippets">Section snippets</h5>
<p>Section snippets. The code turned out to be more complicated than just writing the snippets by hand.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-section-snippets
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;ch&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\chapter{$1}&#34;</span>)
(<span style="color:#e6db74">&#34;sec&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\section{$1}&#34;</span>)
(<span style="color:#e6db74">&#34;ssec&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsection{$1}&#34;</span>)
(<span style="color:#e6db74">&#34;sssec&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\subsubsection{$1}&#34;</span>)
(<span style="color:#e6db74">&#34;par&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;\\paragraph{$1}}&#34;</span>)))
(setq my/latex-section-snippets
(<span style="color:#a6e22e">mapcar</span>
(lambda (elem)
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">car</span> elem)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">cdr</span> elem)
<span style="color:#f92672">,</span>(progn
(<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;[a-z]+&#34;</span> (<span style="color:#a6e22e">cdr</span> elem))
(match-string <span style="color:#ae81ff">0</span> (<span style="color:#a6e22e">cdr</span> elem)))))
my/latex-section-snippets))
(dolist (elem my/latex-section-snippets)
(let* ((key (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> elem))
(value (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem))
(desc (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> elem))
(star-index (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">&#34;\{\$1\}&#34;</span> value)))
(add-to-list <span style="color:#e6db74">&#39;my/latex-section-snippets</span>
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">&#34;*&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span>
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> star-index)
<span style="color:#e6db74">&#34;*&#34;</span>
(<span style="color:#a6e22e">substring</span> value star-index))
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">&#34; with *&#34;</span>)))
(add-to-list <span style="color:#e6db74">&#39;my/latex-section-snippets</span>
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">&#34;l&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> value <span style="color:#e6db74">&#34;%\n\\label{sec:$2}&#34;</span>)
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">&#34; with label&#34;</span>)))))
(dolist (elem my/latex-section-snippets)
(setf (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem) (<span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem) <span style="color:#e6db74">&#34;\n$0&#34;</span>)))
(yas-define-snippets
<span style="color:#e6db74">&#39;latex-mode</span>
my/latex-section-snippets)
</code></pre></div><h3 id="other-markup-languages">Other markup languages</h3>
<h4 id="markdown">Markdown</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package markdown-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.md\\&#39;&#34;</span>
:config
(setq markdown-command
(<span style="color:#a6e22e">concat</span>
<span style="color:#e6db74">&#34;pandoc&#34;</span>
<span style="color:#e6db74">&#34; --from=markdown --to=html&#34;</span>
<span style="color:#e6db74">&#34; --standalone --mathjax --highlight-style=pygments&#34;</span>
<span style="color:#e6db74">&#34; --css=pandoc.css&#34;</span>
<span style="color:#e6db74">&#34; --quiet&#34;</span>
))
(setq markdown-live-preview-delete-export <span style="color:#e6db74">&#39;delete-on-export</span>)
(setq markdown-asymmetric-header <span style="color:#66d9ef">t</span>)
(setq markdown-open-command <span style="color:#e6db74">&#34;/home/pavel/bin/scripts/chromium-sep&#34;</span>)
(add-hook <span style="color:#e6db74">&#39;markdown-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;markdown-mode-map</span>
<span style="color:#e6db74">&#34;M-&lt;left&gt;&#34;</span> <span style="color:#e6db74">&#39;markdown-promote</span>
<span style="color:#e6db74">&#34;M-&lt;right&gt;&#34;</span> <span style="color:#e6db74">&#39;markdown-demote</span>))
<span style="color:#75715e">;; (use-package livedown</span>
<span style="color:#75715e">;; :straight (:host github :repo &#34;shime/emacs-livedown&#34;)</span>
<span style="color:#75715e">;; :commands livedown-preview</span>
<span style="color:#75715e">;; :config</span>
<span style="color:#75715e">;; (setq livedown-browser &#34;qutebrowser&#34;))</span>
</code></pre></div><h4 id="plantuml">PlantUML</h4>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>plantuml</td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package plantuml-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;(\\.\\(plantuml?\\|uml\\|puml\\)\\&#39;&#34;</span>
:config
(setq plantuml-executable-path <span style="color:#e6db74">&#34;/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml&#34;</span>)
(setq plantuml-default-exec-mode <span style="color:#e6db74">&#39;executable</span>)
(setq plantuml-indent-level <span style="color:#ae81ff">2</span>)
(setq my/plantuml-indent-regexp-return <span style="color:#e6db74">&#34;^\s*return\s+.+$&#34;</span>)
(add-to-list
<span style="color:#e6db74">&#39;plantuml-indent-regexp-end</span>
my/plantuml-indent-regexp-return)
(add-to-list <span style="color:#e6db74">&#39;auto-mode-alist</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;\\.plantuml\\&#39;&#34;</span> <span style="color:#f92672">.</span> plantuml-mode))
(add-to-list <span style="color:#e6db74">&#39;auto-mode-alist</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;\\.uml\\&#39;&#34;</span> <span style="color:#f92672">.</span> plantuml-mode))
(add-hook <span style="color:#e6db74">&#39;plantuml-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode))
(general-nmap
:keymaps <span style="color:#e6db74">&#39;plantuml-mode-map</span>
<span style="color:#e6db74">&#34;RET&#34;</span> <span style="color:#e6db74">&#39;plantuml-preview</span>)
</code></pre></div><h4 id="languagetool">LanguageTool</h4>
<p>LanguageTool is a great offline spell checker. For some reason, the download link is nowhere to be found on the home page, so it is listed in the references as well.</p>
<p>References:</p>
<ul>
<li><a href="https://languagetool.org/">LanguageTool homepage</a></li>
<li><a href="https://dev.languagetool.org/http-server">LanguageTool http server</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package langtool
:straight <span style="color:#66d9ef">t</span>
:commands (langtool-check)
:config
(setq langtool-language-tool-server-jar <span style="color:#e6db74">&#34;/home/pavel/bin/LanguageTool-5.4/languagetool-server.jar&#34;</span>)
(setq langtool-mother-tongue <span style="color:#e6db74">&#34;ru&#34;</span>)
(setq langtool-default-language <span style="color:#e6db74">&#34;en-US&#34;</span>))
(my-leader-def
:infix <span style="color:#e6db74">&#34;L&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;languagetool&#34;</span>)
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;langtool-check</span>
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;langtool-server-stop</span>
<span style="color:#e6db74">&#34;d&#34;</span> <span style="color:#e6db74">&#39;langtool-check-done</span>
<span style="color:#e6db74">&#34;n&#34;</span> <span style="color:#e6db74">&#39;langtool-goto-next-error</span>
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#39;langtool-goto-previous-error</span>
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;langtool-correct-buffer</span>)
</code></pre></div><h3 id="lisp">Lisp</h3>
<p>These are your father&rsquo;s parentheses. Elegant weapons for a more&hellip; civilized age.</p>
<h4 id="meta-lisp">Meta Lisp</h4>
<p>Some packages for editing various Lisps.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lispy
:commands (lispy-mode)
:straight <span style="color:#66d9ef">t</span>)
(use-package lispyville
:hook (lispy-mode <span style="color:#f92672">.</span> lispyville-mode)
:straight <span style="color:#66d9ef">t</span>)
(sp-with-modes sp-lisp-modes
(sp-local-pair <span style="color:#e6db74">&#34;&#39;&#34;</span> <span style="color:#66d9ef">nil</span> :actions <span style="color:#66d9ef">nil</span>))
</code></pre></div><h4 id="emacs-lisp">Emacs Lisp</h4>
<h5 id="package-lint">Package Lint</h5>
<p>A package that checks for the metadata in Emacs Lisp packages.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package flycheck-package
:straight <span style="color:#66d9ef">t</span>
:after flycheck
:config
(flycheck-package-setup))
</code></pre></div><h5 id="general-settings">General settings</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>aggressive-indent-mode)
<span style="color:#75715e">;; (add-hook &#39;emacs-lisp-mode-hook #&#39;smartparens-strict-mode)</span>
(add-hook <span style="color:#e6db74">&#39;emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>lispy-mode)
</code></pre></div><h4 id="common-lisp">Common lisp</h4>
<h5 id="slime">SLIME</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package slime
:straight <span style="color:#66d9ef">t</span>
:config
(setq inferior-lisp-program <span style="color:#e6db74">&#34;sbcl&#34;</span>)
(add-hook <span style="color:#e6db74">&#39;slime-repl-mode</span> <span style="color:#e6db74">&#39;smartparens-mode</span>))
</code></pre></div><h5 id="general-settings">General settings</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;lisp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>aggressive-indent-mode)
<span style="color:#75715e">;; (add-hook &#39;emacs-lisp-mode-hook #&#39;smartparens-strict-mode)</span>
(add-hook <span style="color:#e6db74">&#39;lisp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>lispy-mode)
</code></pre></div><h4 id="clojure">Clojure</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package clojure-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.clj[sc]?\\&#39;&#34;</span>
:config
<span style="color:#75715e">;; (add-hook &#39;clojure-mode-hook #&#39;smartparens-strict-mode)</span>
(add-hook <span style="color:#e6db74">&#39;clojure-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>lispy-mode)
(add-hook <span style="color:#e6db74">&#39;clojure-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>aggressive-indent-mode))
(use-package cider
:mode <span style="color:#e6db74">&#34;\\.clj[sc]?\\&#39;&#34;</span>
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><h4 id="hy">Hy</h4>
<p>Python requirements:</p>
<ul>
<li><code>hy</code></li>
<li><code>jedhy</code></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hy-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.hy\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;hy-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>lispy-mode)
(add-hook <span style="color:#e6db74">&#39;hy-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>aggressive-indent-mode))
</code></pre></div><h4 id="scheme">Scheme</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package geiser
:straight <span style="color:#66d9ef">t</span>
:if (not my/lowpower)
:config
(setq geiser-default-implementation <span style="color:#e6db74">&#39;guile</span>))
(use-package geiser-guile
:straight <span style="color:#66d9ef">t</span>
:after geiser)
(add-hook <span style="color:#e6db74">&#39;scheme-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>aggressive-indent-mode)
(add-hook <span style="color:#e6db74">&#39;scheme-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>lispy-mode)
</code></pre></div><h4 id="clips">CLIPS</h4>
<p>An honorary Lisp</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package clips-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.cl\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;clips-mode</span> <span style="color:#e6db74">&#39;lispy-mode</span>))
</code></pre></div><h3 id="python">Python</h3>
<p>Use <a href="https://github.com/Microsoft/python-language-server">Microsoft Language Server for Python</a>.</p>
<p>For some reason it doesn&rsquo;t use pipenv python executable, so here is a small workaround.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/pipenv-python-alist <span style="color:#f92672">&#39;</span>())
(defun my/get-pipenv-python ()
(let ((default-directory (projectile-project-root)))
(if (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">&#34;Pipfile&#34;</span>)
(let ((asc (<span style="color:#a6e22e">assoc</span> default-directory my/pipenv-python-alist)))
(if asc
(<span style="color:#a6e22e">cdr</span> asc)
(let ((python-executable
(string-trim (shell-command-to-string <span style="color:#e6db74">&#34;PIPENV_IGNORE_VIRTUALENVS=1 pipenv run which python 2&gt;/dev/null&#34;</span>))))
(if (string-match-p <span style="color:#e6db74">&#34;.*not found.*&#34;</span> python-executable)
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">&#34;Pipfile found, but not pipenv executable!&#34;</span>)
(<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;Found pipenv python: %s&#34;</span> python-executable))
(add-to-list <span style="color:#e6db74">&#39;my/pipenv-python-alist</span> (<span style="color:#a6e22e">cons</span> default-directory python-executable))
python-executable))))
<span style="color:#e6db74">&#34;python&#34;</span>)))
(use-package lsp-pyright
:straight <span style="color:#66d9ef">t</span>
:defer <span style="color:#66d9ef">t</span>
:if (not my/slow-ssh)
:hook (python-mode <span style="color:#f92672">.</span> (lambda ()
(require <span style="color:#e6db74">&#39;lsp-pyright</span>)
(setq-local lsp-pyright-python-executable-cmd (my/get-pipenv-python))
(lsp))))
(add-hook <span style="color:#e6db74">&#39;python-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;python-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
</code></pre></div><h4 id="pipenv">pipenv</h4>
<p><a href="https://github.com/pypa/pipenv">Pipenv</a> is a package manager for Python.</p>
<p>Automatically creates &amp; manages virtualenvs and stores data in <code>Pipfile</code> and <code>Pipfile.lock</code> (like npm&rsquo;s <code>package.json</code> and <code>package-lock.json</code>).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pipenv
:straight <span style="color:#66d9ef">t</span>
:hook (python-mode <span style="color:#f92672">.</span> pipenv-mode)
:if (not my/slow-ssh)
:init
(setq
pipenv-projectile-after-switch-function
<span style="color:#a6e22e">#&#39;</span>pipenv-projectile-after-switch-extended))
</code></pre></div><h4 id="yapf">yapf</h4>
<p><a href="https://github.com/google/yapf">yapf</a> is a formatter for Python files.</p>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>python-yapf</td>
</tr>
</tbody>
</table>
<p>References:</p>
<ul>
<li><a href="https://github.com/google/yapf">yapf repo</a></li>
<li><a href="https://github.com/JorisE/yapfify">yapfify.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yapfify
:straight (:repo <span style="color:#e6db74">&#34;JorisE/yapfify&#34;</span> :host github)
:commands (yapfify-region
yapfify-buffer
yapfify-region-or-buffer
yapf-mode))
</code></pre></div><p>Global config:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ini" data-lang="ini"><span style="color:#66d9ef">[style]</span>
<span style="color:#a6e22e">based_on_style</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">facebook</span>
<span style="color:#a6e22e">column_limit</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">80</span>
</code></pre></div><h4 id="isort">isort</h4>
<p><a href="https://github.com/PyCQA/isort">isort</a> is a Python package to sort Python imports.</p>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>python-isort</td>
</tr>
</tbody>
</table>
<p>References:</p>
<ul>
<li><a href="https://pycqa.github.io/isort/">isort docs</a></li>
<li><a href="https://github.com/paetzke/py-isort.el">py-isort.el repo</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package py-isort
:straight <span style="color:#66d9ef">t</span>
:commands (py-isort-buffer py-isort-region))
</code></pre></div><p>The following bindings calls yapf &amp; isort on the buffer</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
:keymaps <span style="color:#e6db74">&#39;python-mode-map</span>
<span style="color:#e6db74">&#34;rr&#34;</span> (lambda ()
(interactive)
(unless (and (<span style="color:#a6e22e">fboundp</span> <span style="color:#a6e22e">#&#39;</span>org-src-edit-buffer-p) (org-src-edit-buffer-p))
(py-isort-buffer))
(yapfify-buffer)))
</code></pre></div><h4 id="sphinx-doc">sphinx-doc</h4>
<p>A package to generate sphinx-compatible docstrings.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package sphinx-doc
:straight <span style="color:#66d9ef">t</span>
:hook (python-mode <span style="color:#f92672">.</span> sphinx-doc-mode)
:config
(my-leader-def
:keymaps <span style="color:#e6db74">&#39;sphinx-doc-mode-map</span>
<span style="color:#e6db74">&#34;rd&#34;</span> <span style="color:#e6db74">&#39;sphinx-doc</span>))
</code></pre></div><h4 id="pytest">pytest</h4>
<p><a href="https://docs.pytest.org/en/6.2.x/">pytest</a> is an unit testing framework for Python.</p>
<p>Once again a function to set pytest executable from pipenv.</p>
<p>References:</p>
<ul>
<li><a href="https://docs.pytest.org/en/6.2.x/">pytest docs</a></li>
<li><a href="https://github.com/wbolster/emacs-python-pytest">emacs-python-pytest</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-pipenv-pytest ()
(setq-local
python-pytest-executable
(<span style="color:#a6e22e">concat</span> (my/get-pipenv-python) <span style="color:#e6db74">&#34; -m pytest&#34;</span>)))
(use-package python-pytest
:straight <span style="color:#66d9ef">t</span>
:commands (python-pytest-dispatch)
:init
(my-leader-def
:keymaps <span style="color:#e6db74">&#39;python-mode-map</span>
:infix <span style="color:#e6db74">&#34;t&#34;</span>
<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#39;python-pytest-dispatch</span>)
:config
&lt;&lt;override-pytest-run&gt;&gt;
(add-hook <span style="color:#e6db74">&#39;python-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>my/set-pipenv-pytest)
(when (derived-mode-p <span style="color:#e6db74">&#39;python-mode</span>)
(my/set-pipenv-pytest)))
</code></pre></div><h5 id="fix-comint-buffer-width">Fix comint buffer width</h5>
<p>For some reason default comint output width is way too large.</p>
<p>To fix that, I&rsquo;ve modified the following function in the <code>python-pytest</code> package.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(cl-defun python-pytest--run-as-comint (<span style="color:#66d9ef">&amp;key</span> command)
<span style="color:#e6db74">&#34;Run a pytest comint session for COMMAND.&#34;</span>
(let* ((buffer (python-pytest--get-buffer))
(process (<span style="color:#a6e22e">get-buffer-process</span> buffer)))
(with-current-buffer buffer
(when (comint-check-proc buffer)
(unless (or compilation-always-kill
(<span style="color:#a6e22e">yes-or-no-p</span> <span style="color:#e6db74">&#34;Kill running pytest process?&#34;</span>))
(<span style="color:#a6e22e">user-error</span> <span style="color:#e6db74">&#34;Aborting; pytest still running&#34;</span>)))
(when process
(<span style="color:#a6e22e">delete-process</span> process))
(let ((inhibit-read-only <span style="color:#66d9ef">t</span>))
(<span style="color:#a6e22e">erase-buffer</span>))
(unless (<span style="color:#a6e22e">eq</span> major-mode <span style="color:#e6db74">&#39;python-pytest-mode</span>)
(python-pytest-mode))
(compilation-forget-errors)
(display-buffer buffer)
(setq command (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;export COLUMNS=%s; %s&#34;</span>
(<span style="color:#a6e22e">-</span> (window-width (<span style="color:#a6e22e">get-buffer-window</span> buffer)) <span style="color:#ae81ff">5</span>)
command))
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;cwd: %s\ncmd: %s\n\n&#34;</span> default-directory command))
(setq python-pytest--current-command command)
(when python-pytest-pdb-track
(add-hook
<span style="color:#e6db74">&#39;comint-output-filter-functions</span>
<span style="color:#e6db74">&#39;python-pdbtrack-comint-output-filter-function</span>
<span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>))
(<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">&#39;python-pytest-setup-hook</span>)
(make-comint-in-buffer <span style="color:#e6db74">&#34;pytest&#34;</span> buffer <span style="color:#e6db74">&#34;bash&#34;</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#34;-c&#34;</span> command)
(<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">&#39;python-pytest-started-hook</span>)
(setq process (<span style="color:#a6e22e">get-buffer-process</span> buffer))
(<span style="color:#a6e22e">set-process-sentinel</span> process <span style="color:#a6e22e">#&#39;</span>python-pytest--process-sentinel))))
</code></pre></div><h4 id="code-cells">code-cells</h4>
<p>Support for text with magic comments.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package code-cells
:straight <span style="color:#66d9ef">t</span>
:commands (code-cells-mode))
</code></pre></div><h4 id="tensorboard">tensorboard</h4>
<p>A function to start up <a href="https://www.tensorflow.org/tensorboard">TensorBoard</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/tensorboard-buffer <span style="color:#e6db74">&#34;TensorBoard-out&#34;</span>)
(defun my/tensorboard ()
(interactive)
(<span style="color:#a6e22e">start-process</span>
<span style="color:#e6db74">&#34;tensorboard&#34;</span>
my/tensorboard-buffer
<span style="color:#e6db74">&#34;tensorboard&#34;</span>
<span style="color:#e6db74">&#34;serve&#34;</span>
<span style="color:#e6db74">&#34;--logdir&#34;</span>
(<span style="color:#a6e22e">car</span> (find-file-read-args <span style="color:#e6db74">&#34;Directory: &#34;</span> <span style="color:#66d9ef">t</span>)))
(display-buffer my/tensorboard-buffer))
</code></pre></div><h3 id="java">Java</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lsp-java
:straight <span style="color:#66d9ef">t</span>
:after (lsp)
:config
(setq lsp-java-jdt-download-url <span style="color:#e6db74">&#34;https://download.eclipse.org/jdtls/milestones/0.57.0/jdt-language-server-0.57.0-202006172108.tar.gz&#34;</span>))
(add-hook <span style="color:#e6db74">&#39;java-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
<span style="color:#75715e">;; (add-hook &#39;java-mode-hook #&#39;hs-minor-mode)</span>
(my/set-smartparens-indent <span style="color:#e6db74">&#39;java-mode</span>)
</code></pre></div><h3 id="go">Go</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package go-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.go\\&#39;&#34;</span>
:config
(my/set-smartparens-indent <span style="color:#e6db74">&#39;go-mode</span>)
(add-hook <span style="color:#e6db74">&#39;go-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;go-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode))
</code></pre></div><h3 id="dot-net">.NET</h3>
<h4 id="c">C#</h4>
<table>
<thead>
<tr>
<th>Guix dependencies</th>
<th>Disabled</th>
</tr>
</thead>
<tbody>
<tr>
<td>omnisharp</td>
<td>t</td>
</tr>
<tr>
<td>dotnet</td>
<td>t</td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csharp-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.cs\\&#39;&#34;</span>
:config
(setq lsp-csharp-server-path (executable-find <span style="color:#e6db74">&#34;omnisharp-wrapper&#34;</span>))
(add-hook <span style="color:#e6db74">&#39;csharp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>csharp-tree-sitter-mode)
(add-hook <span style="color:#e6db74">&#39;csharp-tree-sitter-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;csharp-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;csharp-tree-sitter-mode</span>))
</code></pre></div><h4 id="msbuild">MSBuild</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csproj-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.csproj\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;csproj-mode</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode))
</code></pre></div><h3 id="fish">fish</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package fish-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.fish\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;fish-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode))
</code></pre></div><h3 id="sh">sh</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;sh-mode-hook</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
</code></pre></div><h3 id="haskell">Haskell</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package haskell-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.hs\\&#39;&#34;</span>)
(use-package lsp-haskell
:straight <span style="color:#66d9ef">t</span>
:after (lsp haskell-mode))
</code></pre></div><h3 id="lua">Lua</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lua-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.lua\\&#39;&#34;</span>
:hook (lua-mode <span style="color:#f92672">.</span> smartparens-mode))
(my/set-smartparens-indent <span style="color:#e6db74">&#39;lua-mode</span>)
</code></pre></div><h3 id="json">JSON</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package json-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.json\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;json-mode</span> <span style="color:#a6e22e">#&#39;</span>smartparens-mode)
(add-hook <span style="color:#e6db74">&#39;json-mode</span> <span style="color:#a6e22e">#&#39;</span>hs-minor-mode)
(my/set-smartparens-indent <span style="color:#e6db74">&#39;json-mode</span>))
</code></pre></div><h3 id="sql">SQL</h3>
<p><a href="https://github.com/zeroturnaround/sql-formatter">sql-formatter</a> is a nice JavaScript package for pretty-printing SQL queries. It is not packaged for Emacs, so the easiest way to use it seems to be to define a custom formatter via <a href="https://github.com/purcell/emacs-reformatter">reformatter</a>.</p>
<p>Also, I&rsquo;ve a simple function to switch dialects because I often alternate between them.</p>
<p>So far I didn&rsquo;t find a nice SQL client for Emacs, but I occasionally run SQL queries in Org Mode, so this qute package is handy.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/sqlformatter-dialect-choice
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;db2&#34;</span> <span style="color:#e6db74">&#34;mariadb&#34;</span> <span style="color:#e6db74">&#34;mysql&#34;</span> <span style="color:#e6db74">&#34;n1ql&#34;</span> <span style="color:#e6db74">&#34;plsql&#34;</span> <span style="color:#e6db74">&#34;postgresql&#34;</span> <span style="color:#e6db74">&#34;redshift&#34;</span> <span style="color:#e6db74">&#34;spark&#34;</span> <span style="color:#e6db74">&#34;sql&#34;</span> <span style="color:#e6db74">&#34;tsql&#34;</span>))
(setq my/sqlformatter-dialect <span style="color:#e6db74">&#34;postgresql&#34;</span>)
(defun my/sqlformatter-set-dialect ()
<span style="color:#e6db74">&#34;Set dialect for sql-formatter&#34;</span>
(interactive)
(setq my/sqlformatter-dialect
(<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">&#34;Dialect: &#34;</span> my/sqlformatter-dialect-choice)))
(reformatter-define sqlformat
:program (executable-find <span style="color:#e6db74">&#34;sql-formatter&#34;</span>)
:args <span style="color:#f92672">`</span>(<span style="color:#e6db74">&#34;-l&#34;</span> <span style="color:#f92672">,</span>my/sqlformatter-dialect))
(my-leader-def
:keymaps <span style="color:#f92672">&#39;</span>(sql-mode-map)
<span style="color:#e6db74">&#34;rr&#34;</span> <span style="color:#a6e22e">#&#39;</span>sqlformat-buffer)
</code></pre></div><h3 id="yaml">YAML</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yaml-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.yml\\&#39;&#34;</span>
:config
(add-hook <span style="color:#e6db74">&#39;yaml-mode-hook</span> <span style="color:#e6db74">&#39;smartparens-mode</span>)
(add-hook <span style="color:#e6db74">&#39;yaml-mode-hook</span> <span style="color:#e6db74">&#39;highlight-indent-guides-mode</span>)
(add-to-list <span style="color:#e6db74">&#39;auto-mode-alist</span> <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;\\.yml\\&#39;&#34;</span> <span style="color:#f92672">.</span> yaml-mode)))
</code></pre></div><h3 id="dot-env">.env</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dotenv-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.env\\..*\\&#39;&#34;</span>)
</code></pre></div><h3 id="csv">CSV</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csv-mode
:straight <span style="color:#66d9ef">t</span>
:mode <span style="color:#e6db74">&#34;\\.csv\\&#39;&#34;</span>)
</code></pre></div><h3 id="off--pdf"><span class="org-todo done OFF">OFF</span> (OFF) PDF</h3>
<p>A decent package to view PDFs in Emacs, but I prefer Zathura.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/vedang/pdf-tools/">https://github.com/vedang/pdf-tools/</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pdf-tools
:straight <span style="color:#66d9ef">t</span>
:commands (pdf-tools-install))
</code></pre></div><h3 id="docker">Docker</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dockerfile-mode
:mode <span style="color:#e6db74">&#34;Dockerfile\\&#39;&#34;</span>
:straight <span style="color:#66d9ef">t</span>
:config
(add-hook <span style="color:#e6db74">&#39;dockerfile-mode</span> <span style="color:#e6db74">&#39;smartparens-mode</span>))
</code></pre></div><h2 id="apps-and-misc">Apps &amp; Misc</h2>
<h3 id="managing-dotfiles">Managing dotfiles</h3>
<p>A bunch of functions for managing dotfiles with yadm.</p>
<h4 id="open-emacs-config">Open Emacs config</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/edit-configuration ()
<span style="color:#e6db74">&#34;Open the init file.&#34;</span>
(interactive)
(find-file <span style="color:#e6db74">&#34;~/Emacs.org&#34;</span>))
<span style="color:#75715e">;; (defun my/edit-exwm-configuration ()</span>
<span style="color:#75715e">;; &#34;Open the exwm config file.&#34;</span>
<span style="color:#75715e">;; (interactive)</span>
<span style="color:#75715e">;; (find-file &#34;~/.emacs.d/exwm.org&#34;))</span>
(general-define-key <span style="color:#e6db74">&#34;C-c c&#34;</span> <span style="color:#e6db74">&#39;my/edit-configuration</span>)
<span style="color:#75715e">;; (general-define-key &#34;C-c C&#34; &#39;my/edit-exwm-configuration)</span>
(my-leader-def
:infix <span style="color:#e6db74">&#34;c&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;configuration&#34;</span>)
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#e6db74">&#39;my/edit-configuration</span>)
</code></pre></div><h4 id="open-magit-for-yadm">Open Magit for yadm</h4>
<p>Idea:</p>
<ul>
<li><a href="https://www.reddit.com/r/emacs/comments/gjukb3/yadm%5Fmagit/">https://www.reddit.com/r/emacs/comments/gjukb3/yadm%5Fmagit/</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;tramp</span>
(add-to-list <span style="color:#e6db74">&#39;tramp-methods</span>
<span style="color:#f92672">`</span>(<span style="color:#e6db74">&#34;yadm&#34;</span>
(tramp-login-program <span style="color:#e6db74">&#34;yadm&#34;</span>)
(tramp-login-args ((<span style="color:#e6db74">&#34;enter&#34;</span>)))
(tramp-login-env ((<span style="color:#e6db74">&#34;SHELL&#34;</span>) <span style="color:#e6db74">&#34;/bin/sh&#34;</span>))
(tramp-remote-shell <span style="color:#e6db74">&#34;/bin/sh&#34;</span>)
(tramp-remote-shell-args (<span style="color:#e6db74">&#34;-c&#34;</span>)))))
(defun my/yadm-magit ()
(interactive)
(magit-status <span style="color:#e6db74">&#34;/yadm::&#34;</span>))
(my-leader-def <span style="color:#e6db74">&#34;cm&#34;</span> <span style="color:#e6db74">&#39;my/yadm-magit</span>)
</code></pre></div><h4 id="open-a-dotfile">Open a dotfile</h4>
<p>Open a file managed by yadm.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/open-yadm-file ()
<span style="color:#e6db74">&#34;Open a file managed by yadm&#34;</span>
(interactive)
(find-file
(<span style="color:#a6e22e">concat</span>
(<span style="color:#a6e22e">file-name-as-directory</span> (getenv <span style="color:#e6db74">&#34;HOME&#34;</span>))
(<span style="color:#a6e22e">completing-read</span>
<span style="color:#e6db74">&#34;yadm files: &#34;</span>
(split-string
(shell-command-to-string <span style="color:#e6db74">&#34;yadm ls-files $HOME --full-name&#34;</span>) <span style="color:#e6db74">&#34;\n&#34;</span>)))))
(general-define-key <span style="color:#e6db74">&#34;C-c f&#34;</span> <span style="color:#e6db74">&#39;my/open-yadm-file</span>)
(my-leader-def <span style="color:#e6db74">&#34;cf&#34;</span> <span style="color:#e6db74">&#39;my/open-yadm-file</span>)
</code></pre></div><h3 id="internet-and-multimedia">Internet &amp; Multimedia</h3>
<h4 id="notmuch">Notmuch</h4>
<p>My notmuch config now resides in <a href="/configs/mail/">Mail.org</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(unless (or my/is-termux my/remote-server)
(load-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;mail.el&#34;</span> user-emacs-directory)))
</code></pre></div><h4 id="elfeed">Elfeed</h4>
<p><a href="https://github.com/skeeto/elfeed">elfeed</a> is an Emacs RSS client.</p>
<p>The advice there sets <code>shr-use-fonts</code> to nil while rendering HTML, so the <code>elfeed-show</code> buffer will use monospace font.</p>
<p>Using my own fork until the modifications are merged into master.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package elfeed
:straight (:repo <span style="color:#e6db74">&#34;SqrtMinusOne/elfeed&#34;</span> :host github)
:if (not my/remote-server)
:commands (elfeed)
:init
(my-leader-def <span style="color:#e6db74">&#34;ae&#34;</span> <span style="color:#e6db74">&#39;elfeed</span>)
:config
(setq elfeed-db-directory <span style="color:#e6db74">&#34;~/.elfeed&#34;</span>)
(setq elfeed-enclosure-default-dir (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~/Downloads&#34;</span>))
(advice-add <span style="color:#a6e22e">#&#39;</span>elfeed-insert-html
:around
(lambda (fun <span style="color:#66d9ef">&amp;rest</span> r)
(let ((shr-use-fonts <span style="color:#66d9ef">nil</span>))
(<span style="color:#a6e22e">apply</span> fun r))))
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;elfeed-search-mode-map</span>
<span style="color:#e6db74">&#34;o&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/elfeed-search-filter-source
<span style="color:#e6db74">&#34;c&#34;</span> <span style="color:#a6e22e">#&#39;</span>elfeed-search-clear-filter
<span style="color:#e6db74">&#34;gl&#34;</span> (lambda () (interactive) (elfeed-search-set-filter <span style="color:#e6db74">&#34;+later&#34;</span>)))
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;elfeed-show-mode-map</span>
<span style="color:#e6db74">&#34;ge&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/elfeed-show-visit-eww))
</code></pre></div><p><a href="https://github.com/remyhonig/elfeed-org">elfeed-org</a> allows configuring Elfeed feeds with an Org file.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package elfeed-org
:straight <span style="color:#66d9ef">t</span>
:after (elfeed)
:config
(setq rmh-elfeed-org-files <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;~/.emacs.d/elfeed.org&#34;</span>))
(elfeed-org))
</code></pre></div><h5 id="some-additions">Some additions</h5>
<p>Filter elfeed search buffer by the feed under the cursor.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/elfeed-search-filter-source (entry)
<span style="color:#e6db74">&#34;Filter elfeed search buffer by the feed under cursor.&#34;</span>
(interactive (<span style="color:#a6e22e">list</span> (elfeed-search-selected :ignore-region)))
(when (elfeed-entry-p entry)
(elfeed-search-set-filter
(<span style="color:#a6e22e">concat</span>
<span style="color:#e6db74">&#34;@6-months-ago &#34;</span>
<span style="color:#e6db74">&#34;+unread &#34;</span>
<span style="color:#e6db74">&#34;=&#34;</span>
(replace-regexp-in-string
(rx <span style="color:#e6db74">&#34;?&#34;</span> (<span style="color:#a6e22e">*</span> not-newline) eos)
<span style="color:#e6db74">&#34;&#34;</span>
(elfeed-feed-url (elfeed-entry-feed entry)))))))
</code></pre></div><p>Open a URL with eww.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/elfeed-show-visit-eww ()
<span style="color:#e6db74">&#34;Visit the current entry in eww&#34;</span>
(interactive)
(let ((link (elfeed-entry-link elfeed-show-entry)))
(when link
(eww link))))
</code></pre></div><h5 id="youtube-and-emms">YouTube &amp; EMMS</h5>
<p>Previously this block was opening MPV with <code>start-process</code>, but now I&rsquo;ve managed to hook up MPV with EMMS. So there is the EMMS+elfeed &ldquo;integration&rdquo;.</p>
<p>The following function converts URLs from Invidious and the like to YouTube.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/get-youtube-url (link)
(let ((watch-id (cadr
(<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#34;watch?v&#34;</span>
(url-parse-query-string
(<span style="color:#a6e22e">substring</span>
(url-filename
(url-generic-parse-url link))
<span style="color:#ae81ff">1</span>))))))
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">&#34;https://www.youtube.com/watch?v=&#34;</span> watch-id)))
</code></pre></div><p>Now, a function to add YouTube link with metadata from elfeed to EMMS.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;emms</span>
(define-emms-source elfeed (entry)
(let ((track (emms-track
<span style="color:#e6db74">&#39;url</span> (my/get-youtube-url (elfeed-entry-link entry)))))
(emms-track-set track <span style="color:#e6db74">&#39;info-title</span> (elfeed-entry-title entry))
(emms-playlist-insert-track track))))
(defun my/elfeed-add-emms-youtube ()
(interactive)
(emms-add-elfeed elfeed-show-entry)
(elfeed-tag elfeed-show-entry <span style="color:#e6db74">&#39;watched</span>)
(elfeed-show-refresh))
(with-eval-after-load <span style="color:#e6db74">&#39;elfeed</span>
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;elfeed-show-mode-map</span>
<span style="color:#e6db74">&#34;gm&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/elfeed-add-emms-youtube))
</code></pre></div><h4 id="emms">EMMS</h4>
<p>EMMS is the Emacs Multi-Media System. I use it to control MPD &amp; MPV.</p>
<p>References:</p>
<ul>
<li><a href="https://www.gnu.org/software/emms/manual/">EMMS Manual</a></li>
<li><a href="https://www.youtube.com/watch?v=xTVN8UDScqk">Uncle Dave&rsquo;s video</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package emms
:straight <span style="color:#66d9ef">t</span>
:if (not my/remote-server)
:commands (emms-smart-browse
emms-browser
emms-add-url
emms-add-file
emms-add-find)
:if (not my/is-termux)
:init
(my-leader-def
:infix <span style="color:#e6db74">&#34;as&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;emms&#34;</span>)
<span style="color:#e6db74">&#34;s&#34;</span> <span style="color:#e6db74">&#39;emms-smart-browse</span>
<span style="color:#e6db74">&#34;b&#34;</span> <span style="color:#e6db74">&#39;emms-browser</span>
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#39;emms-pause</span>
<span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#39;emms-stop</span>
<span style="color:#e6db74">&#34;h&#34;</span> <span style="color:#e6db74">&#39;emms-previous</span>
<span style="color:#e6db74">&#34;l&#34;</span> <span style="color:#e6db74">&#39;emms-next</span>
<span style="color:#e6db74">&#34;u&#34;</span> <span style="color:#e6db74">&#39;emms-player-mpd-connect</span>)
(setq emms-mode-line-icon-enabled-p <span style="color:#66d9ef">nil</span>)
:config
(require <span style="color:#e6db74">&#39;emms-setup</span>)
(require <span style="color:#e6db74">&#39;emms-player-mpd</span>)
(require <span style="color:#e6db74">&#39;emms-player-mpv</span>)
(emms-all)
<span style="color:#75715e">;; MPD setup</span>
&lt;&lt;emms-mpd-setup&gt;&gt;
<span style="color:#75715e">;; MPV setup</span>
&lt;&lt;emms-mpv-setup&gt;&gt;
<span style="color:#75715e">;; evil-lion and evil-commentary shadow some gX bindings</span>
<span style="color:#75715e">;; (add-hook &#39;emms-browser-mode-hook</span>
<span style="color:#75715e">;; (lambda ()</span>
<span style="color:#75715e">;; (evil-lion-mode -1)</span>
<span style="color:#75715e">;; (evil-commentary-mode -1)</span>
<span style="color:#75715e">;; ))</span>
<span style="color:#75715e">;; I have everything I need in polybar</span>
(emms-mode-line-mode <span style="color:#ae81ff">-1</span>)
(emms-playing-time-display-mode <span style="color:#ae81ff">-1</span>)
&lt;&lt;emms-fixes&gt;&gt;)
</code></pre></div><h5 id="mpd">MPD</h5>
<p><a href="https://www.musicpd.org/">mpd</a> is a server for playing music. It has a couple of first-class clients, including curses-based <a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp</a>, but of course, I want to use Emacs.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq emms-source-file-default-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">&#34;~/Music/&#34;</span>))
(add-to-list <span style="color:#e6db74">&#39;emms-info-functions</span> <span style="color:#e6db74">&#39;emms-info-mpd</span>)
(add-to-list <span style="color:#e6db74">&#39;emms-player-list</span> <span style="color:#e6db74">&#39;emms-player-mpd</span>)
(setq emms-player-mpd-server-name <span style="color:#e6db74">&#34;localhost&#34;</span>)
(setq emms-player-mpd-server-port <span style="color:#e6db74">&#34;6600&#34;</span>)
(setq emms-player-mpd-music-directory <span style="color:#e6db74">&#34;~/Music&#34;</span>)
</code></pre></div><p>Connect on setup. For some reason, it stops the mpd playback whenever it connects, but it is not a big issue.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(emms-player-mpd-connect)
</code></pre></div><p>Clear MPD playlist on clearing EMMS playlist. IDK if this is fine for MPD library playlist, I don&rsquo;t use them anyhow.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">&#39;emms-playlist-cleared-hook</span> <span style="color:#e6db74">&#39;emms-player-mpd-clear</span>)
</code></pre></div><p>Set a custom regex for MPD. EMMS sets up the default one from MPD&rsquo;s diagnostic output so that regex opens basically everything, including videos, https links, etc. That is fine if MPD is the only player in EMMS, but as I want to use MPV as well, I override the regex.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(emms-player-set emms-player-mpd
<span style="color:#e6db74">&#39;regex</span>
(emms-player-simple-regexp
<span style="color:#e6db74">&#34;m3u&#34;</span> <span style="color:#e6db74">&#34;ogg&#34;</span> <span style="color:#e6db74">&#34;flac&#34;</span> <span style="color:#e6db74">&#34;mp3&#34;</span> <span style="color:#e6db74">&#34;wav&#34;</span> <span style="color:#e6db74">&#34;mod&#34;</span> <span style="color:#e6db74">&#34;au&#34;</span> <span style="color:#e6db74">&#34;aiff&#34;</span>))
</code></pre></div><p>After all this is done, run <code>M-x emms-cache-set-from-mpd-all</code> to set cache from MPD. If everything is correct, EMMS browser will be populated with MPD database.</p>
<h5 id="mpv">MPV</h5>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>mpv</td>
</tr>
<tr>
<td>youtube-dl</td>
</tr>
</tbody>
</table>
<p><a href="https://mpv.io/">mpv</a> is a decent media player, which has found a place in this configuration because it integrates with youtube-dl.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-to-list <span style="color:#e6db74">&#39;emms-player-list</span> <span style="color:#e6db74">&#39;emms-player-mpv</span> <span style="color:#66d9ef">t</span>)
</code></pre></div><p>Also a custom regex. My demands for MPV include running <code>youtube-dl</code>, so there is a regex that matches youtube.com or some of the video formats.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(emms-player-set emms-player-mpv
<span style="color:#e6db74">&#39;regex</span>
(rx (or (<span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;https://&#34;</span> (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">&#34;youtube.com&#34;</span> (<span style="color:#a6e22e">*</span> nonl))
(<span style="color:#a6e22e">+</span> (<span style="color:#e6db74">? </span>(or <span style="color:#e6db74">&#34;https://&#34;</span> <span style="color:#e6db74">&#34;http://&#34;</span>))
(<span style="color:#a6e22e">*</span> nonl)
(regexp (<span style="color:#a6e22e">eval</span> (emms-player-simple-regexp
<span style="color:#e6db74">&#34;mp4&#34;</span> <span style="color:#e6db74">&#34;mov&#34;</span> <span style="color:#e6db74">&#34;wmv&#34;</span> <span style="color:#e6db74">&#34;webm&#34;</span> <span style="color:#e6db74">&#34;flv&#34;</span> <span style="color:#e6db74">&#34;avi&#34;</span> <span style="color:#e6db74">&#34;mkv&#34;</span>)))))))
</code></pre></div><p>By default MPV plays the video in the best possible quality, which may be pretty high, even too high with limited bandwidth. So here is the logic to choose the quality.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/youtube-dl-quality-list
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;bestvideo[height&lt;=720]+bestaudio/best[height&lt;=720]&#34;</span>
<span style="color:#e6db74">&#34;bestvideo[height&lt;=480]+bestaudio/best[height&lt;=480]&#34;</span>
<span style="color:#e6db74">&#34;bestvideo[height&lt;=1080]+bestaudio/best[height&lt;=1080]&#34;</span>))
(setq my/default-emms-player-mpv-parameters
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;--quiet&#34;</span> <span style="color:#e6db74">&#34;--really-quiet&#34;</span> <span style="color:#e6db74">&#34;--no-audio-display&#34;</span>))
(defun my/set-emms-mpd-youtube-quality (quality)
(interactive <span style="color:#e6db74">&#34;P&#34;</span>)
(unless quality
(setq quality (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">&#34;Quality: &#34;</span> my/youtube-dl-quality-list <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)))
(setq emms-player-mpv-parameters
<span style="color:#f92672">`</span>(<span style="color:#f92672">,@</span>my/default-emms-player-mpv-parameters <span style="color:#f92672">,</span>(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;--ytdl-format=%s&#34;</span> quality))))
(my/set-emms-mpd-youtube-quality (<span style="color:#a6e22e">car</span> my/youtube-dl-quality-list))
</code></pre></div><p>Now <code>emms-add-url</code> should work on YouTube URLs just fine. Just keep in mind that it will only add the URL to the playlist, not play it right away.</p>
<h5 id="cache-cleanup">Cache cleanup</h5>
<p>All the added URLs reside in the EMMS cache after being played. I don&rsquo;t want them to stay there for a long time, so here is a handy function to clean it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/emms-cleanup-urls ()
(interactive)
(let ((keys-to-delete <span style="color:#f92672">&#39;</span>()))
(<span style="color:#a6e22e">maphash</span> (lambda (key value)
(when (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;type</span> value)) <span style="color:#e6db74">&#39;url</span>)
(add-to-list <span style="color:#e6db74">&#39;keys-to-delete</span> key)))
emms-cache-db)
(dolist (key keys-to-delete)
(<span style="color:#a6e22e">remhash</span> key emms-cache-db)))
(setq emms-cache-dirty <span style="color:#66d9ef">t</span>))
(my-leader-def <span style="color:#e6db74">&#34;asc&#34;</span> <span style="color:#a6e22e">#&#39;</span>my/emms-cleanup-urls)
</code></pre></div><h5 id="fetching-lyrics">Fetching lyrics</h5>
<p>My package for fetching EMMS lyrics and album covers.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lyrics-fetcher
:straight <span style="color:#66d9ef">t</span>
:after (emms)
:init
(my-leader-def
<span style="color:#e6db74">&#34;ast&#34;</span> <span style="color:#a6e22e">#&#39;</span>lyrics-fetcher-show-lyrics
<span style="color:#e6db74">&#34;asT&#34;</span> <span style="color:#a6e22e">#&#39;</span>lyrics-fetcher-show-lyrics-query)
:config
(setq lyrics-fetcher-genius-access-token
(password-store-get <span style="color:#e6db74">&#34;My_Online/APIs/genius.com&#34;</span>))
(general-define-key
:states <span style="color:#f92672">&#39;</span>(emacs normal)
:keymaps <span style="color:#e6db74">&#39;emms-browser-mode-map</span>
<span style="color:#e6db74">&#34;gl&#34;</span> <span style="color:#e6db74">&#39;lyrics-fetcher-emms-browser-show-at-point</span>
<span style="color:#e6db74">&#34;gC&#34;</span> <span style="color:#e6db74">&#39;lyrics-fetcher-emms-browser-fetch-covers-at-point</span>
<span style="color:#e6db74">&#34;go&#34;</span> <span style="color:#e6db74">&#39;lyrics-fetcher-emms-browser-open-large-cover-at-point</span>))
</code></pre></div><h5 id="some-keybindings">Some keybindings</h5>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;emms-browser</span>
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;emms-browser-mode-map</span>
<span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#39;quit-window</span>))
(with-eval-after-load <span style="color:#e6db74">&#39;emms</span>
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;emms-playlist-mode-map</span>
<span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#39;quit-window</span>))
</code></pre></div><h5 id="emms-and-mpd-fixes">EMMS &amp; mpd Fixes</h5>
<p><del>Some fixes until I submit a patch.</del> I&rsquo;ve submitted a patch for with these fixes, so I&rsquo;ll remove this section eventually.</p>
<p>For some reason EMMS doesn&rsquo;t fetch <code>albumartist</code> from MPD. Overriding this function fixes that.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun emms-info-mpd-process (track info)
(dolist (data info)
(let ((name (<span style="color:#a6e22e">car</span> data))
(value (<span style="color:#a6e22e">cdr</span> data)))
(setq name (cond ((string= name <span style="color:#e6db74">&#34;artist&#34;</span>) <span style="color:#e6db74">&#39;info-artist</span>)
((string= name <span style="color:#e6db74">&#34;albumartist&#34;</span>) <span style="color:#e6db74">&#39;info-albumartist</span>)
((string= name <span style="color:#e6db74">&#34;composer&#34;</span>) <span style="color:#e6db74">&#39;info-composer</span>)
((string= name <span style="color:#e6db74">&#34;performer&#34;</span>) <span style="color:#e6db74">&#39;info-performer</span>)
((string= name <span style="color:#e6db74">&#34;title&#34;</span>) <span style="color:#e6db74">&#39;info-title</span>)
((string= name <span style="color:#e6db74">&#34;album&#34;</span>) <span style="color:#e6db74">&#39;info-album</span>)
((string= name <span style="color:#e6db74">&#34;track&#34;</span>) <span style="color:#e6db74">&#39;info-tracknumber</span>)
((string= name <span style="color:#e6db74">&#34;disc&#34;</span>) <span style="color:#e6db74">&#39;info-discnumber</span>)
((string= name <span style="color:#e6db74">&#34;date&#34;</span>) <span style="color:#e6db74">&#39;info-year</span>)
((string= name <span style="color:#e6db74">&#34;genre&#34;</span>) <span style="color:#e6db74">&#39;info-genre</span>)
((string= name <span style="color:#e6db74">&#34;time&#34;</span>)
(setq value (<span style="color:#a6e22e">string-to-number</span> value))
<span style="color:#e6db74">&#39;info-playing-time</span>)
(<span style="color:#66d9ef">t</span> <span style="color:#66d9ef">nil</span>)))
(when name
(emms-track-set track name value)))))
</code></pre></div><p>Also, <code>emms-player-mpd-get-alists</code> has an interesting bug. This function parses the response to <code>listallinfo</code>, which looks something like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">tag1: value1
tag2: value2
...
tag1: value1&#39;
tag2: value2&#39;
</code></pre></div><p>This structure has to be converted to list of alists, which looks like:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">((&#34;tag1&#34; . &#34;value1&#34;
&#34;tag2&#34; . &#34;value2&#34;)
(&#34;tag1&#34; . &#34;value1&#39;&#34;
(&#34;tag2&#34; . &#34;value2&#39;&#34;)))
</code></pre></div><p>The original implementation creates a new alist whenever it encounters a tag it has already put in the current alist. Which doesn&rsquo;t work too well if some tags don&rsquo;t repeat, if the order is messed up, etc.</p>
<p>Fortunately, according to the <a href="https://mpd.readthedocs.io/en/latest/protocol.html#command-lsinfo">protocol specification</a>, each new record has to start with <code>file</code>, <code>directory</code> or <code>playlist</code>. I&rsquo;ve overridden the function with that in mind and it fixed the import, at least in my case.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun emms-player-mpd-get-alists (info)
<span style="color:#e6db74">&#34;Turn the given parsed INFO from MusicPD into an list of alists.
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">The list will be in reverse order.&#34;</span>
(when (and info
(<span style="color:#a6e22e">null</span> (<span style="color:#a6e22e">car</span> info)) <span style="color:#75715e">; no error has occurred</span>
(<span style="color:#a6e22e">cdr</span> info)) <span style="color:#75715e">; data exists</span>
(let ((alists <span style="color:#66d9ef">nil</span>)
(alist <span style="color:#66d9ef">nil</span>)
cell)
(dolist (line (<span style="color:#a6e22e">cdr</span> info))
(when (setq cell (emms-player-mpd-parse-line line))
(if (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">car</span> cell) <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;file&#34;</span> <span style="color:#e6db74">&#34;directory&#34;</span> <span style="color:#e6db74">&#34;playlist&#34;</span>))
(setq alists (<span style="color:#a6e22e">cons</span> alist alists)
alist (<span style="color:#a6e22e">list</span> cell))
(setq alist (<span style="color:#a6e22e">cons</span> cell alist)))))
(when alist
(setq alists (<span style="color:#a6e22e">cons</span> alist alists)))
alists)))
</code></pre></div><h4 id="eww">EWW</h4>
<p>Emacs built-in web browser. <del>I wonder if anyone actually uses it.</del></p>
<p>I use it occasionally to open links in elfeed.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/toggle-shr-use-fonts ()
<span style="color:#e6db74">&#34;Toggle the shr-use-fonts variable in buffer&#34;</span>
(interactive)
(setq-local shr-use-fonts (not shr-use-fonts)))
(my-leader-def <span style="color:#e6db74">&#34;aw&#34;</span> <span style="color:#e6db74">&#39;eww</span>)
(general-define-key
:keymaps <span style="color:#e6db74">&#39;eww-mode-map</span>
<span style="color:#e6db74">&#34;+&#34;</span> <span style="color:#e6db74">&#39;text-scale-increase</span>
<span style="color:#e6db74">&#34;-&#34;</span> <span style="color:#e6db74">&#39;text-scale-decrease</span>)
</code></pre></div><h4 id="erc">ERC</h4>
<p>ERC is a built-it Emacs IRC client.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package erc
:commands (erc erc-tls)
:straight (:type built-in)
:init
(my-leader-def <span style="color:#e6db74">&#34;ai&#34;</span> <span style="color:#a6e22e">#&#39;</span>erc-tls)
:config
<span style="color:#75715e">;; Logging</span>
(setq erc-log-channels-directory <span style="color:#e6db74">&#34;~/.erc/logs&#34;</span>)
(setq erc-save-buffer-on-part <span style="color:#66d9ef">t</span>)
<span style="color:#75715e">;; Config of my ZNC instance.</span>
(setq erc-server <span style="color:#e6db74">&#34;sqrtminusone.xyz&#34;</span>)
(setq erc-port <span style="color:#ae81ff">1984</span>)
(setq erc-nick <span style="color:#e6db74">&#34;sqrtminusone&#34;</span>)
(setq erc-user-full-name <span style="color:#e6db74">&#34;Pavel Korytov&#34;</span>)
(setq erc-password (password-store-get <span style="color:#e6db74">&#34;Selfhosted/ZNC&#34;</span>))
(setq erc-kill-buffer-on-part <span style="color:#66d9ef">t</span>)
(setq erc-track-shorten-start <span style="color:#ae81ff">8</span>))
</code></pre></div><p>Exclude everything but actual messages from notifications.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq erc-track-exclude-types <span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;NICK&#34;</span> <span style="color:#e6db74">&#34;JOIN&#34;</span> <span style="color:#e6db74">&#34;LEAVE&#34;</span> <span style="color:#e6db74">&#34;QUIT&#34;</span> <span style="color:#e6db74">&#34;PART&#34;</span>
<span style="color:#e6db74">&#34;301&#34;</span> <span style="color:#75715e">; away notice</span>
<span style="color:#e6db74">&#34;305&#34;</span> <span style="color:#75715e">; return from awayness</span>
<span style="color:#e6db74">&#34;306&#34;</span> <span style="color:#75715e">; set awayness</span>
<span style="color:#e6db74">&#34;324&#34;</span> <span style="color:#75715e">; modes</span>
<span style="color:#e6db74">&#34;329&#34;</span> <span style="color:#75715e">; channel creation date</span>
<span style="color:#e6db74">&#34;332&#34;</span> <span style="color:#75715e">; topic notice</span>
<span style="color:#e6db74">&#34;333&#34;</span> <span style="color:#75715e">; who set the topic</span>
<span style="color:#e6db74">&#34;353&#34;</span> <span style="color:#75715e">; Names notice</span>
))
</code></pre></div><p>A plugin to highlight IRC nicknames:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package erc-hl-nicks
:hook (erc-mode <span style="color:#f92672">.</span> erc-hl-nicks-mode)
:after (erc)
:straight <span style="color:#66d9ef">t</span>)
</code></pre></div><p>ZNC support. Seems to provide a few nice features for ZNC.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package znc
:straight <span style="color:#66d9ef">t</span>
:after (erc))
</code></pre></div><h4 id="google-translate">Google Translate</h4>
<p>Emacs interface to Google Translate.</p>
<p>Can&rsquo;t make it load lazily for some strange reason.</p>
<p>References:</p>
<ul>
<li><a href="https://github.com/atykhonov/google-translate">google-translate repo</a></li>
<li><a href="https://github.com/atykhonov/google-translate/issues/137#issuecomment-728278849">issue with ttk error fix</a></li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package google-translate
:straight <span style="color:#66d9ef">t</span>
:functions (my-google-translate-at-point google-translate--search-tkk)
:custom
(google-translate-backend-method <span style="color:#e6db74">&#39;curl</span>)
:config
(require <span style="color:#e6db74">&#39;facemenu</span>)
(defun google-translate--search-tkk ()
<span style="color:#e6db74">&#34;Search TKK.&#34;</span>
(<span style="color:#a6e22e">list</span> <span style="color:#ae81ff">430675</span> <span style="color:#ae81ff">2721866130</span>))
(defun my-google-translate-at-point()
<span style="color:#e6db74">&#34;reverse translate if prefix&#34;</span>
(interactive)
(if current-prefix-arg
(google-translate-at-point)
(google-translate-at-point-reverse)))
(setq google-translate-translation-directions-alist
<span style="color:#f92672">&#39;</span>((<span style="color:#e6db74">&#34;en&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;ru&#34;</span>)
(<span style="color:#e6db74">&#34;ru&#34;</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">&#34;en&#34;</span>))))
(my-leader-def
:infix <span style="color:#e6db74">&#34;at&#34;</span>
<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#f92672">&#39;</span>(:which-key <span style="color:#e6db74">&#34;google translate&#34;</span>)
<span style="color:#e6db74">&#34;p&#34;</span> <span style="color:#e6db74">&#39;google-translate-at-point</span>
<span style="color:#e6db74">&#34;P&#34;</span> <span style="color:#e6db74">&#39;google-translate-at-point-reverse</span>
<span style="color:#e6db74">&#34;q&#34;</span> <span style="color:#e6db74">&#39;google-translate-query-translate</span>
<span style="color:#e6db74">&#34;Q&#34;</span> <span style="color:#e6db74">&#39;google-translate-query-translate-reverse</span>
<span style="color:#e6db74">&#34;t&#34;</span> <span style="color:#e6db74">&#39;google-translate-smooth-translate</span>)
</code></pre></div><h3 id="reading-documentation">Reading documentation</h3>
<h4 id="tldr">tldr</h4>
<p><a href="https://tldr.sh/">tldr</a> is a collaborative project providing cheatsheets for various console commands. For some reason, the built-in download in the package is broken, so I use my own function.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package tldr
:straight <span style="color:#66d9ef">t</span>
:commands (tldr)
:config
(setq tldr-source-zip-url <span style="color:#e6db74">&#34;https://github.com/tldr-pages/tldr/archive/refs/heads/main.zip&#34;</span>)
(defun tldr-update-docs ()
(interactive)
(shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;curl -L %s --output %s&#34;</span> tldr-source-zip-url tldr-saved-zip-path))
(when (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">&#34;/tmp/tldr&#34;</span>)
(delete-directory <span style="color:#e6db74">&#34;/tmp/tldr&#34;</span> <span style="color:#66d9ef">t</span>))
(shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;unzip -d /tmp/tldr/ %s&#34;</span> tldr-saved-zip-path))
(when (<span style="color:#a6e22e">file-exists-p</span> tldr-directory-path)
(delete-directory tldr-directory-path <span style="color:#e6db74">&#39;recursive</span> <span style="color:#e6db74">&#39;no-trash</span>))
(shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;mv %s %s&#34;</span> <span style="color:#e6db74">&#34;/tmp/tldr/tldr-main&#34;</span> tldr-directory-path))))
(my-leader-def <span style="color:#e6db74">&#34;hT&#34;</span> <span style="color:#e6db74">&#39;tldr</span>)
</code></pre></div><h4 id="man-and-info">man &amp; info</h4>
<p>Of course, Emacs can also display man and info pages.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq Man-width-max <span style="color:#ae81ff">180</span>)
(my-leader-def <span style="color:#e6db74">&#34;hM&#34;</span> <span style="color:#e6db74">&#39;man</span>)
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;Info-mode-map</span>
(kbd <span style="color:#e6db74">&#34;RET&#34;</span>) <span style="color:#e6db74">&#39;Info-follow-nearest-node</span>)
(defun my/man-fix-width (<span style="color:#66d9ef">&amp;rest</span> _)
(setq-local Man-width (<span style="color:#a6e22e">-</span> (window-width) <span style="color:#ae81ff">4</span>)))
(advice-add <span style="color:#a6e22e">#&#39;</span>Man-update-manpage :before <span style="color:#a6e22e">#&#39;</span>my/man-fix-width)
</code></pre></div><h4 id="devdocs-dot-io">devdocs.io</h4>
<p>Finally, there is also an Emacs plugin for <a href="https://devdocs.io">devdocs.io</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package devdocs
:straight <span style="color:#66d9ef">t</span>
:commands (devdocs-install devdocs-lookup)
:init
(my-leader-def
<span style="color:#e6db74">&#34;he&#34;</span> <span style="color:#a6e22e">#&#39;</span>devdocs-lookup
<span style="color:#e6db74">&#34;hE&#34;</span> <span style="color:#a6e22e">#&#39;</span>devdocs-install))
</code></pre></div><h3 id="utilities">Utilities</h3>
<h4 id="pass">pass</h4>
<p>I use <a href="https://www.passwordstore.org/">pass</a> as my password manager. Expectedly, there is Emacs frontend for it.</p>
<p>Although I use <a href="https://github.com/carnager/rofi-pass">this rofi frontend</a> for actually inserting passwords.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pass
:straight <span style="color:#66d9ef">t</span>
:commands (pass)
:init
(my-leader-def <span style="color:#e6db74">&#34;ak&#34;</span> <span style="color:#a6e22e">#&#39;</span>pass)
:config
(setq pass-show-keybindings <span style="color:#66d9ef">nil</span>))
</code></pre></div><h4 id="docker">Docker</h4>
<p>A package to manage docker containers from Emacs.</p>
<p>The file <code>progidy-config.el</code> sets variable <code>my/docker-directories</code>, which allows to</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package docker
:straight <span style="color:#66d9ef">t</span>
:commands (docker)
:init
(my-leader-def <span style="color:#e6db74">&#34;ao&#34;</span> <span style="color:#e6db74">&#39;docker</span>))
</code></pre></div><p>By default, docker commands are run in <code>default-directory</code>. Even worse, transient doesn&rsquo;t allow to set <code>default-directory</code> temporarily, via <code>let</code>. But often I don&rsquo;t want to change <code>default-directory</code> of a buffer (e.g. via Dired) to run a command from there.</p>
<p>So I decided to implement the following advice:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
(defun my/docker-override-dir (fun <span style="color:#66d9ef">&amp;rest</span> args)
(let ((default-directory (or my/selected-docker-directory default-directory)))
(setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
(<span style="color:#a6e22e">apply</span> fun args)))
</code></pre></div><p>It overrides <code>default-directory</code> for the first launch of a function. Now, add the advice to the required functions from <code>docker.el</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">&#39;docker</span>
(advice-add <span style="color:#a6e22e">#&#39;</span>docker-compose-run-docker-compose-async :around <span style="color:#a6e22e">#&#39;</span>my/docker-override-dir)
(advice-add <span style="color:#a6e22e">#&#39;</span>docker-compose-run-docker-compose :around <span style="color:#a6e22e">#&#39;</span>my/docker-override-dir)
(advice-add <span style="color:#a6e22e">#&#39;</span>docker-run-docker-async :around <span style="color:#a6e22e">#&#39;</span>my/docker-override-dir)
(advice-add <span style="color:#a6e22e">#&#39;</span>docker-run-docker :around <span style="color:#a6e22e">#&#39;</span>my/docker-override-dir))
</code></pre></div><p>And here is a function which prompts the user for the directory. File <code>progidy-config.el</code> sets an alist of possible directories, look the section about <a href="#progidy">progidy</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/docker-from-dir ()
(interactive)
(when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;my/docker-directories</span>))
(<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">&#34;prodigy-config&#34;</span>)))
(let* ((directories
(<span style="color:#a6e22e">mapcar</span>
(lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">&#34;%-30s %s&#34;</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
my/docker-directories))
(selected-directory
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">&#34;Docker: &#34;</span> directories <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">&#34;^&#34;</span>)
directories))))
(setq my/selected-docker-directory selected-directory)
(docker)))
(my-leader-def <span style="color:#e6db74">&#34;aO&#34;</span> <span style="color:#e6db74">&#39;my/docker-from-dir</span>)
</code></pre></div><h4 id="progidy">Progidy</h4>
<p><a href="https://github.com/rejeep/prodigy.el">prodigy.el</a> is a package to run various services. I&rsquo;ve previously used tmuxp + tmux, but want to try this as well.</p>
<p>The actual service definitions are in the <code>~/.emacs.d/prodigy.org</code>, which tangles to <code>prodigy-config.el</code>. Both files are encrypted in yadm, as they contain personal data.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package prodigy
:straight <span style="color:#66d9ef">t</span>
:commands (prodigy)
:init
(my-leader-def <span style="color:#e6db74">&#34;ap&#34;</span> <span style="color:#e6db74">&#39;prodigy</span>)
:config
(when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">&#39;my/docker-directories</span>))
(<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">&#34;prodigy-config&#34;</span>)))
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;prodigy-view-mode-map</span>
<span style="color:#e6db74">&#34;C-h&#34;</span> <span style="color:#e6db74">&#39;evil-window-left</span>
<span style="color:#e6db74">&#34;C-l&#34;</span> <span style="color:#e6db74">&#39;evil-window-right</span>
<span style="color:#e6db74">&#34;C-k&#34;</span> <span style="color:#e6db74">&#39;evil-window-up</span>
<span style="color:#e6db74">&#34;C-j&#34;</span> <span style="color:#e6db74">&#39;evil-window-down</span>))
</code></pre></div><p>A few functions to work with apps on ports.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/get-apps-on-ports ()
(<span style="color:#a6e22e">mapcar</span>
(lambda (line)
(let* ((split (split-string line (rx (| (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">&#34; &#34;</span>) (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">&#34;\t&#34;</span>)))))
(process (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">6</span>)))
<span style="color:#f92672">`</span>((netid <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">0</span>))
(state <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">1</span>))
(recv-q <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">2</span>))
(send-q <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">3</span>))
<span style="color:#f92672">,@</span>(let ((data (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">4</span>)))
(save-match-data
(<span style="color:#a6e22e">string-match</span> (rx (group-n <span style="color:#ae81ff">1</span> (<span style="color:#a6e22e">*</span> nonl)) <span style="color:#e6db74">&#34;:&#34;</span> (group-n <span style="color:#ae81ff">2</span> (or (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">&#34;*&#34;</span>))) data)
<span style="color:#f92672">`</span>((local-address <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(match-string <span style="color:#ae81ff">1</span> data))
(local-port <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(match-string <span style="color:#ae81ff">2</span> data)))))
<span style="color:#f92672">,@</span>(unless (string-empty-p process)
<span style="color:#f92672">`</span>((pid <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(save-match-data
(<span style="color:#a6e22e">string-match</span> (rx <span style="color:#e6db74">&#34;pid=&#34;</span> (<span style="color:#a6e22e">+</span> num)) process)
(<span style="color:#a6e22e">string-to-number</span> (<span style="color:#a6e22e">substring</span> (match-string <span style="color:#ae81ff">0</span> process) <span style="color:#ae81ff">4</span>)))))))))
(seq-filter
(lambda (s) (not (string-empty-p s)))
(split-string
(shell-command-to-string <span style="color:#e6db74">&#34;ss -tulpnH | grep LISTEN&#34;</span>) <span style="color:#e6db74">&#34;\n&#34;</span>))))
(defun my/kill-app-on-port (port <span style="color:#66d9ef">&amp;optional</span> <span style="color:#a6e22e">signal</span>)
(let ((apps (my/get-apps-on-ports)))
(dolist (app apps)
(when (<span style="color:#a6e22e">string-equal</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;local-port</span> app)) port)
(<span style="color:#a6e22e">signal-process</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;pid</span> app)) (or <span style="color:#a6e22e">signal</span> <span style="color:#ae81ff">15</span>))
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">&#34;Sent %d to %d&#34;</span> (or <span style="color:#a6e22e">signal</span> <span style="color:#ae81ff">15</span>) (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">&#39;pid</span> app)))))))
</code></pre></div><h4 id="screenshot-dot-el">screenshot.el</h4>
<p>Tecosaur&rsquo;s plugin to make beautiful code screenshots.</p>
<table>
<thead>
<tr>
<th>Guix dependency</th>
</tr>
</thead>
<tbody>
<tr>
<td>imagemagick</td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package screenshot
:straight (:repo <span style="color:#e6db74">&#34;tecosaur/screenshot&#34;</span> :host github :files (<span style="color:#e6db74">&#34;screenshot.el&#34;</span>))
:if (display-graphic-p)
:commands (screenshot)
:init
(my-leader-def <span style="color:#e6db74">&#34;S&#34;</span> <span style="color:#e6db74">&#39;screenshot</span>))
</code></pre></div><h4 id="proced">proced</h4>
<p>proced is an Emacs built-it process viewer, like top.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def <span style="color:#e6db74">&#34;ah&#34;</span> <span style="color:#e6db74">&#39;proced</span>)
(setq proced-auto-update-interval <span style="color:#ae81ff">1</span>)
(add-hook <span style="color:#e6db74">&#39;proced-mode-hook</span> (lambda ()
(visual-line-mode <span style="color:#ae81ff">-1</span>)
(setq-local truncate-lines <span style="color:#66d9ef">t</span>)
(proced-toggle-auto-update <span style="color:#ae81ff">1</span>)))
</code></pre></div><h4 id="guix">Guix</h4>
<p>An Emacs package to help managing GNU Guix.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package guix
:straight <span style="color:#66d9ef">t</span>
:commands (guix)
:init
(my-leader-def <span style="color:#e6db74">&#34;ag&#34;</span> <span style="color:#e6db74">&#39;guix</span>))
</code></pre></div><h3 id="productivity">Productivity</h3>
<h4 id="pomidor">Pomidor</h4>
<p>A simple pomodoro technique timer.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pomidor
:straight <span style="color:#66d9ef">t</span>
:commands (pomidor)
:init
(my-leader-def <span style="color:#e6db74">&#34;aP&#34;</span> <span style="color:#a6e22e">#&#39;</span>pomidor)
:config
(setq pomidor-sound-tick <span style="color:#66d9ef">nil</span>)
(setq pomidor-sound-tack <span style="color:#66d9ef">nil</span>)
(general-define-key
:states <span style="color:#f92672">&#39;</span>(normal)
:keymaps <span style="color:#e6db74">&#39;pomidor-mode-map</span>
(kbd <span style="color:#e6db74">&#34;q&#34;</span>) <span style="color:#a6e22e">#&#39;</span>quit-window
(kbd <span style="color:#e6db74">&#34;Q&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-quit
(kbd <span style="color:#e6db74">&#34;R&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-reset
(kbd <span style="color:#e6db74">&#34;h&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-hold
(kbd <span style="color:#e6db74">&#34;H&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-unhold
(kbd <span style="color:#e6db74">&#34;RET&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-stop
(kbd <span style="color:#e6db74">&#34;M-RET&#34;</span>) <span style="color:#a6e22e">#&#39;</span>pomidor-break))
</code></pre></div><h4 id="calendar">Calendar</h4>
<p>Emacs' built-in calendar. Can even calculate sunrise and sunset times.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq calendar-date-style <span style="color:#e6db74">&#39;iso</span>) <span style="color:#75715e">;; YYYY/mm/dd</span>
(setq calendar-week-start-day <span style="color:#ae81ff">1</span>)
(setq calendar-time-display-form <span style="color:#f92672">&#39;</span>(24-hours <span style="color:#e6db74">&#34;:&#34;</span> minutes))
(setq calendar-latitude <span style="color:#ae81ff">59.9375</span>)
(setq calendar-longitude <span style="color:#ae81ff">30.308611</span>)
</code></pre></div><h3 id="fun">Fun</h3>
<h4 id="discord-integration">Discord integration</h4>
<p>Integration with Discord. Shows which file is being edited in Emacs.</p>
<p>In order for this to work in Guix, a service is necessary - <a href="/configs/desktop/">Discord rich presence</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package elcord
:straight <span style="color:#66d9ef">t</span>
:if (and (or
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">&#34;indigo&#34;</span>)
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">&#34;eminence&#34;</span>))
(not my/slow-ssh)
(not my/remote-server))
:config
(elcord-mode)
(add-to-list <span style="color:#e6db74">&#39;elcord-boring-buffers-regexp-list</span>
(rx bos (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">&#34;-&#34;</span> (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">&#34;-&#34;</span> (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">&#34;.org&#34;</span> eos))
(add-to-list <span style="color:#e6db74">&#39;elcord-boring-buffers-regexp-list</span>
(rx bos (<span style="color:#a6e22e">=</span> <span style="color:#ae81ff">14</span> num) <span style="color:#e6db74">&#34;-&#34;</span> (<span style="color:#a6e22e">*</span> not-newline) <span style="color:#e6db74">&#34;.org&#34;</span> eos)))
</code></pre></div><h4 id="snow">Snow</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package snow
:straight (:repo <span style="color:#e6db74">&#34;alphapapa/snow.el&#34;</span> :host github)
:commands (snow))
</code></pre></div><h4 id="zone">Zone</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package zone
:ensure <span style="color:#66d9ef">nil</span>
:config
(setq original-zone-programs (<span style="color:#a6e22e">copy-sequence</span> zone-programs)))
(defun my/zone-with-select ()
(interactive)
(ivy-read <span style="color:#e6db74">&#34;Zone programs&#34;</span>
(cl-pairlis
(cl-mapcar <span style="color:#e6db74">&#39;symbol-name</span> original-zone-programs)
original-zone-programs)
:action (lambda (elem)
(setq zone-programs (<span style="color:#a6e22e">vector</span> (<span style="color:#a6e22e">cdr</span> elem)))
(zone))))
</code></pre></div><h2 id="guix-settings">Guix settings</h2>
<table>
<thead>
<tr>
<th>Guix dependency</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>emacs-vterm</td>
<td>A vterm package</td>
</tr>
<tr>
<td>ripgrep</td>
<td>A recursive search tool</td>
</tr>
<tr>
<td>the-silver-searcher</td>
<td>Another recursive search tool</td>
</tr>
</tbody>
</table>
<p><a id="code-snippet--packages"></a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my/format-guix-dependencies)
</code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-scheme" data-lang="scheme">(<span style="color:#a6e22e">specifications-&gt;manifest</span>
<span style="color:#f92672">&#39;</span>(<span style="color:#e6db74">&#34;emacs-native-comp&#34;</span>
&lt;&lt;packages()&gt;&gt;))
</code></pre></div>
</div>
</div><div id="footer" class="mb-5">
<hr>
<div class="container text-center">
</div>
<div class="container text-center">
<a href="https://sqrtminusone.xyz/" title="Pavel Korytov, 2021"><small>Pavel Korytov, 2021</small></a>
</div>
</div>
</body>
</html>