mirror of
https://github.com/SqrtMinusOne/sqrtminusone.github.io.git
synced 2025-12-11 16:13:03 +03:00
6000 lines
650 KiB
HTML
6000 lines
650 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’t hate one another, no young boy will march to war and I will clean up my Emacs config. But that day isn’t today.</p>
|
||
</blockquote>
|
||
<h2 id="introduction">Introduction</h2>
|
||
<p>My configuration of <a href="https://www.gnu.org/software/emacs/">GNU Emacs</a>, an awesome <del>text editor</del> program that can do almost anything.</p>
|
||
<p>At the moment of this writing, this “almost anything” includes:</p>
|
||
<ul>
|
||
<li><strong>Writing code</strong>. With LSP & Co this functionality of Emacs may rival that of IDEs, and is at least on par with editors like VS Code.<br />
|
||
One thing where Emacs is particularly good is writing Lisp code, e.g. Clojure, Common Lisp, and, of course, Emacs Lisp.</li>
|
||
<li><strong>Literate programming</strong> with Org Mode. That includes:
|
||
<ul>
|
||
<li>Configuring the entirety of my software (that can be configured with text files).</li>
|
||
<li>Interactive programming like one provided by Jupyter Notebook.</li>
|
||
</ul>
|
||
</li>
|
||
<li><strong>File management</strong>. Dired is my primary file manager.</li>
|
||
<li><strong>Email</strong>, with notmuch.</li>
|
||
<li><strong>Multimedia management</strong>, with EMMS.</li>
|
||
<li><strong>RSS feed reader</strong>, with elfeed.</li>
|
||
<li><strong>Task management</strong>, with Org Mode.</li>
|
||
<li><strong>Managing passwords</strong>, with pass.</li>
|
||
<li><strong>IRC</strong>, with ERC.</li>
|
||
<li><strong>Formatting documents</strong>, also with Org Mode. When the document is too complex, I prefer to write plain LaTeX, but I’ve come to the conclusion that in most cases Org Mode covers my needs there.</li>
|
||
<li><strong>X Window management</strong>, with EXWM. So I could say I literally live in Emacs.</li>
|
||
<li>…</li>
|
||
</ul>
|
||
<p>As I have hinted above, this file is a piece of literate configuration, which means that the actual code is interweaved with English-language commentary. One could argue that the commentary, not the code, is the primary entity of the file.</p>
|
||
<p>But at the same time, the configuration is personal, so the primary benefactor of the literate structure is me. The commentary is primarily meant to capture my state of mind at the moment of writing the code, which is immensely helpful for maintaining the code in the future. So the quality and quantity of the commentary are… varying.</p>
|
||
<p>Occasionally I save some promising experimentations from scratch buffers without much comment. Or I may not have enough time to describe things in substantial detail. Or, as it is at the moment when I’m writing this, I have the time to write down whatever I consider necessary. Or, when I’m writing a blog post about Emacs configuration, I usually incorporate some things back into this config.</p>
|
||
<p>And of course, human minds share many similarities, so if you are an avid Emacs user, you probably can extract something of value from here. Although in this case, your configuration has a decent chance to have everything I’m doing here. But who knows, because somehow mine is over 6000 LoC at the moment, despite being just a bit over a year old.</p>
|
||
<p>If however, by some twist of fate, this document is one of the first things you see about Emacs, it won’t be a good resource for you. And you definitely shouldn’t try to launch this config as it is. If I could suggest only one resource, I’d advise David Wilson’s <a href="https://www.youtube.com/c/SystemCrafters">System Crafters</a> YouTube channel.</p>
|
||
<div class="ox-hugo-toc toc">
|
||
<div class="heading">Table of Contents</div>
|
||
<ul>
|
||
<li><a href="#introduction">Introduction</a></li>
|
||
<li><a href="#some-remarks">Some remarks</a></li>
|
||
<li><a href="#bootstrap">Bootstrap</a>
|
||
<ul>
|
||
<li><a href="#packages">Packages</a>
|
||
<ul>
|
||
<li><a href="#straight-dot-el">straight.el</a></li>
|
||
<li><a href="#use-package">use-package</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#variables-and-environment">Variables & environment</a></li>
|
||
<li><a href="#performance">Performance</a>
|
||
<ul>
|
||
<li><a href="#measure-startup-speed">Measure startup speed</a></li>
|
||
<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="#config-files">Config files</a>
|
||
<ul>
|
||
<li><a href="#custom-file-location">Custom file location</a></li>
|
||
<li><a href="#authinfo">authinfo</a></li>
|
||
<li><a href="#private-config">Private config</a></li>
|
||
<li><a href="#no-littering">No littering</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#prevent-emacs-from-closing">Prevent Emacs from closing</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#general-settings">General settings</a>
|
||
<ul>
|
||
<li><a href="#keybindings">Keybindings</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>
|
||
<li><a href="#evil">Evil</a>
|
||
<ul>
|
||
<li><a href="#evil-mode">Evil-mode</a></li>
|
||
<li><a href="#addons">Addons</a></li>
|
||
<li><a href="#my-additions">My additions</a></li>
|
||
<li><a href="#evil-collection">evil-collection</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#avy">Avy</a></li>
|
||
<li><a href="#my-keybindings">My keybindings</a>
|
||
<ul>
|
||
<li><a href="#escape-key">Escape key</a></li>
|
||
<li><a href="#home-and-end">Home & 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-ui">Zoom UI</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#i3-integration">i3 integration</a></li>
|
||
<li><a href="#editing-text">Editing text</a>
|
||
<ul>
|
||
<li><a href="#indentation-and-whitespace">Indentation & whitespace</a>
|
||
<ul>
|
||
<li><a href="#aggressive-indent">Aggressive Indent</a></li>
|
||
<li><a href="#delete-trailing-whitespace">Delete trailing whitespace</a></li>
|
||
<li><a href="#tabs">Tabs</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#settings">Settings</a>
|
||
<ul>
|
||
<li><a href="#scrolling">Scrolling</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="#snippets">Snippets</a></li>
|
||
<li><a href="#other-small-packages">Other small packages</a>
|
||
<ul>
|
||
<li><a href="#managing-parentheses--smartparens">Managing parentheses (smartparens)</a></li>
|
||
<li><a href="#expand-region">Expand region</a></li>
|
||
<li><a href="#visual-fill-column-mode">Visual fill column mode</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#working-with-projects">Working with projects</a>
|
||
<ul>
|
||
<li><a href="#projectile">Projectile</a></li>
|
||
<li><a href="#git-and-magit">Git & Magit</a></li>
|
||
<li><a href="#editorconfig">Editorconfig</a></li>
|
||
<li><a href="#editing-files">Editing files</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#completion">Completion</a>
|
||
<ul>
|
||
<li><a href="#ivy-counsel-swiper">Ivy, counsel, swiper</a></li>
|
||
<li><a href="#ivy-rich">ivy-rich</a></li>
|
||
<li><a href="#prescient">prescient</a></li>
|
||
<li><a href="#keybindings">keybindings</a></li>
|
||
<li><a href="#company">company</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#help">Help</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-settings">UI settings</a>
|
||
<ul>
|
||
<li><a href="#general-settings">General settings</a>
|
||
<ul>
|
||
<li><a href="#miscellaneous">Miscellaneous</a></li>
|
||
<li><a href="#line-numbers">Line numbers</a></li>
|
||
<li><a href="#word-wrapping">Word wrapping</a></li>
|
||
<li><a href="#custom-frame-format">Custom frame format</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#themes-and-colors">Themes and colors</a>
|
||
<ul>
|
||
<li><a href="#doom-themes">Doom themes</a></li>
|
||
<li><a href="#custom-theme">Custom theme</a></li>
|
||
<li><a href="#dim-inactive-buffers">Dim inactive buffers</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#fonts">Fonts</a>
|
||
<ul>
|
||
<li><a href="#frame-font">Frame font</a></li>
|
||
<li><a href="#ligatures">Ligatures</a></li>
|
||
<li><a href="#icons">Icons</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#text-highlight">Text highlight</a></li>
|
||
<li><a href="#doom-modeline">Doom Modeline</a></li>
|
||
<li><a href="#perspective-dot-el">perspective.el</a>
|
||
<ul>
|
||
<li><a href="#functions-to-manage-buffers">Functions to manage buffers</a></li>
|
||
<li><a href="#automating-perspectives">Automating perspectives</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#programming">Programming</a>
|
||
<ul>
|
||
<li><a href="#general-setup">General setup</a>
|
||
<ul>
|
||
<li><a href="#treemacs">Treemacs</a></li>
|
||
<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="#dap">DAP</a>
|
||
<ul>
|
||
<li><a href="#controls">Controls</a></li>
|
||
<li><a href="#ui-fixes">UI Fixes</a></li>
|
||
<li><a href="#helper-functions">Helper functions</a></li>
|
||
<li><a href="#improved-stack-frame-switching">Improved stack frame switching</a></li>
|
||
<li><a href="#smarter-switch-to-stack-frame">Smarter switch to stack frame</a></li>
|
||
<li><a href="#debug-templates">Debug templates</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="#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-and-natural-languages">Other markup & natural languages</a>
|
||
<ul>
|
||
<li><a href="#markdown">Markdown</a></li>
|
||
<li><a href="#plantuml">PlantUML</a></li>
|
||
<li><a href="#subtitles">Subtitles</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="#data-serialization">Data serialization</a>
|
||
<ul>
|
||
<li><a href="#json">JSON</a></li>
|
||
<li><a href="#csv">CSV</a></li>
|
||
<li><a href="#yaml">YAML</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#configuration">Configuration</a>
|
||
<ul>
|
||
<li><a href="#dot-env">.env</a></li>
|
||
<li><a href="#dot-gitignore">.gitignore</a></li>
|
||
<li><a href="#docker">Docker</a></li>
|
||
<li><a href="#crontab">crontab</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#shell">Shell</a>
|
||
<ul>
|
||
<li><a href="#sh">sh</a></li>
|
||
<li><a href="#fish">fish</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="#haskell">Haskell</a></li>
|
||
<li><a href="#nix">nix</a></li>
|
||
<li><a href="#lua">Lua</a></li>
|
||
<li><a href="#sql">SQL</a></li>
|
||
<li><a href="#sparql">SPARQL</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#org-mode">Org Mode</a>
|
||
<ul>
|
||
<li><a href="#installation-and-basic-settings">Installation & 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 & 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="#restclient">Restclient</a></li>
|
||
<li><a href="#setup">Setup</a></li>
|
||
<li><a href="#managing-jupyter-kernels">Managing Jupyter kernels</a></li>
|
||
<li><a href="#output-post-processing">Output post-processing</a>
|
||
<ul>
|
||
<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>
|
||
<li><a href="#apply-ansi-color-codes">Apply ANSI color codes</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#managing-a-literate-programming-project">Managing a literate programming project</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#tools">Tools</a>
|
||
<ul>
|
||
<li><a href="#presentations">Presentations</a></li>
|
||
<li><a href="#toc">TOC</a></li>
|
||
<li><a href="#screenshots">Screenshots</a></li>
|
||
<li><a href="#transclusion">Transclusion</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#productivity-and-knowledge-management">Productivity & Knowledge management</a>
|
||
<ul>
|
||
<li><a href="#capture-templates-and-various-settings">Capture templates & various settings</a></li>
|
||
<li><a href="#off--trello-sync"><span class="org-todo done OFF">OFF</span> (OFF) Trello sync</a></li>
|
||
<li><a href="#org-ql">org-ql</a></li>
|
||
<li><a href="#custom-agendas">Custom agendas</a></li>
|
||
<li><a href="#org-journal">Org Journal</a></li>
|
||
<li><a href="#org-roam">Org Roam</a>
|
||
<ul>
|
||
<li><a href="#basic-package-configuration">Basic package configuration</a></li>
|
||
<li><a href="#capture-templates">Capture templates</a></li>
|
||
<li><a href="#keybindings">Keybindings</a></li>
|
||
<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="#review-workflow">Review workflow</a>
|
||
<ul>
|
||
<li><a href="#data-from-git">Data from git</a></li>
|
||
<li><a href="#data-from-org-roam">Data from org-roam</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-ref">org-ref</a></li>
|
||
<li><a href="#org-roam-bibtex">org-roam-bibtex</a></li>
|
||
<li><a href="#org-contacts">org-contacts</a></li>
|
||
<li><a href="#managing-tables">Managing tables</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="#override-colors">Override colors</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 & stuff</a>
|
||
<ul>
|
||
<li><a href="#general-keybindings">General keybindings</a></li>
|
||
<li><a href="#copy-a-link">Copy a link</a></li>
|
||
<li><a href="#open-a-file-from-org-directory">Open a file from <code>org-directory</code></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="#applications">Applications</a>
|
||
<ul>
|
||
<li><a href="#dired">Dired</a>
|
||
<ul>
|
||
<li><a href="#basic-config-and-keybindings">Basic config & 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="#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 & 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="#custom-faces">Custom faces</a></li>
|
||
<li><a href="#elfeed-summary">elfeed-summary</a></li>
|
||
<li><a href="#elfeed-score">elfeed-score</a></li>
|
||
<li><a href="#youtube-podcasts-and-emms">YouTube, podcasts & 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 & mpd Fixes</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#ytel">ytel</a></li>
|
||
<li><a href="#eww">EWW</a></li>
|
||
<li><a href="#erc">ERC</a></li>
|
||
<li><a href="#off--jabber"><span class="org-todo done OFF">OFF</span> (OFF) jabber</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 & 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="#pomm">pomm</a></li>
|
||
<li><a href="#hledger">hledger</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="#power-mode">Power mode</a></li>
|
||
<li><a href="#redacted">Redacted</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="some-remarks">Some remarks</h2>
|
||
<p>I decided not to keep configs for features that I do not use anymore because this config is already huge. But here are the last commits that had these features presented.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Feature</th>
|
||
<th>Last commit</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>org-roam dailies</td>
|
||
<td>d2648918fcc338bd5c1cd6d5c0aa60a65077ccf7</td>
|
||
</tr>
|
||
<tr>
|
||
<td>org-roam projects</td>
|
||
<td>025278a1e180e86f3aade20242e4ac1cdc1a2f13</td>
|
||
</tr>
|
||
<tr>
|
||
<td>treemacs</td>
|
||
<td>3d87852745caacc0863c747f1fa9871d367240d2</td>
|
||
</tr>
|
||
<tr>
|
||
<td>tab-bar.el</td>
|
||
<td>19ff54db9fe21fd5bdf404a8d2612176baa8a6f5</td>
|
||
</tr>
|
||
<tr>
|
||
<td>spaceline</td>
|
||
<td>19ff54db9fe21fd5bdf404a8d2612176baa8a6f5</td>
|
||
</tr>
|
||
<tr>
|
||
<td>code compass</td>
|
||
<td>8594d6f53e42c70bbf903e168607841854818a38</td>
|
||
</tr>
|
||
<tr>
|
||
<td>vue-mode</td>
|
||
<td>8594d6f53e42c70bbf903e168607841854818a38</td>
|
||
</tr>
|
||
<tr>
|
||
<td>svelte-mode</td>
|
||
<td>8594d6f53e42c70bbf903e168607841854818a38</td>
|
||
</tr>
|
||
<tr>
|
||
<td>pomidor</td>
|
||
<td>8594d6f53e42c70bbf903e168607841854818a38</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h2 id="bootstrap">Bootstrap</h2>
|
||
<p>Setting up the environment, performance tuning and a few basic settings.</p>
|
||
<h3 id="packages">Packages</h3>
|
||
<h4 id="straight-dot-el">straight.el</h4>
|
||
<p>Straight.el is my Emacs package manager of choice. Its advantages & 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"><span style="display:flex;"><span>(defvar bootstrap-version)
|
||
</span></span><span style="display:flex;"><span>(let ((bootstrap-file
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"straight/repos/straight.el/bootstrap.el"</span> user-emacs-directory))
|
||
</span></span><span style="display:flex;"><span> (bootstrap-version <span style="color:#ae81ff">5</span>))
|
||
</span></span><span style="display:flex;"><span> (unless (<span style="color:#a6e22e">file-exists-p</span> bootstrap-file)
|
||
</span></span><span style="display:flex;"><span> (with-current-buffer
|
||
</span></span><span style="display:flex;"><span> (url-retrieve-synchronously
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'silent</span> <span style="color:#e6db74">'inhibit-cookies</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">goto-char</span> (<span style="color:#a6e22e">point-max</span>))
|
||
</span></span><span style="display:flex;"><span> (eval-print-last-sexp)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">load</span> bootstrap-file <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">'nomessage</span>))
|
||
</span></span></code></pre></div><h4 id="use-package">use-package</h4>
|
||
<p>A macro to simplify package specification & 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"><span style="display:flex;"><span>(straight-use-package <span style="color:#e6db74">'use-package</span>)
|
||
</span></span><span style="display:flex;"><span>(eval-when-compile (require <span style="color:#e6db74">'use-package</span>))
|
||
</span></span></code></pre></div><h3 id="variables-and-environment">Variables & environment</h3>
|
||
<p>This section is about optioning the Emacs config.</p>
|
||
<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"><span style="display:flex;"><span>(setq my/lowpower (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"azure"</span>))
|
||
</span></span></code></pre></div><p>The following is true if Emacs is meant to be used with TRAMP over slow ssh. Take a look at the <a href="#tramp">TRAMP</a> section for more details.</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="display:flex;"><span>(setq my/slow-ssh
|
||
</span></span><span style="display:flex;"><span> (or
|
||
</span></span><span style="display:flex;"><span> (string= (getenv <span style="color:#e6db74">"IS_TRAMP"</span>) <span style="color:#e6db74">"true"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"dev-digital"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"violet"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"viridian"</span>)))
|
||
</span></span></code></pre></div><p>The following is true is Emacs is run on a remote server where I don’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"><span style="display:flex;"><span>(setq my/remote-server
|
||
</span></span><span style="display:flex;"><span> (or (string= (getenv <span style="color:#e6db74">"IS_REMOTE"</span>) <span style="color:#e6db74">"true"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"dev-digital"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"violet"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"viridian"</span>)))
|
||
</span></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"><span style="display:flex;"><span>(setq my/is-termux (string-match-p (rx (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">"com.termux"</span> (<span style="color:#a6e22e">*</span> nonl)) (getenv <span style="color:#e6db74">"HOME"</span>)))
|
||
</span></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"><span style="display:flex;"><span>(setenv <span style="color:#e6db74">"IS_EMACS"</span> <span style="color:#e6db74">"true"</span>)
|
||
</span></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"><span style="display:flex;"><span><<minimal>>
|
||
</span></span></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"><span style="display:flex;"><span>emacs -q -l ~/.emacs.d/init-minimal.el
|
||
</span></span></code></pre></div><h3 id="performance">Performance</h3>
|
||
<h4 id="measure-startup-speed">Measure startup speed</h4>
|
||
<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"><span style="display:flex;"><span>(setq my/emacs-started <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'emacs-startup-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"*** Emacs loaded in %s with %d garbage collections."</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%.2f seconds"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">float-time</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">time-subtract</span> after-init-time before-init-time)))
|
||
</span></span><span style="display:flex;"><span> gcs-done))
|
||
</span></span><span style="display:flex;"><span> (setq my/emacs-started <span style="color:#66d9ef">t</span>))
|
||
</span></span></code></pre></div><p>Set the following to <code>t</code> to print debug information during the startup. This will include the order in which the packages are loaded and the loading time of individual 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"><span style="display:flex;"><span><span style="color:#75715e">;; (setq use-package-verbose t)</span>
|
||
</span></span></code></pre></div><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"><span style="display:flex;"><span>(setq gc-cons-threshold <span style="color:#ae81ff">80000000</span>)
|
||
</span></span><span style="display:flex;"><span>(setq read-process-output-max (<span style="color:#a6e22e">*</span> <span style="color:#ae81ff">1024</span> <span style="color:#ae81ff">1024</span>))
|
||
</span></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’s a good idea.</del></p>
|
||
<p>Some time has passed, and I still don’t know if there is any quantifiable advantage to this, but it doesn’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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'emacs-startup-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'after-focus-change-function</span>)
|
||
</span></span><span style="display:flex;"><span> (add-function :after after-focus-change-function
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (unless (frame-focus-state)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">garbage-collect</span>))))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'after-focus-change-function</span> <span style="color:#e6db74">'garbage-collect</span>))))
|
||
</span></span></code></pre></div><h4 id="native-compilation">Native compilation</h4>
|
||
<p>Set the number of native compilation 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"><span style="display:flex;"><span>(when my/lowpower
|
||
</span></span><span style="display:flex;"><span> (setq comp-async-jobs-number <span style="color:#ae81ff">1</span>))
|
||
</span></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. Take a look at <a href="/configs/guix/#conda">the corresponding entry</a> in the Guix config for details about using it on Guix.</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 auxiliary environment variable. This variable is used in the <a href="/configs/console/#anaconda">shell config</a>.</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"><span style="display:flex;"><span>(use-package conda
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (executable-find <span style="color:#e6db74">"conda"</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq conda-anaconda-home (string-replace <span style="color:#e6db74">"/bin/conda"</span> <span style="color:#e6db74">""</span> (executable-find <span style="color:#e6db74">"conda"</span>)))
|
||
</span></span><span style="display:flex;"><span> (setq conda-env-home-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/.conda/"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq conda-env-subdirectory <span style="color:#e6db74">"envs"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'conda-env-activate</span> :after
|
||
</span></span><span style="display:flex;"><span> (lambda (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (setenv <span style="color:#e6db74">"EMACS_CONDA_ENV"</span> conda-env-current-name)
|
||
</span></span><span style="display:flex;"><span> (setenv <span style="color:#e6db74">"INIT_CONDA"</span> <span style="color:#e6db74">"true"</span>)))
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'conda-env-deactivate</span> :after
|
||
</span></span><span style="display:flex;"><span> (lambda (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (setenv <span style="color:#e6db74">"EMACS_CONDA_ENV"</span> <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setenv <span style="color:#e6db74">"INIT_CONDA"</span> <span style="color:#66d9ef">nil</span>)))
|
||
</span></span><span style="display:flex;"><span> (unless (getenv <span style="color:#e6db74">"CONDA_DEFAULT_ENV"</span>)
|
||
</span></span><span style="display:flex;"><span> (conda-env-activate <span style="color:#e6db74">"general"</span>)))
|
||
</span></span></code></pre></div><h3 id="config-files">Config files</h3>
|
||
<h4 id="custom-file-location">Custom file location</h4>
|
||
<p>By default, custom writes stuff to <code>init.el</code>, which is somewhat annoying. The following makes it write to 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"><span style="display:flex;"><span>(setq custom-file (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"custom.el"</span>))
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">load</span> custom-file <span style="color:#e6db74">'noerror</span>)
|
||
</span></span></code></pre></div><h4 id="authinfo">authinfo</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="display:flex;"><span>(setq auth-source-debug <span style="color:#66d9ef">nil</span>)
|
||
</span></span></code></pre></div><h4 id="private-config">Private config</h4>
|
||
<p>I have some variables which I don’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"><span style="display:flex;"><span>(let ((private-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"private.el"</span> user-emacs-directory)))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">file-exists-p</span> private-file)
|
||
</span></span><span style="display:flex;"><span> (load-file private-file)))
|
||
</span></span></code></pre></div><h4 id="no-littering">No littering</h4>
|
||
<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 that 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"><span style="display:flex;"><span>(use-package no-littering
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq confirm-kill-emacs <span style="color:#e6db74">'y-or-n-p</span>)
|
||
</span></span></code></pre></div><h2 id="general-settings">General settings</h2>
|
||
<h3 id="keybindings">Keybindings</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"><span style="display:flex;"><span>(use-package general
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (general-evil-setup))
|
||
</span></span></code></pre></div><h4 id="which-key">which-key</h4>
|
||
<p>A package that displays the available keybindings in a popup. The package is 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"><span style="display:flex;"><span>(use-package which-key
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq which-key-idle-delay (if my/lowpower <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">0.3</span>))
|
||
</span></span><span style="display:flex;"><span> (setq which-key-popup-type <span style="color:#e6db74">'frame</span>)
|
||
</span></span><span style="display:flex;"><span> (which-key-mode)
|
||
</span></span><span style="display:flex;"><span> (which-key-setup-side-window-bottom)
|
||
</span></span><span style="display:flex;"><span> (set-face-attribute <span style="color:#e6db74">'which-key-local-map-description-face</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :weight <span style="color:#e6db74">'bold</span>)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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 a 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"><span style="display:flex;"><span>(defun my/dump-bindings-recursive (prefix <span style="color:#66d9ef">&optional</span> level)
|
||
</span></span><span style="display:flex;"><span> (dolist (key (which-key--get-bindings (kbd prefix)))
|
||
</span></span><span style="display:flex;"><span> (when level
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">make-string</span> level <span style="color:#e6db74">? </span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'format</span> <span style="color:#e6db74">"%s%s%s\n"</span> key))
|
||
</span></span><span style="display:flex;"><span> (when (string-match-p
|
||
</span></span><span style="display:flex;"><span> (rx bos <span style="color:#e6db74">"+"</span> (<span style="color:#a6e22e">*</span> nonl))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">elt</span> key <span style="color:#ae81ff">2</span>)))
|
||
</span></span><span style="display:flex;"><span> (my/dump-bindings-recursive
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> prefix <span style="color:#e6db74">" "</span> (<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">car</span> key)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">+</span> <span style="color:#ae81ff">2</span> (or level <span style="color:#ae81ff">0</span>))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/dump-bindings (prefix)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Dump keybindings starting with PREFIX in a tree-like form."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive <span style="color:#e6db74">"sPrefix: "</span>)
|
||
</span></span><span style="display:flex;"><span> (with-current-buffer (<span style="color:#a6e22e">get-buffer-create</span> <span style="color:#e6db74">"bindings"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">point-max</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">erase-buffer</span>)
|
||
</span></span><span style="display:flex;"><span> (save-excursion
|
||
</span></span><span style="display:flex;"><span> (my/dump-bindings-recursive prefix)))
|
||
</span></span><span style="display:flex;"><span> (switch-to-buffer-other-window <span style="color:#e6db74">"bindings"</span>))
|
||
</span></span></code></pre></div><h4 id="evil">Evil</h4>
|
||
<p>An entire 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 “evil”.</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>
|
||
<h5 id="evil-mode">Evil-mode</h5>
|
||
<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"><span style="display:flex;"><span>(use-package evil
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq evil-want-integration <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq evil-want-C-u-scroll <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq evil-want-keybinding <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq evil-search-module <span style="color:#e6db74">'evil-search</span>)
|
||
</span></span><span style="display:flex;"><span> (setq evil-split-window-below <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq evil-vsplit-window-right <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (unless (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> (setq evil-want-C-i-jump <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (evil-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq evil-respect-visual-line-mode t)</span>
|
||
</span></span><span style="display:flex;"><span> (evil-set-undo-system <span style="color:#e6db74">'undo-tree</span>))
|
||
</span></span></code></pre></div><h5 id="addons">Addons</h5>
|
||
<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"><span style="display:flex;"><span>(use-package evil-surround
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after evil
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-evil-surround-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span></code></pre></div><p><a href="https://github.com/linktohack/evil-commentary">evil-commentary</a> emulates commentary.vim. It provides actions for quick insertion and deletion of 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"><span style="display:flex;"><span>(use-package evil-commentary
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after evil
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (evil-commentary-mode))
|
||
</span></span></code></pre></div><p><a href="https://github.com/blorbx/evil-quickscope">evil-quickscope</a> emulates quickscope.vim. It highlights certain 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"><span style="display:flex;"><span>(use-package evil-quickscope
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after evil
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> :hook ((prog-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
|
||
</span></span><span style="display:flex;"><span> (LaTeX-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
|
||
</span></span><span style="display:flex;"><span> (org-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)))
|
||
</span></span></code></pre></div><p><a href="https://github.com/cofi/evil-numbers">evil-numbers</a> allows incrementing and decrementing numbers at 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"><span style="display:flex;"><span>(use-package evil-numbers
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (evil-numbers/inc-at-pt evil-numbers/dec-at-pt)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (general-nmap
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"g+"</span> <span style="color:#e6db74">'evil-numbers/inc-at-pt</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"g-"</span> <span style="color:#e6db74">'evil-numbers/dec-at-pt</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package evil-lion
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq evil-lion-left-align-key (kbd <span style="color:#e6db74">"g a"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq evil-lion-right-align-key (kbd <span style="color:#e6db74">"g A"</span>))
|
||
</span></span><span style="display:flex;"><span> (evil-lion-mode))
|
||
</span></span></code></pre></div><p><a href="https://github.com/redguardtoo/evil-matchit">evil-matchit</a> makes “%” to match things like tags. It doesn’t work perfectly, so I <del>occasionally</del> turn it off.</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="display:flex;"><span>(use-package evil-matchit
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-evil-matchit-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span></code></pre></div><h5 id="my-additions">My additions</h5>
|
||
<p>Do ex search in other buffer. Like <code>*</code>, but switch to other buffer and search there.</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="display:flex;"><span>(defun my/evil-ex-search-word-forward-other-window (count <span style="color:#66d9ef">&optional</span> symbol)
|
||
</span></span><span style="display:flex;"><span> (interactive (<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">prefix-numeric-value</span> current-prefix-arg)
|
||
</span></span><span style="display:flex;"><span> evil-symbol-word-search))
|
||
</span></span><span style="display:flex;"><span> (save-excursion
|
||
</span></span><span style="display:flex;"><span> (evil-ex-start-word-search <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">'forward</span> count symbol))
|
||
</span></span><span style="display:flex;"><span> (other-window <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (evil-ex-search-next))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"&"</span> <span style="color:#a6e22e">#'</span>my/evil-ex-search-word-forward-other-window)
|
||
</span></span></code></pre></div><h5 id="evil-collection">evil-collection</h5>
|
||
<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 complete list in the <a href="https://github.com/emacs-evil/evil-collection/tree/master/modes">modes</a> folder.</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="display:flex;"><span>(use-package evil-collection
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after evil
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (evil-collection-init
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(eww
|
||
</span></span><span style="display:flex;"><span> devdocs
|
||
</span></span><span style="display:flex;"><span> proced
|
||
</span></span><span style="display:flex;"><span> emms
|
||
</span></span><span style="display:flex;"><span> pass
|
||
</span></span><span style="display:flex;"><span> calendar
|
||
</span></span><span style="display:flex;"><span> dired
|
||
</span></span><span style="display:flex;"><span> ivy
|
||
</span></span><span style="display:flex;"><span> debug
|
||
</span></span><span style="display:flex;"><span> guix
|
||
</span></span><span style="display:flex;"><span> calc
|
||
</span></span><span style="display:flex;"><span> docker
|
||
</span></span><span style="display:flex;"><span> ibuffer
|
||
</span></span><span style="display:flex;"><span> geiser
|
||
</span></span><span style="display:flex;"><span> pdf
|
||
</span></span><span style="display:flex;"><span> info
|
||
</span></span><span style="display:flex;"><span> elfeed
|
||
</span></span><span style="display:flex;"><span> edebug
|
||
</span></span><span style="display:flex;"><span> bookmark
|
||
</span></span><span style="display:flex;"><span> company
|
||
</span></span><span style="display:flex;"><span> vterm
|
||
</span></span><span style="display:flex;"><span> flycheck
|
||
</span></span><span style="display:flex;"><span> profiler
|
||
</span></span><span style="display:flex;"><span> cider
|
||
</span></span><span style="display:flex;"><span> explain-pause-mode
|
||
</span></span><span style="display:flex;"><span> notmuch
|
||
</span></span><span style="display:flex;"><span> custom
|
||
</span></span><span style="display:flex;"><span> xref
|
||
</span></span><span style="display:flex;"><span> eshell
|
||
</span></span><span style="display:flex;"><span> helpful
|
||
</span></span><span style="display:flex;"><span> compile
|
||
</span></span><span style="display:flex;"><span> comint
|
||
</span></span><span style="display:flex;"><span> git-timemachine
|
||
</span></span><span style="display:flex;"><span> magit
|
||
</span></span><span style="display:flex;"><span> prodigy
|
||
</span></span><span style="display:flex;"><span> slime
|
||
</span></span><span style="display:flex;"><span> forge)))
|
||
</span></span></code></pre></div><h4 id="avy">Avy</h4>
|
||
<p><a href="https://github.com/abo-abo/avy">Avy</a> is a package that helps navigate Emacs in a tree-like manner.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://karthinks.com/software/avy-can-do-anything/">Avy can do anything</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"><span style="display:flex;"><span>(use-package avy
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq avy-timeout-seconds <span style="color:#ae81ff">0.5</span>)
|
||
</span></span><span style="display:flex;"><span> (setq avy-ignored-modes
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(image-mode doc-view-mode pdf-view-mode exwm-mode))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal motion)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"-"</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"--"</span> <span style="color:#a6e22e">#'</span>avy-goto-char-2
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"-="</span> <span style="color:#a6e22e">#'</span>avy-goto-symbol-1))
|
||
</span></span></code></pre></div><h4 id="my-keybindings">My keybindings</h4>
|
||
<p>Various keybindings settings that I can’t put anywhere else.</p>
|
||
<h5 id="escape-key">Escape key</h5>
|
||
<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"><span style="display:flex;"><span>(defun minibuffer-keyboard-quit ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Abort recursive edit.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">In Delete Selection mode, if the mark is active, just deactivate it;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">then it takes a second \\[keyboard-quit] to abort the minibuffer."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (if (and delete-selection-mode transient-mark-mode mark-active)
|
||
</span></span><span style="display:flex;"><span> (setq deactivate-mark <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">get-buffer</span> <span style="color:#e6db74">"*Completions*"</span>) (delete-windows-on <span style="color:#e6db74">"*Completions*"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">abort-recursive-edit</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/escape-key ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (evil-ex-nohighlight)
|
||
</span></span><span style="display:flex;"><span> (keyboard-quit))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(normal visual global)
|
||
</span></span><span style="display:flex;"><span> [escape] <span style="color:#a6e22e">#'</span>my/escape-key)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(minibuffer-local-map
|
||
</span></span><span style="display:flex;"><span> minibuffer-local-ns-map
|
||
</span></span><span style="display:flex;"><span> minibuffer-local-completion-map
|
||
</span></span><span style="display:flex;"><span> minibuffer-local-must-match-map
|
||
</span></span><span style="display:flex;"><span> minibuffer-local-isearch-map)
|
||
</span></span><span style="display:flex;"><span> [escape] <span style="color:#e6db74">'minibuffer-keyboard-quit</span>)
|
||
</span></span></code></pre></div><h5 id="home-and-end">Home & end</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"><span style="display:flex;"><span>(general-def :states <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span> visual)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<home>"</span> <span style="color:#e6db74">'beginning-of-line</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<end>"</span> <span style="color:#e6db74">'end-of-line</span>)
|
||
</span></span></code></pre></div><h5 id="my-leader">My leader</h5>
|
||
<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"><span style="display:flex;"><span>(general-create-definer my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'override</span>
|
||
</span></span><span style="display:flex;"><span> :prefix <span style="color:#e6db74">"SPC"</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal motion emacs))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-def :states <span style="color:#f92672">'</span>(normal motion emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"SPC"</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-SPC"</span> (general-key <span style="color:#e6db74">"SPC"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-def :states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-SPC"</span> (general-key <span style="color:#e6db74">"SPC"</span> :state <span style="color:#e6db74">'normal</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"?"</span> <span style="color:#e6db74">'which-key-show-top-level</span>)
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"E"</span> <span style="color:#e6db74">'eval-expression</span>)
|
||
</span></span></code></pre></div><p><code>general.el</code> has a nice integration with which-key, so I use that to show more descriptive annotations for certain groups of keybindings (the default annotation is just <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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"a"</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"apps"</span>))
|
||
</span></span></code></pre></div><h5 id="universal-argument">Universal argument</h5>
|
||
<p>Change the universal argument to <code>M-u</code>. I use <code>C-u</code> to scroll up, as I’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"><span style="display:flex;"><span>(general-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'universal-argument-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-u"</span> <span style="color:#e6db74">'universal-argument-more</span>)
|
||
</span></span><span style="display:flex;"><span>(general-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'override</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal motion emacs <span style="color:#a6e22e">insert</span> visual)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-u"</span> <span style="color:#e6db74">'universal-argument</span>)
|
||
</span></span></code></pre></div><h5 id="profiler">Profiler</h5>
|
||
<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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"P"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"profiler"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'profiler-start</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'profiler-stop</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'profiler-report</span>)
|
||
</span></span></code></pre></div><h5 id="buffer-switching">Buffer switching</h5>
|
||
<p>Some keybindings I used in vim to switch buffers and can’t let go of. But I think I started to use these less since I made an attempt in <a href="#i3-integration">i3 integration</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="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'override</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<right>"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<left>"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<up>"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<down>"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-x h"</span> <span style="color:#e6db74">'previous-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-x l"</span> <span style="color:#e6db74">'next-buffer</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'evil-window-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"x"</span> <span style="color:#e6db74">'kill-buffer-and-window</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'kill-current-buffer</span>)
|
||
</span></span></code></pre></div><p><code>winner-mode</code> to keep the history of window states.</p>
|
||
<p>It doesn’t play too well with perspective.el, that is it has a single history list for all of the perspectives. But it is still quite usable.</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="display:flex;"><span>(winner-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'evil-window-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'winner-undo</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"U"</span> <span style="color:#e6db74">'winner-redo</span>)
|
||
</span></span></code></pre></div><h5 id="buffer-management">Buffer management</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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"b"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"buffers"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#f92672">'</span>((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||
</span></span><span style="display:flex;"><span> :which-key <span style="color:#e6db74">"*scratch*"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"m"</span> <span style="color:#f92672">'</span>((lambda () (interactive) (persp-switch-to-buffer <span style="color:#e6db74">"*Messages*"</span>))
|
||
</span></span><span style="display:flex;"><span> :which-key <span style="color:#e6db74">"*Messages*"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'next-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'previous-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"k"</span> <span style="color:#e6db74">'kill-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'revert-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'ibuffer</span>)
|
||
</span></span></code></pre></div><h5 id="xref">xref</h5>
|
||
<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"><span style="display:flex;"><span>(general-nmap
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gD"</span> <span style="color:#e6db74">'xref-find-definitions-other-window</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gr"</span> <span style="color:#e6db74">'xref-find-references</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gd"</span> <span style="color:#e6db74">'evil-goto-definition</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"fx"</span> <span style="color:#e6db74">'xref-find-apropos</span>)
|
||
</span></span></code></pre></div><h5 id="folding">Folding</h5>
|
||
<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’t use it at the moment.</p>
|
||
<p>Evil does a pretty good job of abstracting the first two with a set of vim-like keybindings. I was using <code>SPC</code> in vim, but as now this isn’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"><span style="display:flex;"><span>(general-nmap :keymaps <span style="color:#f92672">'</span>(hs-minor-mode-map outline-minor-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ze"</span> <span style="color:#e6db74">'hs-hide-level</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"TAB"</span> <span style="color:#e6db74">'evil-toggle-fold</span>)
|
||
</span></span></code></pre></div><h5 id="zoom-ui">Zoom UI</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"><span style="display:flex;"><span>(defun my/zoom-in ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Increase font size by 10 points"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (set-face-attribute <span style="color:#e6db74">'default</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :height
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">+</span> (face-attribute <span style="color:#e6db74">'default</span> :height) <span style="color:#ae81ff">10</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/zoom-out ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Decrease font size by 10 points"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (set-face-attribute <span style="color:#e6db74">'default</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :height
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">-</span> (face-attribute <span style="color:#e6db74">'default</span> :height) <span style="color:#ae81ff">10</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; change font size, interactively</span>
|
||
</span></span><span style="display:flex;"><span>(global-set-key (kbd <span style="color:#e6db74">"C-+"</span>) <span style="color:#e6db74">'my/zoom-in</span>)
|
||
</span></span><span style="display:flex;"><span>(global-set-key (kbd <span style="color:#e6db74">"C-="</span>) <span style="color:#e6db74">'my/zoom-out</span>)
|
||
</span></span></code></pre></div><h3 id="i3-integration">i3 integration</h3>
|
||
<p>UPD <span class="timestamp-wrapper"><span class="timestamp"><2021-11-27 Sat></span></span>. I have finally switched to EXWM as my window manager, but as long as I keep i3 as a backup solution, this section persists. Check out the <a href="https://sqrtminusone.xyz/posts/2021-10-04-emacs-i3/">post</a> for a somewhat better presentation.</p>
|
||
<p>One advantage of EXWM for an Emacs user is that EXWM gives one set of keybindings to manage both Emacs windows and X windows. In every other WM, like my preferred <a href="https://i3wm.org">i3wm</a>, two orthogonal keymaps seem to be necessary. But, as both programs are quite customizable, I want to see whether I can replicate at least some part of the EXWM goodness in i3.</p>
|
||
<p>But why not just use EXWM? One key reason is that to my taste (and perhaps on my hardware) EXWM didn’t feel snappy enough. Also, I really like i3’s tree-based layout structure; I feel like it fits my workflow much better than anything else I tried, including the master/stack paradigm of <a href="https://xmonad.org/">XMonad</a>, for instance.</p>
|
||
<p>One common point of criticism of i3 is that it is not extensible enough, especially compared to WMs that are configured in an actual programing language, like the mentioned XMonad, <a href="http://www.qtile.org/">Qtile</a>, <a href="https://awesomewm.org/">Awesome</a>, etc. But I think i3’s extensibility is underappreciated, although the contents of this section may lie closer to the limits of how far one can go there.</p>
|
||
<p>The basic idea is to launch a normal i3 command with <code>i3-msg</code> in case the current window is not Emacs, otherwise pass that command to Emacs with <code>emacsclient</code>. In Emacs, execute the command if possible, otherwise pass the command back to i3.</p>
|
||
<p>This may seem like a lot of overhead, but I didn’t feel it even in the worst case (i3 -> Emacs -> i3), so at least in that regard, the interaction feels seamless. The only concern is that this command flow is vulnerable to Emacs getting stuck, but it is still much less of a problem than with EXWM.</p>
|
||
<p>One interesting observation here is that Emacs windows and X windows are sort of one-level entities, so I can talk just about “windows”.</p>
|
||
<p>At any rate, we need a script to do the i3 -> Emacs part:</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"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[[</span> <span style="color:#66d9ef">$(</span>xdotool getactivewindow getwindowname<span style="color:#66d9ef">)</span> <span style="color:#f92672">=</span>~ ^emacs<span style="color:#f92672">(</span>:.*<span style="color:#f92672">)</span>?@.* <span style="color:#f92672">]]</span>; <span style="color:#66d9ef">then</span>
|
||
</span></span><span style="display:flex;"><span> command<span style="color:#f92672">=</span><span style="color:#e6db74">"(my/emacs-i3-integration \"</span>$@<span style="color:#e6db74">\")"</span>
|
||
</span></span><span style="display:flex;"><span> emacsclient -e <span style="color:#e6db74">"</span>$command<span style="color:#e6db74">"</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
|
||
</span></span><span style="display:flex;"><span> i3-msg $@
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
|
||
</span></span></code></pre></div><p>This script is being run from the <a href="/configs/desktop/#i3wm">i3 configuration</a>.</p>
|
||
<p>For this to work, we need to make sure that Emacs starts a server, so here is an expression to do just 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"><span style="display:flex;"><span>(unless my/remote-server
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'after-init-hook</span> <span style="color:#a6e22e">#'</span>server-start))
|
||
</span></span></code></pre></div><p>And here is a simple macro to do the Emacs -> i3 part:</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="display:flex;"><span>(defmacro i3-msg (<span style="color:#66d9ef">&rest</span> args)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#a6e22e">start-process</span> <span style="color:#e6db74">"emacs-i3-windmove"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"i3-msg"</span> <span style="color:#f92672">,@</span>args))
|
||
</span></span></code></pre></div><p>Now we have to handle the required set of i3 commands. It is worth noting here that I’m not trying to implement a general mechanism to apply i3 commands to Emacs, rather I’m implementing a small subset that I use in my i3 configuration and that maps reasonably to the Emacs concepts.</p>
|
||
<p>Also, I use <a href="https://github.com/emacs-evil/evil">evil-mode</a> and generally configure the software to have vim-style bindings where possible. So if you don’t use evil-mode you’d have to detangle the given functions from evil, but then, I guess, you do not use super+hjkl to manage windows either.</p>
|
||
<p>First, for the <code>focus</code> command I want to move to an Emacs window in the given direction if there is one, otherwise move to an X window in the same direction. Fortunately, i3 and windmove have the same names for directions, so the function is rather straightforward.</p>
|
||
<p>One caveat here is that the minibuffer is always the bottom-most Emacs window, so it is necessary to check for that 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"><span style="display:flex;"><span>(defun my/emacs-i3-windmove (dir)
|
||
</span></span><span style="display:flex;"><span> (let ((other-window (windmove-find-other-window dir)))
|
||
</span></span><span style="display:flex;"><span> (if (or (<span style="color:#a6e22e">null</span> other-window) (<span style="color:#a6e22e">window-minibuffer-p</span> other-window))
|
||
</span></span><span style="display:flex;"><span> (i3-msg <span style="color:#e6db74">"focus"</span> (<span style="color:#a6e22e">symbol-name</span> dir))
|
||
</span></span><span style="display:flex;"><span> (windmove-do-window-select dir))))
|
||
</span></span></code></pre></div><p>For the <code>move</code> I want the following behavior:</p>
|
||
<ul>
|
||
<li>if there is space in the required direction, move the Emacs window there;</li>
|
||
<li>if there is no space in the required direction, but space in two orthogonal directions, move the Emacs window so that there is no more space in the orthogonal directions;</li>
|
||
<li>otherwise, move an X window (Emacs frame).</li>
|
||
</ul>
|
||
<p>For the first part, <code>window-swap-states</code> with <code>windmove-find-other-window</code> do well enough.</p>
|
||
<p><code>evil-move-window</code> works well for the second part. By itself it doesn’t behave quite like i3, for instance, <code>(evil-move-window 'right)</code> in a three-column split would move the window from the far left side to the far right side (bypassing center). Hence the combination as described here.</p>
|
||
<p>So here is a simple predicate which checks whether there is space in the given direction.</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="display:flex;"><span>(defun my/emacs-i3-direction-exists-p (dir)
|
||
</span></span><span style="display:flex;"><span> (cl-some (lambda (dir)
|
||
</span></span><span style="display:flex;"><span> (let ((win (windmove-find-other-window dir)))
|
||
</span></span><span style="display:flex;"><span> (and win (not (<span style="color:#a6e22e">window-minibuffer-p</span> win)))))
|
||
</span></span><span style="display:flex;"><span> (pcase dir
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'width</span> <span style="color:#f92672">'</span>(left right))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'height</span> <span style="color:#f92672">'</span>(up down)))))
|
||
</span></span></code></pre></div><p>And the implementation of the move command.</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="display:flex;"><span>(defun my/emacs-i3-move-window (dir)
|
||
</span></span><span style="display:flex;"><span> (let ((other-window (windmove-find-other-window dir))
|
||
</span></span><span style="display:flex;"><span> (other-direction (my/emacs-i3-direction-exists-p
|
||
</span></span><span style="display:flex;"><span> (pcase dir
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'up</span> <span style="color:#e6db74">'width</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'down</span> <span style="color:#e6db74">'width</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'left</span> <span style="color:#e6db74">'height</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'right</span> <span style="color:#e6db74">'height</span>)))))
|
||
</span></span><span style="display:flex;"><span> (cond
|
||
</span></span><span style="display:flex;"><span> ((and other-window (not (<span style="color:#a6e22e">window-minibuffer-p</span> other-window)))
|
||
</span></span><span style="display:flex;"><span> (window-swap-states (<span style="color:#a6e22e">selected-window</span>) other-window))
|
||
</span></span><span style="display:flex;"><span> (other-direction
|
||
</span></span><span style="display:flex;"><span> (evil-move-window dir))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> (i3-msg <span style="color:#e6db74">"move"</span> (<span style="color:#a6e22e">symbol-name</span> dir))))))
|
||
</span></span></code></pre></div><p>Next on the line are <code>resize grow</code> and <code>resize shrink</code>. <code>evil-window-</code> functions do nicely for this task.</p>
|
||
<p>This function also checks whether there is space to resize in the given direction with the help of the predicate defined above. The command is forwarded back to i3 if there is not.</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="display:flex;"><span>(defun my/emacs-i3-resize-window (dir kind value)
|
||
</span></span><span style="display:flex;"><span> (if (or (one-window-p)
|
||
</span></span><span style="display:flex;"><span> (not (my/emacs-i3-direction-exists-p dir)))
|
||
</span></span><span style="display:flex;"><span> (i3-msg <span style="color:#e6db74">"resize"</span> (<span style="color:#a6e22e">symbol-name</span> kind) (<span style="color:#a6e22e">symbol-name</span> dir)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s px or %s ppt"</span> value value))
|
||
</span></span><span style="display:flex;"><span> (setq value (<span style="color:#a6e22e">/</span> value <span style="color:#ae81ff">2</span>))
|
||
</span></span><span style="display:flex;"><span> (pcase kind
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'shrink</span>
|
||
</span></span><span style="display:flex;"><span> (pcase dir
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'width</span>
|
||
</span></span><span style="display:flex;"><span> (evil-window-decrease-width value))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'height</span>
|
||
</span></span><span style="display:flex;"><span> (evil-window-decrease-height value))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'grow</span>
|
||
</span></span><span style="display:flex;"><span> (pcase dir
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'width</span>
|
||
</span></span><span style="display:flex;"><span> (evil-window-increase-width value))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">'height</span>
|
||
</span></span><span style="display:flex;"><span> (evil-window-increase-height value)))))))
|
||
</span></span></code></pre></div><p><a href="https://github.com/emacsorphanage/transpose-frame">transpose-frame</a> is a package to “transpose” the current frame layout, which behaves someone similar to the <code>layout toggle split</code> command in i3, so I’ll use it 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"><span style="display:flex;"><span>(use-package transpose-frame
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (transpose-frame))
|
||
</span></span></code></pre></div><p>Finally, the entrypoint for the Emacs integration. In addition to the commands defined above, it processes <code>split</code> and <code>kill</code> commands and passes every other command back to i3.</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="display:flex;"><span>(defun my/emacs-i3-integration (command)
|
||
</span></span><span style="display:flex;"><span> (pcase command
|
||
</span></span><span style="display:flex;"><span> ((rx bos <span style="color:#e6db74">"focus"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/emacs-i3-windmove
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</span>))))
|
||
</span></span><span style="display:flex;"><span> ((rx bos <span style="color:#e6db74">"move"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/emacs-i3-move-window
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</span>))))
|
||
</span></span><span style="display:flex;"><span> ((rx bos <span style="color:#e6db74">"resize"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/emacs-i3-resize-window
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">2</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-to-number</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">3</span>))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"layout toggle split"</span> (transpose-frame))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"split h"</span> (evil-window-split))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"split v"</span> (evil-window-vsplit))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"kill"</span> (evil-quit))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">-</span> (i3-msg command))))
|
||
</span></span></code></pre></div><h3 id="editing-text">Editing text</h3>
|
||
<p>Various packages, tricks, and settings that help with the central task of Emacs - editing text.</p>
|
||
<h4 id="indentation-and-whitespace">Indentation & whitespace</h4>
|
||
<h5 id="aggressive-indent">Aggressive Indent</h5>
|
||
<p>A package to keep the code intended.</p>
|
||
<p>Doesn’t work too well with many ecosystems 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"><span style="display:flex;"><span>(use-package aggressive-indent
|
||
</span></span><span style="display:flex;"><span> :commands (aggressive-indent-mode)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h5 id="delete-trailing-whitespace">Delete trailing whitespace</h5>
|
||
<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"><span style="display:flex;"><span>(setq my/trailing-whitespace-modes <span style="color:#f92672">'</span>(markdown-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(require <span style="color:#e6db74">'cl-extra</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'before-save-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (unless (cl-some <span style="color:#a6e22e">#'</span>derived-mode-p my/trailing-whitespace-modes)
|
||
</span></span><span style="display:flex;"><span> (delete-trailing-whitespace))))
|
||
</span></span></code></pre></div><h5 id="tabs">Tabs</h5>
|
||
<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"><span style="display:flex;"><span>(setq tab-always-indent <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq-default default-tab-width <span style="color:#ae81ff">4</span>)
|
||
</span></span><span style="display:flex;"><span>(setq-default tab-width <span style="color:#ae81ff">4</span>)
|
||
</span></span><span style="display:flex;"><span>(setq-default evil-indent-convert-tabs <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>(setq-default indent-tabs-mode <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>(setq-default evil-shift-round <span style="color:#66d9ef">nil</span>)
|
||
</span></span></code></pre></div><h4 id="settings">Settings</h4>
|
||
<h5 id="scrolling">Scrolling</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"><span style="display:flex;"><span>(setq scroll-conservatively scroll-margin)
|
||
</span></span><span style="display:flex;"><span>(setq scroll-step <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>(setq scroll-preserve-screen-position <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>(setq scroll-error-top-bottom <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>(setq mouse-wheel-progressive-speed <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>(setq mouse-wheel-inhibit-click-time <span style="color:#66d9ef">nil</span>)
|
||
</span></span></code></pre></div><h5 id="clipboard">Clipboard</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"><span style="display:flex;"><span>(setq select-enable-clipboard <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>(setq mouse-yank-at-point <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h5 id="backups">Backups</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"><span style="display:flex;"><span>(setq backup-inhibited <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>(setq auto-save-default <span style="color:#66d9ef">nil</span>)
|
||
</span></span></code></pre></div><h4 id="undo-tree">Undo Tree</h4>
|
||
<p>Replaces Emacs built-in sequential undo system with a tree-based one. Probably one of the greatest options 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"><span style="display:flex;"><span>(use-package undo-tree
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-undo-tree-mode)
|
||
</span></span><span style="display:flex;"><span> (setq undo-tree-visualizer-diff <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq undo-tree-visualizer-timestamps <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'undo-tree-visualize</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">fset</span> <span style="color:#e6db74">'undo-auto-amalgamate</span> <span style="color:#e6db74">'ignore</span>)
|
||
</span></span><span style="display:flex;"><span> (setq undo-limit <span style="color:#ae81ff">6710886400</span>)
|
||
</span></span><span style="display:flex;"><span> (setq undo-strong-limit <span style="color:#ae81ff">100663296</span>)
|
||
</span></span><span style="display:flex;"><span> (setq undo-outer-limit <span style="color:#ae81ff">1006632960</span>))
|
||
</span></span></code></pre></div><h4 id="snippets">Snippets</h4>
|
||
<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"><span style="display:flex;"><span>(use-package yasnippet-snippets
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package yasnippet
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq yas-snippet-dirs
|
||
</span></span><span style="display:flex;"><span> <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">"snippets"</span>)
|
||
</span></span><span style="display:flex;"><span> yasnippet-snippets-dir))
|
||
</span></span><span style="display:flex;"><span> (setq yas-triggers-in-field <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (yas-global-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-imap <span style="color:#e6db74">"M-TAB"</span> <span style="color:#e6db74">'company-yasnippet</span>)
|
||
</span></span></code></pre></div><h4 id="other-small-packages">Other small packages</h4>
|
||
<h5 id="managing-parentheses--smartparens">Managing parentheses (smartparens)</h5>
|
||
<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"><span style="display:flex;"><span>(use-package smartparens
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h5 id="expand-region">Expand region</h5>
|
||
<p>A package to select an ever-increasing (or ever-decreasing) region of text.</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="display:flex;"><span>(use-package expand-region
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (er/expand-region)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (general-nmap <span style="color:#e6db74">"+"</span> <span style="color:#e6db74">'er/expand-region</span>))
|
||
</span></span></code></pre></div><h5 id="visual-fill-column-mode">Visual fill column mode</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"><span style="display:flex;"><span>(use-package visual-fill-column
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (visual-fill-column-mode)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'visual-fill-column-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda () (setq visual-fill-column-center-text <span style="color:#66d9ef">t</span>))))
|
||
</span></span></code></pre></div><h3 id="working-with-projects">Working with projects</h3>
|
||
<p>Packages related to managing projects.</p>
|
||
<p>Another important package that also touches this category is <a href="#dired">dired</a>, but it has its separate section in “Applications”. I used to have <a href="https://github.com/Alexander-Miller/treemacs">Treemacs</a> here, but in the end, decided that dired with <a href="https://github.com/jojojames/dired-sidebar">dired-sidebar</a> does a better job.</p>
|
||
<h4 id="projectile">Projectile</h4>
|
||
<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"><span style="display:flex;"><span>(use-package projectile
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (projectile-mode <span style="color:#ae81ff">+1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq projectile-project-search-path <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/Code"</span> <span style="color:#e6db74">"~/Documents"</span>))
|
||
</span></span><span style="display:flex;"><span> (defadvice projectile-project-root (around ignore-remote first activate)
|
||
</span></span><span style="display:flex;"><span> (unless (file-remote-p default-directory) ad-do-it)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package counsel-projectile
|
||
</span></span><span style="display:flex;"><span> :after (counsel projectile)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"p"</span> <span style="color:#f92672">'</span>(:keymap projectile-command-map :which-key <span style="color:#e6db74">"projectile"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-nmap <span style="color:#e6db74">"C-p"</span> <span style="color:#e6db74">'counsel-projectile-find-file</span>)
|
||
</span></span></code></pre></div><h4 id="git-and-magit">Git & Magit</h4>
|
||
<p><a href="https://magit.vc/">Magit</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/magit/forge">forge</a> provides integration with forges, such as GitHub and GitLab.</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 visiting 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"><span style="display:flex;"><span>(use-package magit
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (magit-status magit-file-dispatch)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq magit-blame-styles
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((margin
|
||
</span></span><span style="display:flex;"><span> (margin-format <span style="color:#f92672">.</span> (<span style="color:#e6db74">"%a %A %s"</span>))
|
||
</span></span><span style="display:flex;"><span> (margin-width <span style="color:#f92672">.</span> <span style="color:#ae81ff">42</span>)
|
||
</span></span><span style="display:flex;"><span> (margin-face <span style="color:#f92672">.</span> magit-blame-margin)
|
||
</span></span><span style="display:flex;"><span> (margin-body-face <span style="color:#f92672">.</span> (magit-blame-dimmed)))
|
||
</span></span><span style="display:flex;"><span> (headings
|
||
</span></span><span style="display:flex;"><span> (heading-format <span style="color:#f92672">.</span> <span style="color:#e6db74">"%-20a %C %s\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (highlight
|
||
</span></span><span style="display:flex;"><span> (highlight-face <span style="color:#f92672">.</span> magit-blame-highlight))
|
||
</span></span><span style="display:flex;"><span> (lines
|
||
</span></span><span style="display:flex;"><span> (show-lines <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (show-message <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package forge
|
||
</span></span><span style="display:flex;"><span> :after magit
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'forge-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"gitlab.etu.ru"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gitlab.etu.ru/api/v4"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gitlab.etu.ru"</span>
|
||
</span></span><span style="display:flex;"><span> forge-gitlab-repository)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package git-gutter
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-git-gutter-mode <span style="color:#ae81ff">+1</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package git-timemachine
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (git-timemachine))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"m"</span> <span style="color:#e6db74">'magit</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M"</span> <span style="color:#e6db74">'magit-file-dispatch</span>)
|
||
</span></span></code></pre></div><h4 id="editorconfig">Editorconfig</h4>
|
||
<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"><span style="display:flex;"><span>(use-package editorconfig
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (unless my/slow-ssh (editorconfig-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'editorconfig-indentation-alist</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(emmet-mode emmet-indentation)))
|
||
</span></span></code></pre></div><h4 id="editing-files">Editing files</h4>
|
||
<p>A minor mode to remember recently edited 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"><span style="display:flex;"><span>(recentf-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span></code></pre></div><p>Save the last place visited in the 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"><span style="display:flex;"><span>(save-place-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span></code></pre></div><h3 id="completion">Completion</h3>
|
||
<h4 id="ivy-counsel-swiper">Ivy, counsel, swiper</h4>
|
||
<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"><span style="display:flex;"><span>(use-package ivy
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq ivy-use-virtual-buffers <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (ivy-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package counsel
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after ivy
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (counsel-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package swiper
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package ivy-rich
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after ivy
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (ivy-rich-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><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">#'</span>ivy-format-function-line))
|
||
</span></span></code></pre></div><h4 id="prescient">prescient</h4>
|
||
<p>A package that enhances sorting & 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"><span style="display:flex;"><span>(use-package ivy-prescient
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after counsel
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (ivy-prescient-mode <span style="color:#ae81ff">+1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq ivy-prescient-retain-classic-highlighting <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (prescient-persist-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq ivy-prescient-sort-commands
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(:not swiper
|
||
</span></span><span style="display:flex;"><span> swiper-isearch
|
||
</span></span><span style="display:flex;"><span> ivy-switch-buffer
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; ivy-resume</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; ivy--restore-session</span>
|
||
</span></span><span style="display:flex;"><span> lsp-ivy-workspace-symbol
|
||
</span></span><span style="display:flex;"><span> dap-switch-stack-frame
|
||
</span></span><span style="display:flex;"><span> my/dap-switch-stack-frame
|
||
</span></span><span style="display:flex;"><span> dap-switch-session
|
||
</span></span><span style="display:flex;"><span> dap-switch-thread
|
||
</span></span><span style="display:flex;"><span> counsel-grep
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; counsel-find-file</span>
|
||
</span></span><span style="display:flex;"><span> counsel-git-grep
|
||
</span></span><span style="display:flex;"><span> counsel-rg
|
||
</span></span><span style="display:flex;"><span> counsel-ag
|
||
</span></span><span style="display:flex;"><span> counsel-ack
|
||
</span></span><span style="display:flex;"><span> counsel-fzf
|
||
</span></span><span style="display:flex;"><span> counsel-pt
|
||
</span></span><span style="display:flex;"><span> counsel-imenu
|
||
</span></span><span style="display:flex;"><span> counsel-yank-pop
|
||
</span></span><span style="display:flex;"><span> counsel-recentf
|
||
</span></span><span style="display:flex;"><span> counsel-buffer-or-recentf
|
||
</span></span><span style="display:flex;"><span> proced-filter-interactive
|
||
</span></span><span style="display:flex;"><span> proced-sort-interactive
|
||
</span></span><span style="display:flex;"><span> perspective-exwm-switch-perspective
|
||
</span></span><span style="display:flex;"><span> my/persp-ivy-switch-buffer-other-window
|
||
</span></span><span style="display:flex;"><span> lsp-execute-code-action
|
||
</span></span><span style="display:flex;"><span> dired-recent-open))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Do not use prescient in find-file</span>
|
||
</span></span><span style="display:flex;"><span> (ivy--alist-set <span style="color:#e6db74">'ivy-sort-functions-alist</span> <span style="color:#a6e22e">#'</span>read-file-name-internal <span style="color:#a6e22e">#'</span>ivy-sort-file-function-default))
|
||
</span></span></code></pre></div><h4 id="keybindings">keybindings</h4>
|
||
<p>Setting up quick access to various completions.</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="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"f"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"various completions"</span>)<span style="color:#f92672">'</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; "b" 'counsel-switch-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'conda-env-activate</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"f"</span> <span style="color:#e6db74">'project-find-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'counsel-yank-pop</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'counsel-rg</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"A"</span> <span style="color:#e6db74">'counsel-ag</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span> normal)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-y"</span> <span style="color:#e6db74">'counsel-yank-pop</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"SPC"</span> <span style="color:#e6db74">'ivy-resume</span>)
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'swiper-isearch</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"S"</span> <span style="color:#e6db74">'swiper-all</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(ivy-minibuffer-map swiper-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-j"</span> <span style="color:#e6db74">'ivy-next-line</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-k"</span> <span style="color:#e6db74">'ivy-previous-line</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<C-return>"</span> <span style="color:#e6db74">'ivy-call</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-RET"</span> <span style="color:#e6db74">'ivy-immediate-done</span>
|
||
</span></span><span style="display:flex;"><span> [escape] <span style="color:#e6db74">'minibuffer-keyboard-quit</span>)
|
||
</span></span></code></pre></div><h4 id="company">company</h4>
|
||
<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"><span style="display:flex;"><span>(use-package company
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-company-mode)
|
||
</span></span><span style="display:flex;"><span> (setq company-idle-delay (if my/lowpower <span style="color:#ae81ff">0.5</span> <span style="color:#ae81ff">0.125</span>))
|
||
</span></span><span style="display:flex;"><span> (setq company-dabbrev-downcase <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq company-show-numbers <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-imap <span style="color:#e6db74">"C-SPC"</span> <span style="color:#e6db74">'company-complete</span>)
|
||
</span></span></code></pre></div><p>A company frontend with nice icons. Disabled since the base company got icons support and since company-box has some issues with spaceline.</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="display:flex;"><span>(use-package company-box
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (and (display-graphic-p) (not my/lowpower))
|
||
</span></span><span style="display:flex;"><span> :after (company)
|
||
</span></span><span style="display:flex;"><span> :hook (company-mode <span style="color:#f92672">.</span> company-box-mode))
|
||
</span></span></code></pre></div><h3 id="help">Help</h3>
|
||
<ul>
|
||
<li><strong>CREDIT</strong>: Thanks @phundrak on the System Crafters Discord for suggesting <code>help-map</code></li>
|
||
</ul>
|
||
<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"><span style="display:flex;"><span>(use-package helpful
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (helpful-callable
|
||
</span></span><span style="display:flex;"><span> helpful-variable
|
||
</span></span><span style="display:flex;"><span> helpful-key
|
||
</span></span><span style="display:flex;"><span> helpful-macro
|
||
</span></span><span style="display:flex;"><span> helpful-function
|
||
</span></span><span style="display:flex;"><span> helpful-command))
|
||
</span></span></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.</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="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"h"</span> <span style="color:#f92672">'</span>(:keymap help-map :which-key <span style="color:#e6db74">"help"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'help-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"f"</span> <span style="color:#e6db74">'helpful-function</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"k"</span> <span style="color:#e6db74">'helpful-key</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"v"</span> <span style="color:#e6db74">'helpful-variable</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"o"</span> <span style="color:#e6db74">'helpful-symbol</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package wakatime-mode
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"SqrtMinusOne/wakatime-mode"</span>)
|
||
</span></span><span style="display:flex;"><span> :if (not (or my/is-termux my/remote-server))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq wakatime-ignore-exit-codes <span style="color:#f92672">'</span>(<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">102</span>))
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'wakatime-init</span> :after (lambda () (setq wakatime-cli-path <span style="color:#e6db74">"/home/pavel/bin/wakatime-cli"</span>)))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq wakatime-cli-path (executable-find "wakatime"))</span>
|
||
</span></span><span style="display:flex;"><span> (global-wakatime-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package request
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package activity-watch-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not (or my/is-termux my/remote-server))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-activity-watch-mode))
|
||
</span></span></code></pre></div><h2 id="ui-settings">UI settings</h2>
|
||
<h3 id="general-settings">General settings</h3>
|
||
<h4 id="miscellaneous">Miscellaneous</h4>
|
||
<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"><span style="display:flex;"><span>(unless my/is-termux
|
||
</span></span><span style="display:flex;"><span> (tool-bar-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (menu-bar-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (scroll-bar-mode <span style="color:#ae81ff">-1</span>))
|
||
</span></span></code></pre></div><p>Transparency. Not setting it now, as I’m using <a href="/configs/desktop/#picom">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="display:flex;"><span><span style="color:#75715e">;; (set-frame-parameter (selected-frame) 'alpha '(90 . 90))</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (add-to-list 'default-frame-alist '(alpha . (90 . 90)))</span>
|
||
</span></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="display:flex;"><span><span style="color:#75715e">;; (global-prettify-symbols-mode)</span>
|
||
</span></span></code></pre></div><p>Do not show GUI dialogs</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="display:flex;"><span>(setq use-dialog-box <span style="color:#66d9ef">nil</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq inhibit-startup-screen <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq visible-bell <span style="color:#ae81ff">0</span>)
|
||
</span></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"><span style="display:flex;"><span>(defalias <span style="color:#e6db74">'yes-or-no-p</span> <span style="color:#e6db74">'y-or-n-p</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq make-pointer-invisible <span style="color:#66d9ef">t</span>)
|
||
</span></span></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"><span style="display:flex;"><span>(show-paren-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span></code></pre></div><p>Highlight the 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"><span style="display:flex;"><span>(global-hl-line-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span></code></pre></div><h4 id="line-numbers">Line numbers</h4>
|
||
<p>Line numbers. There seems to be a catch with the relative number setting:</p>
|
||
<ul>
|
||
<li><code>visual</code> doesn’t take folding into account but also doesn’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"><span style="display:flex;"><span>(global-display-line-numbers-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>(line-number-mode <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>(setq display-line-numbers-type <span style="color:#e6db74">'visual</span>)
|
||
</span></span><span style="display:flex;"><span>(column-number-mode)
|
||
</span></span></code></pre></div><h4 id="word-wrapping">Word wrapping</h4>
|
||
<p>Word wrapping. These settings aren’t too obvious compared to <code>:set wrap</code> from vim:</p>
|
||
<ul>
|
||
<li><code>word-wrap</code> means just “don’t split one word between two lines”. So, if there isn’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"><span style="display:flex;"><span>(setq word-wrap <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>(global-visual-line-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span></code></pre></div><h4 id="custom-frame-format">Custom frame format</h4>
|
||
<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"><span style="display:flex;"><span>(setq-default frame-title-format
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">""</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"emacs"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (:eval</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (let ((project-name (projectile-project-name)))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (if (not (string= "-" project-name))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (format ":%s@%s" project-name (system-name))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (format "@%s" (system-name)))))</span>
|
||
</span></span><span style="display:flex;"><span> ))
|
||
</span></span></code></pre></div><h3 id="themes-and-colors">Themes and colors</h3>
|
||
<h4 id="doom-themes">Doom themes</h4>
|
||
<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"><span style="display:flex;"><span>(use-package doom-themes
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/is-termux)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq doom-themes-enable-bold <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> doom-themes-enable-italic <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (if my/remote-server
|
||
</span></span><span style="display:flex;"><span> (load-theme <span style="color:#e6db74">'doom-gruvbox</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (load-theme <span style="color:#e6db74">'doom-palenight</span> <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (doom-themes-visual-bell-config)
|
||
</span></span><span style="display:flex;"><span> (setq doom-themes-treemacs-theme <span style="color:#e6db74">"doom-colors"</span>)
|
||
</span></span><span style="display:flex;"><span> (doom-themes-treemacs-config))
|
||
</span></span></code></pre></div><h4 id="custom-theme">Custom theme</h4>
|
||
<p>Here I define a custom theme, dependent on Doom color.</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>To make defining colors a bit easier, here is a function to blend two colors, taken from <a href="https://oremacs.com/2015/04/28/blending-faces/">this post</a> by abo-abo.</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="display:flex;"><span>(defun my/color-join (r g b)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Build a color from R G B.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Inverse of </span><span style="color:#e6db74">`color-values'</span><span style="color:#e6db74">."</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"#%02x%02x%02x"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">ash</span> r <span style="color:#ae81ff">-8</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">ash</span> g <span style="color:#ae81ff">-8</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">ash</span> b <span style="color:#ae81ff">-8</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/color-blend (c1 c2 <span style="color:#66d9ef">&optional</span> alpha)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Blend the two colors C1 and C2 with ALPHA.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">C1 and C2 are in the format of </span><span style="color:#e6db74">`color-values'</span><span style="color:#e6db74">.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">ALPHA is a number between 0.0 and 1.0 which corresponds to the
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">influence of C1 on the result."</span>
|
||
</span></span><span style="display:flex;"><span> (setq alpha (or alpha <span style="color:#ae81ff">0.5</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'</span>my/color-join
|
||
</span></span><span style="display:flex;"><span> (cl-mapcar
|
||
</span></span><span style="display:flex;"><span> (lambda (x y)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">round</span> (<span style="color:#a6e22e">+</span> (<span style="color:#a6e22e">*</span> x alpha) (<span style="color:#a6e22e">*</span> y (<span style="color:#a6e22e">-</span> <span style="color:#ae81ff">1</span> alpha)))))
|
||
</span></span><span style="display:flex;"><span> c1 c2)))
|
||
</span></span></code></pre></div><p>Defining the theme itself.</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="display:flex;"><span>(deftheme my-theme-1)
|
||
</span></span></code></pre></div><p>A macro to simplify defining custom 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"><span style="display:flex;"><span>(defvar my/doom-theme-update-colors-hook <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defmacro my/use-doom-colors (<span style="color:#66d9ef">&rest</span> data)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(progn
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'my/doom-theme-update-colors-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (custom-theme-set-faces
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'my-theme-1</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,@</span>(cl-loop for i in data collect
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span><span style="color:#e6db74">'\`</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#f92672">,</span>(<span style="color:#a6e22e">car</span> i)
|
||
</span></span><span style="display:flex;"><span> ((<span style="color:#66d9ef">t</span> (<span style="color:#f92672">,@</span>(cl-loop for (key value) on (<span style="color:#a6e22e">cdr</span> i) by <span style="color:#a6e22e">#'</span>cddr
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">append</span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>key (<span style="color:#f92672">,</span><span style="color:#e6db74">'\,</span> <span style="color:#f92672">,</span>value))))))))))))
|
||
</span></span><span style="display:flex;"><span> (when (and (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'doom-color</span>) my/emacs-started)
|
||
</span></span><span style="display:flex;"><span> (my/update-my-theme))))
|
||
</span></span></code></pre></div><p>This macro puts lambdas to <code>my/doom-theme-update-colors-hook</code> that updates faces in <code>my-theme-1</code>. Now I have to call this hook:</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="display:flex;"><span>(defun my/update-my-theme (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">'my/doom-theme-update-colors-hook</span>)
|
||
</span></span><span style="display:flex;"><span> (enable-theme <span style="color:#e6db74">'my-theme-1</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(unless my/is-termux
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'load-theme</span> :after <span style="color:#a6e22e">#'</span>my/update-my-theme)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'doom-color</span>)
|
||
</span></span><span style="display:flex;"><span> (my/update-my-theme))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'emacs-startup-hook</span> <span style="color:#a6e22e">#'</span>my/update-my-theme))
|
||
</span></span></code></pre></div><p>Defining colors for <code>tab-bar.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"><span style="display:flex;"><span>(my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span> (tab-bar-tab :background (doom-color <span style="color:#e6db74">'bg</span>)
|
||
</span></span><span style="display:flex;"><span> :foreground (doom-color <span style="color:#e6db74">'yellow</span>)
|
||
</span></span><span style="display:flex;"><span> :underline (doom-color <span style="color:#e6db74">'yellow</span>))
|
||
</span></span><span style="display:flex;"><span> (tab-bar :background <span style="color:#66d9ef">nil</span> :foreground <span style="color:#66d9ef">nil</span>))
|
||
</span></span></code></pre></div><h4 id="dim-inactive-buffers">Dim inactive buffers</h4>
|
||
<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"><span style="display:flex;"><span>(use-package auto-dim-other-buffers
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (auto-dim-other-buffers-mode <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span> (auto-dim-other-buffers-face
|
||
</span></span><span style="display:flex;"><span> :background (color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>))))
|
||
</span></span></code></pre></div><h3 id="fonts">Fonts</h3>
|
||
<h4 id="frame-font">Frame 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’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"><span style="display:flex;"><span>(when (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">x-list-fonts</span> <span style="color:#e6db74">"JetBrainsMono Nerd Font"</span>)
|
||
</span></span><span style="display:flex;"><span> (set-frame-font <span style="color:#e6db74">"JetBrainsMono Nerd Font 10"</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Install JetBrainsMono Nerd Font!"</span>)))
|
||
</span></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>
|
||
<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"><span style="display:flex;"><span>(use-package ligature
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"mickeynp/ligature.el"</span>)
|
||
</span></span><span style="display:flex;"><span> :if (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (ligature-set-ligatures
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(
|
||
</span></span><span style="display:flex;"><span> typescript-mode
|
||
</span></span><span style="display:flex;"><span> js2-mode
|
||
</span></span><span style="display:flex;"><span> vue-mode
|
||
</span></span><span style="display:flex;"><span> svelte-mode
|
||
</span></span><span style="display:flex;"><span> scss-mode
|
||
</span></span><span style="display:flex;"><span> php-mode
|
||
</span></span><span style="display:flex;"><span> python-mode
|
||
</span></span><span style="display:flex;"><span> js-mode
|
||
</span></span><span style="display:flex;"><span> markdown-mode
|
||
</span></span><span style="display:flex;"><span> clojure-mode
|
||
</span></span><span style="display:flex;"><span> go-mode
|
||
</span></span><span style="display:flex;"><span> sh-mode
|
||
</span></span><span style="display:flex;"><span> haskell-mode
|
||
</span></span><span style="display:flex;"><span> web-mode)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"--"</span> <span style="color:#e6db74">"---"</span> <span style="color:#e6db74">"=="</span> <span style="color:#e6db74">"==="</span> <span style="color:#e6db74">"!="</span> <span style="color:#e6db74">"!=="</span> <span style="color:#e6db74">"=!="</span> <span style="color:#e6db74">"=:="</span> <span style="color:#e6db74">"=/="</span> <span style="color:#e6db74">"<="</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">">="</span> <span style="color:#e6db74">"&&"</span> <span style="color:#e6db74">"&&&"</span> <span style="color:#e6db74">"&="</span> <span style="color:#e6db74">"++"</span> <span style="color:#e6db74">"+++"</span> <span style="color:#e6db74">"***"</span> <span style="color:#e6db74">";;"</span> <span style="color:#e6db74">"!!"</span> <span style="color:#e6db74">"??"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"?:"</span> <span style="color:#e6db74">"?."</span> <span style="color:#e6db74">"?="</span> <span style="color:#e6db74">"<:"</span> <span style="color:#e6db74">":<"</span> <span style="color:#e6db74">":>"</span> <span style="color:#e6db74">">:"</span> <span style="color:#e6db74">"<>"</span> <span style="color:#e6db74">"<<<"</span> <span style="color:#e6db74">">>>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<<"</span> <span style="color:#e6db74">">>"</span> <span style="color:#e6db74">"||"</span> <span style="color:#e6db74">"-|"</span> <span style="color:#e6db74">"_|_"</span> <span style="color:#e6db74">"|-"</span> <span style="color:#e6db74">"||-"</span> <span style="color:#e6db74">"|="</span> <span style="color:#e6db74">"||="</span> <span style="color:#e6db74">"##"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"###"</span> <span style="color:#e6db74">"####"</span> <span style="color:#e6db74">"#{"</span> <span style="color:#e6db74">"#["</span> <span style="color:#e6db74">"]#"</span> <span style="color:#e6db74">"#("</span> <span style="color:#e6db74">"#?"</span> <span style="color:#e6db74">"#_"</span> <span style="color:#e6db74">"#_("</span> <span style="color:#e6db74">"#:"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"#!"</span> <span style="color:#e6db74">"#="</span> <span style="color:#e6db74">"^="</span> <span style="color:#e6db74">"<$>"</span> <span style="color:#e6db74">"<$"</span> <span style="color:#e6db74">"$>"</span> <span style="color:#e6db74">"<+>"</span> <span style="color:#e6db74">"<+"</span> <span style="color:#e6db74">"+>"</span> <span style="color:#e6db74">"<*>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<*"</span> <span style="color:#e6db74">"*>"</span> <span style="color:#e6db74">"</"</span> <span style="color:#e6db74">"</>"</span> <span style="color:#e6db74">"/>"</span> <span style="color:#e6db74">"<!--"</span> <span style="color:#e6db74">"<#--"</span> <span style="color:#e6db74">"-->"</span> <span style="color:#e6db74">"->"</span> <span style="color:#e6db74">"->>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<<-"</span> <span style="color:#e6db74">"<-"</span> <span style="color:#e6db74">"<=<"</span> <span style="color:#e6db74">"=<<"</span> <span style="color:#e6db74">"<<="</span> <span style="color:#e6db74">"<=="</span> <span style="color:#e6db74">"<=>"</span> <span style="color:#e6db74">"<==>"</span> <span style="color:#e6db74">"==>"</span> <span style="color:#e6db74">"=>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"=>>"</span> <span style="color:#e6db74">">=>"</span> <span style="color:#e6db74">">>="</span> <span style="color:#e6db74">">>-"</span> <span style="color:#e6db74">">-"</span> <span style="color:#e6db74">">--"</span> <span style="color:#e6db74">"-<"</span> <span style="color:#e6db74">"-<<"</span> <span style="color:#e6db74">">->"</span> <span style="color:#e6db74">"<-<"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<-|"</span> <span style="color:#e6db74">"<=|"</span> <span style="color:#e6db74">"|=>"</span> <span style="color:#e6db74">"|->"</span> <span style="color:#e6db74">"<->"</span> <span style="color:#e6db74">"<~~"</span> <span style="color:#e6db74">"<~"</span> <span style="color:#e6db74">"<~>"</span> <span style="color:#e6db74">"~~"</span> <span style="color:#e6db74">"~~>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"~>"</span> <span style="color:#e6db74">"~-"</span> <span style="color:#e6db74">"-~"</span> <span style="color:#e6db74">"~@"</span> <span style="color:#e6db74">"[||]"</span> <span style="color:#e6db74">"|]"</span> <span style="color:#e6db74">"[|"</span> <span style="color:#e6db74">"|}"</span> <span style="color:#e6db74">"{|"</span> <span style="color:#e6db74">"[<"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">">]"</span> <span style="color:#e6db74">"|>"</span> <span style="color:#e6db74">"<|"</span> <span style="color:#e6db74">"||>"</span> <span style="color:#e6db74">"<||"</span> <span style="color:#e6db74">"|||>"</span> <span style="color:#e6db74">"<|||"</span> <span style="color:#e6db74">"<|>"</span> <span style="color:#e6db74">"..."</span> <span style="color:#e6db74">".."</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">".="</span> <span style="color:#e6db74">".-"</span> <span style="color:#e6db74">"..<"</span> <span style="color:#e6db74">".?"</span> <span style="color:#e6db74">"::"</span> <span style="color:#e6db74">":::"</span> <span style="color:#e6db74">":="</span> <span style="color:#e6db74">"::="</span> <span style="color:#e6db74">":?"</span> <span style="color:#e6db74">":?>"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"//"</span> <span style="color:#e6db74">"///"</span> <span style="color:#e6db74">"/*"</span> <span style="color:#e6db74">"*/"</span> <span style="color:#e6db74">"/="</span> <span style="color:#e6db74">"//="</span> <span style="color:#e6db74">"/=="</span> <span style="color:#e6db74">"@_"</span> <span style="color:#e6db74">"__"</span>))
|
||
</span></span><span style="display:flex;"><span> (global-ligature-mode <span style="color:#66d9ef">t</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package all-the-icons
|
||
</span></span><span style="display:flex;"><span> :if (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h3 id="text-highlight">Text highlight</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"><span style="display:flex;"><span>(use-package highlight-indent-guides
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not (or my/lowpower my/remote-server))
|
||
</span></span><span style="display:flex;"><span> :hook (
|
||
</span></span><span style="display:flex;"><span> (prog-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
|
||
</span></span><span style="display:flex;"><span> (vue-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
|
||
</span></span><span style="display:flex;"><span> (LaTeX-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq highlight-indent-guides-method <span style="color:#e6db74">'bitmap</span>)
|
||
</span></span><span style="display:flex;"><span> (setq highlight-indent-guides-bitmap-function <span style="color:#e6db74">'highlight-indent-guides--bitmap-line</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package rainbow-delimiters
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/lowpower)
|
||
</span></span><span style="display:flex;"><span> :hook ((prog-mode <span style="color:#f92672">.</span> rainbow-delimiters-mode)))
|
||
</span></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"><span style="display:flex;"><span>(use-package rainbow-mode
|
||
</span></span><span style="display:flex;"><span> :commands (rainbow-mode)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><p>Highlight TODOs and 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"><span style="display:flex;"><span>(use-package hl-todo
|
||
</span></span><span style="display:flex;"><span> :hook (prog-mode <span style="color:#f92672">.</span> hl-todo-mode)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h3 id="doom-modeline">Doom Modeline</h3>
|
||
<p>A modeline from Doom Emacs. A big advantage of this package is that it just works out of the box and does not require much customization.</p>
|
||
<p>I tried a bunch of other options, including <a href="https://github.com/TheBB/spaceline">spaceline</a>, but in the end, decided that Doom Modeline works best for me.</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"><span style="display:flex;"><span>(use-package doom-modeline
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; :if (not (display-graphic-p))</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-env-enable-python <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-env-enable-go <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-buffer-encoding <span style="color:#e6db74">'nondefault</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-hud <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-persp-icon <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-persp-name <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-minor-modes <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq doom-modeline-buffer-state-icon <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (doom-modeline-mode <span style="color:#ae81ff">1</span>))
|
||
</span></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 “perspectives”, 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’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"><span style="display:flex;"><span>(use-package perspective
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq persp-show-modestring 'header)</span>
|
||
</span></span><span style="display:flex;"><span> (setq persp-sort <span style="color:#e6db74">'created</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (persp-mode)
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"x"</span> <span style="color:#f92672">'</span>(:keymap perspective-map :which-key <span style="color:#e6db74">"perspective"</span>))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'override</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gt"</span> <span style="color:#e6db74">'persp-next</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gT"</span> <span style="color:#e6db74">'persp-prev</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gn"</span> <span style="color:#e6db74">'persp-switch</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gN"</span> <span style="color:#e6db74">'persp-kill</span>)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'perspective-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"x"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'persp-ibuffer</span>))
|
||
</span></span></code></pre></div><h4 id="functions-to-manage-buffers">Functions to manage buffers</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"><span style="display:flex;"><span>(defun my/persp-move-window-and-switch ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#'</span>persp-switch)
|
||
</span></span><span style="display:flex;"><span> (persp-set-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
|
||
</span></span><span style="display:flex;"><span> (switch-to-buffer buffer)))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/persp-copy-window-and-switch ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#'</span>persp-switch)
|
||
</span></span><span style="display:flex;"><span> (persp-add-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
|
||
</span></span><span style="display:flex;"><span> (switch-to-buffer buffer)))
|
||
</span></span></code></pre></div><p>Switch to a perspective buffer in other window.</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="display:flex;"><span>(defun my/persp-ivy-switch-buffer-other-window (arg)
|
||
</span></span><span style="display:flex;"><span> (interactive <span style="color:#e6db74">"P"</span>)
|
||
</span></span><span style="display:flex;"><span> (declare-function ivy-switch-buffer-other-window <span style="color:#e6db74">"ivy.el"</span>)
|
||
</span></span><span style="display:flex;"><span> (persp--switch-buffer-ivy-counsel-helper
|
||
</span></span><span style="display:flex;"><span> arg
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (ivy-read <span style="color:#e6db74">"Switch to buffer in other window: "</span> <span style="color:#a6e22e">#'internal-complete-buffer</span>
|
||
</span></span><span style="display:flex;"><span> :keymap ivy-switch-buffer-map
|
||
</span></span><span style="display:flex;"><span> :preselect (<span style="color:#a6e22e">buffer-name</span> (<span style="color:#a6e22e">other-buffer</span> (<span style="color:#a6e22e">current-buffer</span>)))
|
||
</span></span><span style="display:flex;"><span> :action <span style="color:#a6e22e">#'</span>ivy--switch-buffer-other-window-action
|
||
</span></span><span style="display:flex;"><span> :matcher <span style="color:#a6e22e">#'</span>ivy--switch-buffer-matcher
|
||
</span></span><span style="display:flex;"><span> :caller <span style="color:#e6db74">'ivy-switch-buffer</span>))))
|
||
</span></span></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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'perspective</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'perspective-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"m"</span> <span style="color:#a6e22e">#'</span>my/persp-move-window-and-switch
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"f"</span> <span style="color:#a6e22e">#'</span>my/persp-copy-window-and-switch))
|
||
</span></span></code></pre></div><h4 id="automating-perspectives">Automating perspectives</h4>
|
||
<p>I’d like to have various Emacs apps open up in their designated perspectives (also in their designated workspaces when I’m using EXWM).</p>
|
||
<p>So, here is a macro to run something in a given perspective in a given workspace. This is meant to be used in general.el 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"><span style="display:flex;"><span>(defmacro my/command-in-persp (command-name persp-name workspace-index <span style="color:#66d9ef">&rest</span> args)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`'</span>((lambda ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (when (and <span style="color:#f92672">,</span>workspace-index (<span style="color:#a6e22e">fboundp</span> <span style="color:#a6e22e">#'</span>exwm-workspace-switch-create))
|
||
</span></span><span style="display:flex;"><span> (exwm-workspace-switch-create <span style="color:#f92672">,</span>workspace-index))
|
||
</span></span><span style="display:flex;"><span> (persp-switch <span style="color:#f92672">,</span>persp-name)
|
||
</span></span><span style="display:flex;"><span> (delete-other-windows)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,@</span>args)
|
||
</span></span><span style="display:flex;"><span> :wk <span style="color:#f92672">,</span>command-name))
|
||
</span></span></code></pre></div><h2 id="programming">Programming</h2>
|
||
<h3 id="general-setup">General setup</h3>
|
||
<h4 id="treemacs">Treemacs</h4>
|
||
<p><a href="https://github.com/Alexander-Miller/treemacs">Treemacs</a> is a quite large & powerful package, but as of now I’ve replaced it with dired. However, I still have a small configuration because lsp-mode and dap-mode depend on 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="display:flex;"><span>(use-package treemacs
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq treemacs-follow-mode nil)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq treemacs-follow-after-init nil)</span>
|
||
</span></span><span style="display:flex;"><span> (setq treemacs-space-between-root-nodes <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (treemacs-git-mode 'extended)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (add-to-list 'treemacs-pre-file-insert-predicates #'treemacs-is-file-git-ignored?)</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'treemacs-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> [mouse-1] <span style="color:#a6e22e">#'</span>treemacs-single-click-expand-action
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-l"</span> <span style="color:#a6e22e">#'</span>treemacs-root-down
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-h"</span> <span style="color:#a6e22e">#'</span>treemacs-root-up
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#a6e22e">#'</span>treemacs-quit)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'treemacs-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'treemacs-quit</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package treemacs-evil
|
||
</span></span><span style="display:flex;"><span> :after (treemacs evil)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><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"><span style="display:flex;"><span>(use-package lsp-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not (or my/slow-ssh my/is-termux my/remote-server))
|
||
</span></span><span style="display:flex;"><span> :hook (
|
||
</span></span><span style="display:flex;"><span> (typescript-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (js-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (vue-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (go-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (svelte-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (python-mode . lsp)</span>
|
||
</span></span><span style="display:flex;"><span> (json-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (haskell-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (haskell-literate-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> (java-mode <span style="color:#f92672">.</span> lsp)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (csharp-mode . lsp)</span>
|
||
</span></span><span style="display:flex;"><span> )
|
||
</span></span><span style="display:flex;"><span> :commands lsp
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq lsp-keymap-prefix <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq lsp-idle-delay <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq lsp-eslint-server-command <span style="color:#f92672">'</span>(<span style="color:#e6db74">"node"</span> <span style="color:#e6db74">"/home/pavel/.emacs.d/.cache/lsp/eslint/unzipped/extension/server/out/eslintServer.js"</span> <span style="color:#e6db74">"--stdio"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq lsp-eslint-run <span style="color:#e6db74">"onSave"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq lsp-signature-render-documentation <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (lsp-headerline-breadcrumb-mode nil)</span>
|
||
</span></span><span style="display:flex;"><span> (setq lsp-headerline-breadcrumb-enable <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq lsp-modeline-code-actions-enable <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq lsp-modeline-diagnostics-enable <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'lsp-language-id-configuration</span> <span style="color:#f92672">'</span>(svelte-mode <span style="color:#f92672">.</span> <span style="color:#e6db74">"svelte"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package lsp-ui
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands lsp-ui-mode
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq lsp-ui-doc-delay <span style="color:#ae81ff">2</span>)
|
||
</span></span><span style="display:flex;"><span> (setq lsp-ui-sideline-show-hover <span style="color:#66d9ef">nil</span>))
|
||
</span></span></code></pre></div><h5 id="integrations">Integrations</h5>
|
||
<p>The only integration left now is treemacs.</p>
|
||
<p>Origami should’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="display:flex;"><span><span style="color:#75715e">;; (use-package helm-lsp</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :straight t</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :commands helm-lsp-workspace-symbol)</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (use-package origami</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :straight t</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :hook (prog-mode . origami-mode))</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (use-package lsp-origami</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :straight t</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :config</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (add-hook 'lsp-after-open-hook #'lsp-origami-try-enable))</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package lsp-treemacs
|
||
</span></span><span style="display:flex;"><span> :after (lsp)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands lsp-treemacs-errors-list)
|
||
</span></span></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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"l"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"lsp"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'lsp-ui-peek-find-definitions</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'lsp-rename</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'lsp-ui-peek-find-references</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'lsp-ui-find-workspace-symbol</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'lsp-execute-code-action</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'list-flycheck-errors</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package flycheck
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (global-flycheck-mode)
|
||
</span></span><span style="display:flex;"><span> (setq flycheck-check-syntax-automatically <span style="color:#f92672">'</span>(save idle-buffer-switch mode-enabled))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (add-hook 'evil-insert-state-exit-hook</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (lambda ()</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (if flycheck-checker</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (flycheck-buffer))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; ))</span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'flycheck-eslint-config-exists-p</span> :override (lambda() <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'display-buffer-alist</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx bos <span style="color:#e6db74">"*Flycheck errors*"</span> eos)
|
||
</span></span><span style="display:flex;"><span> (display-buffer-reuse-window
|
||
</span></span><span style="display:flex;"><span> display-buffer-in-side-window)
|
||
</span></span><span style="display:flex;"><span> (side <span style="color:#f92672">.</span> bottom)
|
||
</span></span><span style="display:flex;"><span> (reusable-frames <span style="color:#f92672">.</span> visible)
|
||
</span></span><span style="display:flex;"><span> (window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>))))
|
||
</span></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’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 run 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"><span style="display:flex;"><span>(defun my/tree-sitter-if-not-mmm ()
|
||
</span></span><span style="display:flex;"><span> (when (not (and (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'mmm-temp-buffer-name</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-equal</span> mmm-temp-buffer-name (<span style="color:#a6e22e">buffer-name</span>))))
|
||
</span></span><span style="display:flex;"><span> (tree-sitter-mode)
|
||
</span></span><span style="display:flex;"><span> (tree-sitter-hl-mode)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package tree-sitter
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :hook ((typescript-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
|
||
</span></span><span style="display:flex;"><span> (js-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
|
||
</span></span><span style="display:flex;"><span> (python-mode <span style="color:#f92672">.</span> tree-sitter-mode)
|
||
</span></span><span style="display:flex;"><span> (python-mode <span style="color:#f92672">.</span> tree-sitter-hl-mode)
|
||
</span></span><span style="display:flex;"><span> (csharp-mode <span style="color:#f92672">.</span> tree-sitter-mode)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package tree-sitter-langs
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after tree-sitter)
|
||
</span></span></code></pre></div><h4 id="dap">DAP</h4>
|
||
<p>An Emacs client for Debugger Adapter Protocol.</p>
|
||
<p>As of the time of this writing, I mostly debug TypeScript, so the main competitor is Chrome Inspector for node.js.</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"><span style="display:flex;"><span>(use-package dap-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (dap-debug)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq lsp-enable-dap-auto-configure <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (setq dap-ui-variable-length <span style="color:#ae81ff">100</span>)
|
||
</span></span><span style="display:flex;"><span> (setq dap-auto-show-output <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'dap-node</span>)
|
||
</span></span><span style="display:flex;"><span> (dap-node-setup)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'dap-chrome</span>)
|
||
</span></span><span style="display:flex;"><span> (dap-chrome-setup)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'dap-python</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (dap-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (dap-ui-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (dap-tooltip-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (tooltip-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span></code></pre></div><h5 id="controls">Controls</h5>
|
||
<p>I don’t like some keybindings in the built-in hydra, and there seems to be no easy way to modify the existing hydra, so I create my own. I tried to use transient, but the transient buffer seems to conflict with special buffers of DAP, and hydra does not.</p>
|
||
<p>Also, I want the hydra to toggle UI windows instead of just opening them, so here is a macro that defines such functions:</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="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
</span></span><span style="display:flex;"><span> (defmacro my/define-dap-ui-window-toggler (name)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(defun <span style="color:#f92672">,</span>(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"my/dap-ui-toggle-"</span> name)) ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Toggle DAP "</span> name <span style="color:#e6db74">"buffer"</span>)
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (if-let (window (<span style="color:#a6e22e">get-buffer-window</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"dap-ui--"</span> name <span style="color:#e6db74">"-buffer"</span>))))
|
||
</span></span><span style="display:flex;"><span> (quit-window <span style="color:#66d9ef">nil</span> window)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#f92672">,</span>(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"dap-ui-"</span> name))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-ui-window-toggler <span style="color:#e6db74">"locals"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-ui-window-toggler <span style="color:#e6db74">"expressions"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-ui-window-toggler <span style="color:#e6db74">"sessions"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-ui-window-toggler <span style="color:#e6db74">"breakpoints"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-ui-window-toggler <span style="color:#e6db74">"repl"</span>))
|
||
</span></span></code></pre></div><p>And here is the hydra:</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="display:flex;"><span>(defhydra my/dap-hydra (:color pink :hint <span style="color:#66d9ef">nil</span> :foreign-keys run)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">^Stepping^ ^UI^ ^Switch^ ^Breakpoints^ ^Debug^ ^Expressions
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">^^^^^^^^------------------------------------------------------------------------------------------------------------------------------------------
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">_n_: Next _uc_: Controls _ss_: Session _bb_: Toggle _dd_: Debug _ee_: Eval
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">_i_: Step in _ue_: Expressions _st_: Thread _bd_: Delete _dr_: Debug recent _er_: Eval region
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">_o_: Step out _ul_: Locals _sf_: Stack frame _ba_: Add _dl_: Debug last _es_: Eval thing at point
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">_c_: Continue _ur_: REPL _su_: Up stack frame _bc_: Set condition _de_: Edit debug template _ea_: Add expression
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">_r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set hit count _Q_: Disconnect _ed_: Remove expression
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> _us_: Sessions _sF_: Stack frame filtered _bl_: Set log message _eu_: Refresh expressions
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> _ub_: Breakpoints "</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"n"</span> dap-next)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"i"</span> dap-step-in)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"o"</span> dap-step-out)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"c"</span> dap-continue)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"r"</span> dap-restart-frame)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"uc"</span> dap-ui-controls-mode)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ue"</span> my/dap-ui-toggle-expressions)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ul"</span> my/dap-ui-toggle-locals)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ur"</span> my/dap-ui-toggle-repl)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"uo"</span> dap-go-to-output-buffer)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"us"</span> my/dap-ui-toggle-sessions)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ub"</span> my/dap-ui-toggle-breakpoints)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ss"</span> dap-switch-session)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"st"</span> dap-switch-thread)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"sf"</span> dap-switch-stack-frame)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"sF"</span> my/dap-switch-stack-frame)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"su"</span> dap-up-stack-frame)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"sd"</span> dap-down-stack-frame)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"bb"</span> dap-breakpoint-toggle)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ba"</span> dap-breakpoint-add)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"bd"</span> dap-breakpoint-delete)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"bc"</span> dap-breakpoint-condition)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"bh"</span> dap-breakpoint-hit-condition)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"bl"</span> dap-breakpoint-log-message)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"dd"</span> dap-debug)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"dr"</span> dap-debug-recent)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"dl"</span> dap-debug-last)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"de"</span> dap-debug-edit-template)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ee"</span> dap-eval)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ea"</span> dap-ui-expressions-add)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"er"</span> dap-eval-region)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"es"</span> dap-eval-thing-at-point)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ed"</span> dap-ui-expressions-remove)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"eu"</span> dap-ui-expressions-refresh)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"q"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"quit"</span> :color blue)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"Q"</span> dap-disconnect :color red))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"d"</span> <span style="color:#a6e22e">#'</span>my/dap-hydra/body)
|
||
</span></span></code></pre></div><h5 id="ui-fixes">UI Fixes</h5>
|
||
<p>There are some problems with DAP UI in my setup.</p>
|
||
<p>First, DAP uses Treemacs buffers quite extensively, and they hide the doom modeline for some reason, so I can’t tell which buffer is active and can’t see borders between buffers.</p>
|
||
<p>Second, lines are truncated in some strange way, but calling <code>toggle-truncate-lines</code> seems to fix that.</p>
|
||
<p>So I define a macro that creates a function that I can further use in advices.</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="display:flex;"><span>(defvar my/dap-mode-buffer-fixed <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
</span></span><span style="display:flex;"><span> (defmacro my/define-dap-tree-buffer-fixer (buffer-var <span style="color:#a6e22e">buffer-name</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(defun <span style="color:#f92672">,</span>(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"my/fix-dap-ui-"</span> <span style="color:#a6e22e">buffer-name</span> <span style="color:#e6db74">"-buffer"</span>)) (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (with-current-buffer <span style="color:#f92672">,</span>buffer-var
|
||
</span></span><span style="display:flex;"><span> (unless my/dap-mode-buffer-fixed
|
||
</span></span><span style="display:flex;"><span> (toggle-truncate-lines <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (doom-modeline-set-modeline <span style="color:#e6db74">'info</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local my/dap-mode-buffer-fixed <span style="color:#66d9ef">t</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-tree-buffer-fixer dap-ui--locals-buffer <span style="color:#e6db74">"locals"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-tree-buffer-fixer dap-ui--expressions-buffer <span style="color:#e6db74">"expressions"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-tree-buffer-fixer dap-ui--sessions-buffer <span style="color:#e6db74">"sessions"</span>)
|
||
</span></span><span style="display:flex;"><span> (my/define-dap-tree-buffer-fixer dap-ui--breakpoints-buffer <span style="color:#e6db74">"breakpoints"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dap-ui-locals</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-locals-buffer)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dap-ui-expressions</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-expressions-buffer)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dap-ui-sessions</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-sessions-buffer)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dap-ui-breakpoints</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-breakpoints-buffer))
|
||
</span></span></code></pre></div><h5 id="helper-functions">Helper functions</h5>
|
||
<p>Some helper functions that make debugging with DAP easier.</p>
|
||
<p>DAP seems to mess with window parameters from time to time. This function clears “bad” window parameters.</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="display:flex;"><span>(defun my/clear-bad-window-parameters ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Clear window parameters that interrupt my workflow."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((window (<span style="color:#a6e22e">get-buffer-window</span> (<span style="color:#a6e22e">current-buffer</span>))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">set-window-parameter</span> window <span style="color:#e6db74">'no-delete-other-windows</span> <span style="color:#66d9ef">nil</span>)))
|
||
</span></span></code></pre></div><p>A function to kill a value from a treemacs node.</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="display:flex;"><span>(defun my/dap-yank-value-at-point (node)
|
||
</span></span><span style="display:flex;"><span> (interactive (<span style="color:#a6e22e">list</span> (treemacs-node-at-point)))
|
||
</span></span><span style="display:flex;"><span> (kill-new (<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">plist-get</span> (button-get node :item) :value))))
|
||
</span></span></code></pre></div><p>A function to open a value from a treemacs node in a new 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"><span style="display:flex;"><span>(defun my/dap-display-value (node)
|
||
</span></span><span style="display:flex;"><span> (interactive (<span style="color:#a6e22e">list</span> (treemacs-node-at-point)))
|
||
</span></span><span style="display:flex;"><span> (let ((value (<span style="color:#a6e22e">plist-get</span> (button-get node :item) :value)))
|
||
</span></span><span style="display:flex;"><span> (when value
|
||
</span></span><span style="display:flex;"><span> (let ((buffer (generate-new-buffer <span style="color:#e6db74">"dap-value"</span>)))
|
||
</span></span><span style="display:flex;"><span> (with-current-buffer buffer
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span> value))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">select-window</span> (display-buffer buffer))))))
|
||
</span></span></code></pre></div><h5 id="improved-stack-frame-switching">Improved stack frame switching</h5>
|
||
<p>One significant improvement over Chrome Inspector for my particular stack is an ability to filter the stack frame list, for instance, to see only frames that relate to my current project.</p>
|
||
<p>So, here are functions that customize the filters:</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="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
</span></span><span style="display:flex;"><span> (setq my/dap-stack-frame-filters
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"node_modules,node:internal"</span> <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(rx (or <span style="color:#e6db74">"node_modules"</span> <span style="color:#e6db74">"node:internal"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"node_modules"</span> <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(rx (or <span style="color:#e6db74">"node_modules"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"node:internal"</span> <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(rx (or <span style="color:#e6db74">"node:internal"</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (setq my/dap-stack-frame-current-filter (cdar my/dap-stack-frame-filters))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (defun my/dap-stack-frame-filter-set ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (setq my/dap-stack-frame-current-filter
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">assoc</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Filter: "</span> my/dap-stack-frame-filters)
|
||
</span></span><span style="display:flex;"><span> my/dap-stack-frame-filters))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (defun my/dap-stack-frame-filter (frame)
|
||
</span></span><span style="display:flex;"><span> (when-let (path (dap--get-path-for-frame frame))
|
||
</span></span><span style="display:flex;"><span> (not (<span style="color:#a6e22e">string-match</span> my/dap-stack-frame-current-filter path)))))
|
||
</span></span></code></pre></div><p>And here is a version of <code>dap-switch-stack-frame</code> that uses the said 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"><span style="display:flex;"><span>(defun my/dap-switch-stack-frame ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Switch stackframe by selecting another stackframe stackframes from current thread."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (when (not (dap--cur-session))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">error</span> <span style="color:#e6db74">"There is no active session"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (-if-let (thread-id (dap--debug-session-thread-id (dap--cur-session)))
|
||
</span></span><span style="display:flex;"><span> (-if-let (stack-frames
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">gethash</span>
|
||
</span></span><span style="display:flex;"><span> thread-id
|
||
</span></span><span style="display:flex;"><span> (dap--debug-session-thread-stack-frames (dap--cur-session))))
|
||
</span></span><span style="display:flex;"><span> (let* ((index <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (stack-framces-filtered
|
||
</span></span><span style="display:flex;"><span> (-filter
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'</span>my/dap-stack-frame-filter
|
||
</span></span><span style="display:flex;"><span> stack-frames))
|
||
</span></span><span style="display:flex;"><span> (new-stack-frame
|
||
</span></span><span style="display:flex;"><span> (dap--completing-read
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Select active frame: "</span>
|
||
</span></span><span style="display:flex;"><span> stack-framces-filtered
|
||
</span></span><span style="display:flex;"><span> (-lambda ((frame &as &hash <span style="color:#e6db74">"name"</span>))
|
||
</span></span><span style="display:flex;"><span> (if-let (frame-path (dap--get-path-for-frame frame))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s: %s (in %s)"</span>
|
||
</span></span><span style="display:flex;"><span> (cl-incf index) name frame-path)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s: %s"</span> (cl-incf index) name)))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span> (dap--go-to-stack-frame (dap--cur-session) new-stack-frame))
|
||
</span></span><span style="display:flex;"><span> (->> (dap--cur-session)
|
||
</span></span><span style="display:flex;"><span> dap--debug-session-name
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Current session %s is not stopped"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">error</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">error</span> <span style="color:#e6db74">"No thread is currently active %s"</span> (dap--debug-session-name (dap--cur-session)))))
|
||
</span></span></code></pre></div><h5 id="smarter-switch-to-stack-frame">Smarter switch to stack frame</h5>
|
||
<ul>
|
||
<li><strong>CREDIT</strong>: Thanks @yyoncho on the Emacs LSP Discord for helping me with this!</li>
|
||
</ul>
|
||
<p>By default, when a breakpoint is hit, dap always pop us the buffer in the active EXWM workspace and in the active perspective. I’d like it to switch to an existing buffer instead.</p>
|
||
<p>So first we need to locate EXWM workspace for the file with <code>path</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"><span style="display:flex;"><span>(defun my/exwm-perspective-find-buffer (path)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Find a buffer with PATH in all EXWM perspectives.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Returns (<buffer> . <workspace-index>) or nil."</span>
|
||
</span></span><span style="display:flex;"><span> (let* ((buf (cl-loop for buf being buffers
|
||
</span></span><span style="display:flex;"><span> if (and (<span style="color:#a6e22e">buffer-file-name</span> buf)
|
||
</span></span><span style="display:flex;"><span> (f-equal-p (<span style="color:#a6e22e">buffer-file-name</span> buf) path))
|
||
</span></span><span style="display:flex;"><span> return buf))
|
||
</span></span><span style="display:flex;"><span> (target-workspace
|
||
</span></span><span style="display:flex;"><span> (and buf
|
||
</span></span><span style="display:flex;"><span> (cl-loop for frame in exwm-workspace--list
|
||
</span></span><span style="display:flex;"><span> if (with-selected-frame frame
|
||
</span></span><span style="display:flex;"><span> (cl-loop for persp-name being the hash-keys of (perspectives-hash)
|
||
</span></span><span style="display:flex;"><span> if (<span style="color:#a6e22e">member</span> buf (persp-buffers
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">gethash</span> persp-name (perspectives-hash))))
|
||
</span></span><span style="display:flex;"><span> return persp-name))
|
||
</span></span><span style="display:flex;"><span> return (cl-position frame exwm-workspace--list)))))
|
||
</span></span><span style="display:flex;"><span> (when target-workspace (<span style="color:#a6e22e">cons</span> buf target-workspace))))
|
||
</span></span></code></pre></div><p>And override <code>dap--go-to-stack-frame</code> to take that into account:</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="display:flex;"><span>(defun my/dap--go-to-stack-frame-override (debug-session stack-frame)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Make STACK-FRAME the active STACK-FRAME of DEBUG-SESSION."</span>
|
||
</span></span><span style="display:flex;"><span> (with-lsp-workspace (dap--debug-session-workspace debug-session)
|
||
</span></span><span style="display:flex;"><span> (when stack-frame
|
||
</span></span><span style="display:flex;"><span> (-let* (((&hash <span style="color:#e6db74">"line"</span> line <span style="color:#e6db74">"column"</span> column <span style="color:#e6db74">"name"</span> name) stack-frame)
|
||
</span></span><span style="display:flex;"><span> (path (dap--get-path-for-frame stack-frame)))
|
||
</span></span><span style="display:flex;"><span> (setf (dap--debug-session-active-frame debug-session) stack-frame)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; If we have a source file with path attached, open it and</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; position the point in the line/column referenced in the</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; stack trace.</span>
|
||
</span></span><span style="display:flex;"><span> (if (and path (<span style="color:#a6e22e">file-exists-p</span> path))
|
||
</span></span><span style="display:flex;"><span> (progn
|
||
</span></span><span style="display:flex;"><span> (let ((exwm-target (my/exwm-perspective-find-buffer path)))
|
||
</span></span><span style="display:flex;"><span> (if exwm-target
|
||
</span></span><span style="display:flex;"><span> (progn
|
||
</span></span><span style="display:flex;"><span> (unless (<span style="color:#a6e22e">=</span> (<span style="color:#a6e22e">cdr</span> exwm-target) exwm-workspace-current-index)
|
||
</span></span><span style="display:flex;"><span> (exwm-workspace-switch (<span style="color:#a6e22e">cdr</span> exwm-target)))
|
||
</span></span><span style="display:flex;"><span> (persp-switch-to-buffer (<span style="color:#a6e22e">car</span> exwm-target)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">select-window</span> (get-mru-window (<span style="color:#a6e22e">selected-frame</span>) <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (find-file path)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">goto-char</span> (<span style="color:#a6e22e">point-min</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">forward-line</span> (<span style="color:#a6e22e">1-</span> line))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">forward-char</span> column))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"No source code for %s. Cursor at %s:%s."</span> name line column))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">run-hook-with-args</span> <span style="color:#e6db74">'dap-stack-frame-changed-hook</span> debug-session)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'exwm</span>
|
||
</span></span><span style="display:flex;"><span> (with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>dap--go-to-stack-frame :override <span style="color:#a6e22e">#'</span>my/dap--go-to-stack-frame-override)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (advice-remove #'dap--go-to-stack-frame #'my/dap--go-to-stack-frame-override)</span>
|
||
</span></span></code></pre></div><h5 id="debug-templates">Debug templates</h5>
|
||
<p>Some debug templates I frequently use.</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="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
</span></span><span style="display:flex;"><span> (dap-register-debug-template
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Node::Nest.js"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">list</span> :type <span style="color:#e6db74">"node"</span>
|
||
</span></span><span style="display:flex;"><span> :request <span style="color:#e6db74">"attach"</span>
|
||
</span></span><span style="display:flex;"><span> :name <span style="color:#e6db74">"Node::Attach"</span>
|
||
</span></span><span style="display:flex;"><span> :port <span style="color:#ae81ff">9229</span>
|
||
</span></span><span style="display:flex;"><span> :outFiles [<span style="color:#e6db74">"${workspaceFolder}/dist/**/*.js"</span>]
|
||
</span></span><span style="display:flex;"><span> :sourceMaps <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :program <span style="color:#e6db74">"${workspaceFolder}/src/app.ts"</span>))
|
||
</span></span><span style="display:flex;"><span> (dap-register-debug-template
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Node::Babel"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">list</span> :type <span style="color:#e6db74">"node"</span>
|
||
</span></span><span style="display:flex;"><span> :request <span style="color:#e6db74">"attach"</span>
|
||
</span></span><span style="display:flex;"><span> :name <span style="color:#e6db74">"Node::Attach"</span>
|
||
</span></span><span style="display:flex;"><span> :port <span style="color:#ae81ff">9229</span>
|
||
</span></span><span style="display:flex;"><span> :program <span style="color:#e6db74">"${workspaceFolder}/dist/bin/www.js"</span>)))
|
||
</span></span></code></pre></div><h4 id="reformatter">Reformatter</h4>
|
||
<p>A general-purpose package to run formatters on files. While the most popular formatters are already packaged for Emacs, those that aren’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"><span style="display:flex;"><span>(use-package reformatter
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(defun my/set-smartparens-indent (mode)
|
||
</span></span><span style="display:flex;"><span> (sp-local-pair mode <span style="color:#e6db74">"{"</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">'</span>((<span style="color:#e6db74">"|| "</span> <span style="color:#e6db74">"SPC"</span>) (<span style="color:#e6db74">"||\n[i]"</span> <span style="color:#e6db74">"RET"</span>)))
|
||
</span></span><span style="display:flex;"><span> (sp-local-pair mode <span style="color:#e6db74">"["</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">'</span>((<span style="color:#e6db74">"|| "</span> <span style="color:#e6db74">"SPC"</span>) (<span style="color:#e6db74">"||\n[i]"</span> <span style="color:#e6db74">"RET"</span>)))
|
||
</span></span><span style="display:flex;"><span> (sp-local-pair mode <span style="color:#e6db74">"("</span> <span style="color:#66d9ef">nil</span> :post-handlers <span style="color:#f92672">'</span>((<span style="color:#e6db74">"|| "</span> <span style="color:#e6db74">"SPC"</span>) (<span style="color:#e6db74">"||\n[i]"</span> <span style="color:#e6db74">"RET"</span>))))
|
||
</span></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"><span style="display:flex;"><span>(defun my/set-flycheck-eslint()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Override flycheck checker with eslint."</span>
|
||
</span></span><span style="display:flex;"><span> (setq-local lsp-diagnostic-package :none)
|
||
</span></span><span style="display:flex;"><span> (setq-local flycheck-checker <span style="color:#e6db74">'javascript-eslint</span>))
|
||
</span></span></code></pre></div><h3 id="web-development">Web development</h3>
|
||
<p>Configs for various web development technologies I’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 & 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"><span style="display:flex;"><span>(use-package emmet-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :hook ((vue-html-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
</span></span><span style="display:flex;"><span> (svelte-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
</span></span><span style="display:flex;"><span> (web-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
</span></span><span style="display:flex;"><span> (html-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
</span></span><span style="display:flex;"><span> (css-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
</span></span><span style="display:flex;"><span> (scss-mode <span style="color:#f92672">.</span> emmet-mode))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (setq emmet-indent-after-insert nil)</span>
|
||
</span></span><span style="display:flex;"><span> (setq my/emmet-mmm-submodes <span style="color:#f92672">'</span>(vue-html-mode css-mode))
|
||
</span></span><span style="display:flex;"><span> (defun my/emmet-or-tab (<span style="color:#66d9ef">&optional</span> arg)
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (if (and
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'mmm-current-submode</span>)
|
||
</span></span><span style="display:flex;"><span> mmm-current-submode
|
||
</span></span><span style="display:flex;"><span> (not (<span style="color:#a6e22e">member</span> mmm-current-submode my/emmet-mmm-submodes)))
|
||
</span></span><span style="display:flex;"><span> (indent-for-tab-command arg)
|
||
</span></span><span style="display:flex;"><span> (or (emmet-expand-line arg)
|
||
</span></span><span style="display:flex;"><span> (emmet-go-to-edit-point <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (indent-for-tab-command arg))))
|
||
</span></span><span style="display:flex;"><span> (general-imap :keymaps <span style="color:#e6db74">'emmet-mode-keymap</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"TAB"</span> <span style="color:#e6db74">'my/emmet-or-tab</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<backtab>"</span> <span style="color:#e6db74">'emmet-prev-edit-point</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package prettier
|
||
</span></span><span style="display:flex;"><span> :commands (prettier-prettify)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(js-mode-map web-mode-map typescript-mode-map vue-mode-map svelte-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"rr"</span> <span style="color:#a6e22e">#'</span>prettier-prettify))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package typescript-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.ts\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>rainbow-delimiters-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'typescript-mode</span>))
|
||
</span></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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'js-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'js-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span><span style="display:flex;"><span>(my/set-smartparens-indent <span style="color:#e6db74">'js-mode</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package jest-test-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :hook ((typescript-mode <span style="color:#f92672">.</span> jest-test-mode)
|
||
</span></span><span style="display:flex;"><span> (js-mode <span style="color:#f92672">.</span> jest-test-mode))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'jest-test-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"t"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'jest-test-run-at-point</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'jest-test-run</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'jest-test-run-all-tests</span>))
|
||
</span></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"><span style="display:flex;"><span>(defun my/jest-test-run-at-point-copy ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Run the top level describe block of the current buffer's point."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((filename (jest-test-find-file))
|
||
</span></span><span style="display:flex;"><span> (example (jest-test-example-at-point)))
|
||
</span></span><span style="display:flex;"><span> (if (and filename example)
|
||
</span></span><span style="display:flex;"><span> (jest-test-from-project-directory filename
|
||
</span></span><span style="display:flex;"><span> (let ((jest-test-options (seq-concatenate <span style="color:#e6db74">'list</span> jest-test-options (<span style="color:#a6e22e">list</span> <span style="color:#e6db74">"-t"</span> example))))
|
||
</span></span><span style="display:flex;"><span> (kill-new (jest-test-command filename))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> jest-test-not-found-message))))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package web-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (web-mode)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.svelte\\'"</span> <span style="color:#f92672">.</span> web-mode))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.vue\\'"</span> <span style="color:#f92672">.</span> web-mode))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'hs-minor-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'web-mode</span>))
|
||
</span></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"><span style="display:flex;"><span>(setq my/web-mode-lsp-extensions
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">".svelte"</span> eos)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(rx <span style="color:#e6db74">".vue"</span> eos)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/web-mode-lsp ()
|
||
</span></span><span style="display:flex;"><span> (when (seq-some
|
||
</span></span><span style="display:flex;"><span> (lambda (regex) (string-match-p regex (<span style="color:#a6e22e">buffer-name</span>)))
|
||
</span></span><span style="display:flex;"><span> my/web-mode-lsp-extensions)
|
||
</span></span><span style="display:flex;"><span> (lsp-deferred)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#a6e22e">#'</span>my/web-mode-lsp)
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/web-mode-vue-setup (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (when (string-match-p (rx <span style="color:#e6db74">".vue"</span> eos) (<span style="color:#a6e22e">buffer-name</span>))
|
||
</span></span><span style="display:flex;"><span> (setq-local web-mode-script-padding <span style="color:#ae81ff">0</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'my/web-mode-vue-setup</span>)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'editorconfig-after-apply-functions</span> <span style="color:#e6db74">'my/web-mode-vue-setup</span>)
|
||
</span></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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'scss-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'scss-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span><span style="display:flex;"><span>(my/set-smartparens-indent <span style="color:#e6db74">'scss-mode</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package php-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.php\\'"</span>)
|
||
</span></span></code></pre></div><h3 id="latex">LaTeX</h3>
|
||
<h4 id="auctex">AUCTeX</h4>
|
||
<p>The best LaTeX editing environment I’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"><span style="display:flex;"><span>(use-package tex
|
||
</span></span><span style="display:flex;"><span> :straight auctex
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-auto-save <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-parse-self <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (TeX-PDF-mode)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Use XeLaTeX & stuff</span>
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-engine <span style="color:#e6db74">'xetex</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-command-extra-options <span style="color:#e6db74">"-shell-escape"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-source-correlate-method <span style="color:#e6db74">'synctex</span>)
|
||
</span></span><span style="display:flex;"><span> (TeX-source-correlate-mode)
|
||
</span></span><span style="display:flex;"><span> (setq-default TeX-source-correlate-start-server <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-default LaTeX-math-menu-unicode <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (setq-default font-latex-fontify-sectioning <span style="color:#ae81ff">1.3</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Scale preview for my DPI</span>
|
||
</span></span><span style="display:flex;"><span> (setq-default preview-scale-function <span style="color:#ae81ff">1.4</span>)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'tex--prettify-symbols-alist</span>)
|
||
</span></span><span style="display:flex;"><span> (assoc-delete-all <span style="color:#e6db74">"--"</span> tex--prettify-symbols-alist)
|
||
</span></span><span style="display:flex;"><span> (assoc-delete-all <span style="color:#e6db74">"---"</span> tex--prettify-symbols-alist))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (TeX-fold-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (outline-minor-mode)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'TeX-view-program-selection</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(output-pdf <span style="color:#e6db74">"Zathura"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Do not run lsp within templated TeX files</span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (unless (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"\.hogan\.tex$"</span> (<span style="color:#a6e22e">buffer-name</span>))
|
||
</span></span><span style="display:flex;"><span> (lsp))
|
||
</span></span><span style="display:flex;"><span> (setq-local lsp-diagnostic-package :none)
|
||
</span></span><span style="display:flex;"><span> (setq-local flycheck-checker <span style="color:#e6db74">'tex-chktex</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>rainbow-delimiters-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>prettify-symbols-mode)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'LaTeX-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'smartparens-latex</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (general-nmap
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(LaTeX-mode-map latex-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'TeX-command-run-all</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c t"</span> <span style="color:#e6db74">'orgtbl-mode</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <<init-greek-latex-snippets>>
|
||
</span></span><span style="display:flex;"><span> <<init-english-latex-snippets>>
|
||
</span></span><span style="display:flex;"><span> <<init-math-latex-snippets>>
|
||
</span></span><span style="display:flex;"><span> <<init-section-latex-snippets>>)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package ivy-bibtex
|
||
</span></span><span style="display:flex;"><span> :commands (ivy-bibtex)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"fB"</span> <span style="color:#e6db74">'ivy-bibtex</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'bibtex-mode</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
</span></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"><span style="display:flex;"><span>(defun my/list-sty ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">reverse</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">sort</span>
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (file) (if (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">".*\.sty$"</span> file) <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">directory-files</span>
|
||
</span></span><span style="display:flex;"><span> (seq-some
|
||
</span></span><span style="display:flex;"><span> (lambda (dir)
|
||
</span></span><span style="display:flex;"><span> (if (and
|
||
</span></span><span style="display:flex;"><span> (f-directory-p dir)
|
||
</span></span><span style="display:flex;"><span> (seq-some
|
||
</span></span><span style="display:flex;"><span> (lambda (file) (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">".*\.sty$"</span> file))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">directory-files</span> dir))
|
||
</span></span><span style="display:flex;"><span> ) dir <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">list</span> <span style="color:#e6db74">"./styles"</span> <span style="color:#e6db74">"../styles/"</span> <span style="color:#e6db74">"."</span> <span style="color:#e6db74">".."</span>)) :full))
|
||
</span></span><span style="display:flex;"><span> (lambda (f1 f2)
|
||
</span></span><span style="display:flex;"><span> (let ((f1b (file-name-base f1))
|
||
</span></span><span style="display:flex;"><span> (f1b (file-name-base f2)))
|
||
</span></span><span style="display:flex;"><span> (cond
|
||
</span></span><span style="display:flex;"><span> ((string-match-p <span style="color:#e6db74">".*BibTex"</span> f1) <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> ((and (string-match-p <span style="color:#e6db74">".*Locale"</span> f1) (not (string-match-p <span style="color:#e6db74">".*BibTex"</span> f2))) <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> ((string-match-p <span style="color:#e6db74">".*Preamble"</span> f2) <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> (<span style="color:#a6e22e">string-lessp</span> f1 f2))))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/import-sty ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'concat</span>
|
||
</span></span><span style="display:flex;"><span> (cl-mapcar
|
||
</span></span><span style="display:flex;"><span> (lambda (file) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"\\usepackage{"</span> (file-name-sans-extension (file-relative-name file default-directory)) <span style="color:#e6db74">"}\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (my/list-sty)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/import-sty-org ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'concat</span>
|
||
</span></span><span style="display:flex;"><span> (cl-mapcar
|
||
</span></span><span style="display:flex;"><span> (lambda (file) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+LATEX_HEADER: \\usepackage{"</span> (file-name-sans-extension (file-relative-name file default-directory)) <span style="color:#e6db74">"}\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (my/list-sty)))))
|
||
</span></span></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’s faster & 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"><span style="display:flex;"><span>(setq my/greek-alphabet
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"a"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\alpha"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"b"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\beta"</span> )
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"g"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\gamma"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"d"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\delta"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"e"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\epsilon"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"z"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\zeta"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"h"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\eta"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"o"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\theta"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"i"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\iota"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"k"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\kappa"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"l"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\lambda"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"m"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\mu"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"n"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\nu"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"x"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\xi"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"p"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\pi"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"r"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\rho"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"s"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sigma"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"t"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\tau"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"u"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\upsilon"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"f"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\phi"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"c"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\chi"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"v"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\psi"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"g"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\omega"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/latex-greek-prefix <span style="color:#e6db74">"'"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; The same for capitalized letters</span>
|
||
</span></span><span style="display:flex;"><span>(dolist (elem my/greek-alphabet)
|
||
</span></span><span style="display:flex;"><span> (let ((key (<span style="color:#a6e22e">car</span> elem))
|
||
</span></span><span style="display:flex;"><span> (value (<span style="color:#a6e22e">cdr</span> elem)))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">string-equal</span> key (<span style="color:#a6e22e">downcase</span> key))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'my/greek-alphabet</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cons</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">capitalize</span> (<span style="color:#a6e22e">car</span> elem))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><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></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">2</span>)))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(yas-define-snippets
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'latex-mode</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (elem)
|
||
</span></span><span style="display:flex;"><span> (<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">"Greek letter "</span> (<span style="color:#a6e22e">car</span> elem))))
|
||
</span></span><span style="display:flex;"><span> my/greek-alphabet))
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/english-alphabet
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"a"</span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">"c"</span> <span style="color:#e6db74">"d"</span> <span style="color:#e6db74">"e"</span> <span style="color:#e6db74">"f"</span> <span style="color:#e6db74">"g"</span> <span style="color:#e6db74">"h"</span> <span style="color:#e6db74">"i"</span> <span style="color:#e6db74">"j"</span> <span style="color:#e6db74">"k"</span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">"m"</span> <span style="color:#e6db74">"n"</span> <span style="color:#e6db74">"o"</span> <span style="color:#e6db74">"p"</span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">"r"</span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">"t"</span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">"v"</span> <span style="color:#e6db74">"w"</span> <span style="color:#e6db74">"x"</span> <span style="color:#e6db74">"y"</span> <span style="color:#e6db74">"z"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(dolist (elem my/english-alphabet)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">string-equal</span> elem (<span style="color:#a6e22e">downcase</span> elem))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'my/english-alphabet</span> (<span style="color:#a6e22e">upcase</span> elem))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/latex-mathbb-prefix <span style="color:#e6db74">"`"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(yas-define-snippets
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'latex-mode</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (elem)
|
||
</span></span><span style="display:flex;"><span> (<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">"\\mathbb{"</span> elem <span style="color:#e6db74">"}"</span>) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Mathbb letter "</span> elem)))
|
||
</span></span><span style="display:flex;"><span> my/english-alphabet))
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/latex-math-symbols
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"x"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\times"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"."</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cdot"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"v"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\forall"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"s"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sum_{$1}^{$2}$0"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"p"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\prod_{$1}^{$2}$0"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"d"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\partial"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"e"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\exists"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"i"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\int_{$1}^{$2}$0"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"c"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cap"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"u"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cup"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"0"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\emptyset"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"^"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\widehat{$1}$0"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"_"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\overline{$1}$0"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"~"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sim"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"|"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\mid"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"_|"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\perp"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/latex-math-prefix <span style="color:#e6db74">";"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(yas-define-snippets
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'latex-mode</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (elem)
|
||
</span></span><span style="display:flex;"><span> (let ((key (<span style="color:#a6e22e">car</span> elem))
|
||
</span></span><span style="display:flex;"><span> (value (<span style="color:#a6e22e">cdr</span> elem)))
|
||
</span></span><span style="display:flex;"><span> (<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">"Math symbol "</span> value))))
|
||
</span></span><span style="display:flex;"><span> my/latex-math-symbols))
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/latex-section-snippets
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"ch"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\chapter{$1}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"sec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section{$1}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ssec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection{$1}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"sssec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection{$1}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"par"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\paragraph{$1}}"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/latex-section-snippets
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (elem)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">car</span> elem)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">cdr</span> elem)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(progn
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"[a-z]+"</span> (<span style="color:#a6e22e">cdr</span> elem))
|
||
</span></span><span style="display:flex;"><span> (match-string <span style="color:#ae81ff">0</span> (<span style="color:#a6e22e">cdr</span> elem)))))
|
||
</span></span><span style="display:flex;"><span> my/latex-section-snippets))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(dolist (elem my/latex-section-snippets)
|
||
</span></span><span style="display:flex;"><span> (let* ((key (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> elem))
|
||
</span></span><span style="display:flex;"><span> (value (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem))
|
||
</span></span><span style="display:flex;"><span> (desc (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> elem))
|
||
</span></span><span style="display:flex;"><span> (star-index (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"\{\$1\}"</span> value)))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'my/latex-section-snippets</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">"*"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> star-index)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"*"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> value star-index))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">" with *"</span>)))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'my/latex-section-snippets</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">"l"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> value <span style="color:#e6db74">"%\n\\label{sec:$2}"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">" with label"</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(dolist (elem my/latex-section-snippets)
|
||
</span></span><span style="display:flex;"><span> (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">"\n$0"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(yas-define-snippets
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'latex-mode</span>
|
||
</span></span><span style="display:flex;"><span> my/latex-section-snippets)
|
||
</span></span></code></pre></div><h3 id="other-markup-and-natural-languages">Other markup & natural 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"><span style="display:flex;"><span>(use-package markdown-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.md\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq markdown-command
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"pandoc"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">" --from=markdown --to=html"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">" --standalone --mathjax --highlight-style=pygments"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">" --css=pandoc.css"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">" --quiet"</span>
|
||
</span></span><span style="display:flex;"><span> ))
|
||
</span></span><span style="display:flex;"><span> (setq markdown-live-preview-delete-export <span style="color:#e6db74">'delete-on-export</span>)
|
||
</span></span><span style="display:flex;"><span> (setq markdown-asymmetric-header <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq markdown-open-command <span style="color:#e6db74">"/home/pavel/bin/scripts/chromium-sep"</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'markdown-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'markdown-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<left>"</span> <span style="color:#e6db74">'markdown-promote</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<right>"</span> <span style="color:#e6db74">'markdown-demote</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (use-package livedown</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :straight (:host github :repo "shime/emacs-livedown")</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :commands livedown-preview</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; :config</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (setq livedown-browser "qutebrowser"))</span>
|
||
</span></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"><span style="display:flex;"><span>(use-package plantuml-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"(\\.\\(plantuml?\\|uml\\|puml\\)\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq plantuml-executable-path <span style="color:#e6db74">"/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq plantuml-default-exec-mode <span style="color:#e6db74">'executable</span>)
|
||
</span></span><span style="display:flex;"><span> (setq plantuml-indent-level <span style="color:#ae81ff">2</span>)
|
||
</span></span><span style="display:flex;"><span> (setq my/plantuml-indent-regexp-return <span style="color:#e6db74">"^\s*return\s+.+$"</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'plantuml-indent-regexp-end</span>
|
||
</span></span><span style="display:flex;"><span> my/plantuml-indent-regexp-return)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.plantuml\\'"</span> <span style="color:#f92672">.</span> plantuml-mode))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.uml\\'"</span> <span style="color:#f92672">.</span> plantuml-mode))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'plantuml-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-nmap
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'plantuml-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'plantuml-preview</span>)
|
||
</span></span></code></pre></div><h4 id="subtitles">Subtitles</h4>
|
||
<p>A major mode to work with subtitles.</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="display:flex;"><span>(use-package subed
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"rndusr/subed"</span> :files (<span style="color:#e6db74">"subed/*.el"</span>) :build (:not native-compile))
|
||
</span></span><span style="display:flex;"><span> :mode (rx (| <span style="color:#e6db74">"srt"</span> <span style="color:#e6db74">"vtt"</span> <span style="color:#e6db74">"ass"</span>) eos))
|
||
</span></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"><span style="display:flex;"><span>(use-package langtool
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (langtool-check)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq langtool-language-tool-server-jar <span style="color:#e6db74">"/home/pavel/bin/LanguageTool-5.4/languagetool-server.jar"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq langtool-mother-tongue <span style="color:#e6db74">"ru"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq langtool-default-language <span style="color:#e6db74">"en-US"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"L"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"languagetool"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'langtool-check</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'langtool-server-stop</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'langtool-check-done</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"n"</span> <span style="color:#e6db74">'langtool-goto-next-error</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'langtool-goto-previous-error</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'langtool-correct-buffer</span>)
|
||
</span></span></code></pre></div><h3 id="lisp">Lisp</h3>
|
||
<figure><img src="./dot-imgs/lisp_cycles.png"/>
|
||
</figure>
|
||
|
||
<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"><span style="display:flex;"><span>(use-package lispy
|
||
</span></span><span style="display:flex;"><span> :commands (lispy-mode)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package lispyville
|
||
</span></span><span style="display:flex;"><span> :hook (lispy-mode <span style="color:#f92672">.</span> lispyville-mode)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(sp-with-modes sp-lisp-modes
|
||
</span></span><span style="display:flex;"><span> (sp-local-pair <span style="color:#e6db74">"'"</span> <span style="color:#66d9ef">nil</span> :actions <span style="color:#66d9ef">nil</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package flycheck-package
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after flycheck
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (flycheck-package-setup))
|
||
</span></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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode)</span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package slime
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (slime)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq inferior-lisp-program <span style="color:#e6db74">"sbcl"</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'slime-repl-mode</span> <span style="color:#e6db74">'smartparens-mode</span>))
|
||
</span></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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode)</span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package clojure-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.clj[sc]?\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (add-hook 'clojure-mode-hook #'smartparens-strict-mode)</span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'clojure-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'clojure-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package cider
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.clj[sc]?\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package hy-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.hy\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'hy-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'hy-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package geiser
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/lowpower)
|
||
</span></span><span style="display:flex;"><span> :commands (geiser run-geiser)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq geiser-default-implementation <span style="color:#e6db74">'guile</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package geiser-guile
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after geiser)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'scheme-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'scheme-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package clips-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.cl\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'clips-mode</span> <span style="color:#e6db74">'lispy-mode</span>))
|
||
</span></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’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"><span style="display:flex;"><span>(setq my/pipenv-python-alist <span style="color:#f92672">'</span>())
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/get-pipenv-python ()
|
||
</span></span><span style="display:flex;"><span> (let ((default-directory (projectile-project-root)))
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">"Pipfile"</span>)
|
||
</span></span><span style="display:flex;"><span> (let ((asc (<span style="color:#a6e22e">assoc</span> default-directory my/pipenv-python-alist)))
|
||
</span></span><span style="display:flex;"><span> (if asc
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span> asc)
|
||
</span></span><span style="display:flex;"><span> (let ((python-executable
|
||
</span></span><span style="display:flex;"><span> (string-trim (shell-command-to-string <span style="color:#e6db74">"PIPENV_IGNORE_VIRTUALENVS=1 pipenv run which python 2>/dev/null"</span>))))
|
||
</span></span><span style="display:flex;"><span> (if (string-match-p <span style="color:#e6db74">".*not found.*"</span> python-executable)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Pipfile found, but not pipenv executable!"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Found pipenv python: %s"</span> python-executable))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'my/pipenv-python-alist</span> (<span style="color:#a6e22e">cons</span> default-directory python-executable))
|
||
</span></span><span style="display:flex;"><span> python-executable))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"python"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package lsp-pyright
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> :hook (python-mode <span style="color:#f92672">.</span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'lsp-pyright</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local lsp-pyright-python-executable-cmd (my/get-pipenv-python))
|
||
</span></span><span style="display:flex;"><span> (lsp))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span></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 & manages virtualenvs and stores data in <code>Pipfile</code> and <code>Pipfile.lock</code> (like npm’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"><span style="display:flex;"><span>(use-package pipenv
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :hook (python-mode <span style="color:#f92672">.</span> pipenv-mode)
|
||
</span></span><span style="display:flex;"><span> :if (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq
|
||
</span></span><span style="display:flex;"><span> pipenv-projectile-after-switch-function
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'</span>pipenv-projectile-after-switch-extended))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package yapfify
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"JorisE/yapfify"</span> :host github)
|
||
</span></span><span style="display:flex;"><span> :commands (yapfify-region
|
||
</span></span><span style="display:flex;"><span> yapfify-buffer
|
||
</span></span><span style="display:flex;"><span> yapfify-region-or-buffer
|
||
</span></span><span style="display:flex;"><span> yapf-mode))
|
||
</span></span></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="display:flex;"><span><span style="color:#66d9ef">[style]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">based_on_style</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">facebook</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">column_limit</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">80</span>
|
||
</span></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"><span style="display:flex;"><span>(use-package py-isort
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (py-isort-buffer py-isort-region))
|
||
</span></span></code></pre></div><p>The following binding calls yapf & 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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'python-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"rr"</span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (unless (and (<span style="color:#a6e22e">fboundp</span> <span style="color:#a6e22e">#'</span>org-src-edit-buffer-p) (org-src-edit-buffer-p))
|
||
</span></span><span style="display:flex;"><span> (py-isort-buffer))
|
||
</span></span><span style="display:flex;"><span> (yapfify-buffer)))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package sphinx-doc
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :hook (python-mode <span style="color:#f92672">.</span> sphinx-doc-mode)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'sphinx-doc-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"rd"</span> <span style="color:#e6db74">'sphinx-doc</span>))
|
||
</span></span></code></pre></div><h4 id="pytest">pytest</h4>
|
||
<p><a href="https://docs.pytest.org/en/6.2.x/">pytest</a> is a 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"><span style="display:flex;"><span>(defun my/set-pipenv-pytest ()
|
||
</span></span><span style="display:flex;"><span> (setq-local
|
||
</span></span><span style="display:flex;"><span> python-pytest-executable
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> (my/get-pipenv-python) <span style="color:#e6db74">" -m pytest"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package python-pytest
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (python-pytest-dispatch)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'python-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"t"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'python-pytest-dispatch</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> <<override-pytest-run>>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>my/set-pipenv-pytest)
|
||
</span></span><span style="display:flex;"><span> (when (derived-mode-p <span style="color:#e6db74">'python-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (my/set-pipenv-pytest)))
|
||
</span></span></code></pre></div><h5 id="fix-comint-buffer-width">Fix comint buffer width</h5>
|
||
<p>For some reason, the default comint output width is way too large.</p>
|
||
<p>To fix that, I’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"><span style="display:flex;"><span>(cl-defun python-pytest--run-as-comint (<span style="color:#66d9ef">&key</span> command)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Run a pytest comint session for COMMAND."</span>
|
||
</span></span><span style="display:flex;"><span> (let* ((buffer (python-pytest--get-buffer))
|
||
</span></span><span style="display:flex;"><span> (process (<span style="color:#a6e22e">get-buffer-process</span> buffer)))
|
||
</span></span><span style="display:flex;"><span> (with-current-buffer buffer
|
||
</span></span><span style="display:flex;"><span> (when (comint-check-proc buffer)
|
||
</span></span><span style="display:flex;"><span> (unless (or compilation-always-kill
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">yes-or-no-p</span> <span style="color:#e6db74">"Kill running pytest process?"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">user-error</span> <span style="color:#e6db74">"Aborting; pytest still running"</span>)))
|
||
</span></span><span style="display:flex;"><span> (when process
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">delete-process</span> process))
|
||
</span></span><span style="display:flex;"><span> (let ((inhibit-read-only <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">erase-buffer</span>))
|
||
</span></span><span style="display:flex;"><span> (unless (<span style="color:#a6e22e">eq</span> major-mode <span style="color:#e6db74">'python-pytest-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (python-pytest-mode))
|
||
</span></span><span style="display:flex;"><span> (compilation-forget-errors)
|
||
</span></span><span style="display:flex;"><span> (display-buffer buffer)
|
||
</span></span><span style="display:flex;"><span> (setq command (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"export COLUMNS=%s; %s"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">-</span> (window-width (<span style="color:#a6e22e">get-buffer-window</span> buffer)) <span style="color:#ae81ff">5</span>)
|
||
</span></span><span style="display:flex;"><span> command))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"cwd: %s\ncmd: %s\n\n"</span> default-directory command))
|
||
</span></span><span style="display:flex;"><span> (setq python-pytest--current-command command)
|
||
</span></span><span style="display:flex;"><span> (when python-pytest-pdb-track
|
||
</span></span><span style="display:flex;"><span> (add-hook
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'comint-output-filter-functions</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'python-pdbtrack-comint-output-filter-function</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">'python-pytest-setup-hook</span>)
|
||
</span></span><span style="display:flex;"><span> (make-comint-in-buffer <span style="color:#e6db74">"pytest"</span> buffer <span style="color:#e6db74">"bash"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"-c"</span> command)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">'python-pytest-started-hook</span>)
|
||
</span></span><span style="display:flex;"><span> (setq process (<span style="color:#a6e22e">get-buffer-process</span> buffer))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">set-process-sentinel</span> process <span style="color:#a6e22e">#'</span>python-pytest--process-sentinel))))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package code-cells
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (code-cells-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/tensorboard-buffer <span style="color:#e6db74">"TensorBoard-out"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/tensorboard ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">start-process</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"tensorboard"</span>
|
||
</span></span><span style="display:flex;"><span> my/tensorboard-buffer
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"tensorboard"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"serve"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"--logdir"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">car</span> (find-file-read-args <span style="color:#e6db74">"Directory: "</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span> (display-buffer my/tensorboard-buffer))
|
||
</span></span></code></pre></div><h3 id="data-serialization">Data serialization</h3>
|
||
<h4 id="json">JSON</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="display:flex;"><span>(use-package json-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.json\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'json-mode</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'json-mode</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'json-mode</span>))
|
||
</span></span></code></pre></div><h4 id="csv">CSV</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="display:flex;"><span>(use-package csv-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.csv\\'"</span>)
|
||
</span></span></code></pre></div><h4 id="yaml">YAML</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="display:flex;"><span>(use-package yaml-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.yml\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'yaml-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'yaml-mode-hook</span> <span style="color:#e6db74">'highlight-indent-guides-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.yml\\'"</span> <span style="color:#f92672">.</span> yaml-mode)))
|
||
</span></span></code></pre></div><h3 id="configuration">Configuration</h3>
|
||
<h4 id="dot-env">.env</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="display:flex;"><span>(use-package dotenv-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.env\\..*\\'"</span>)
|
||
</span></span></code></pre></div><h4 id="dot-gitignore">.gitignore</h4>
|
||
<p>A package to quickly create <code>.gitignore</code> 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"><span style="display:flex;"><span>(use-package gitignore-templates
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (gitignore-templates-insert
|
||
</span></span><span style="display:flex;"><span> gitignore-templates-new-file))
|
||
</span></span></code></pre></div><h4 id="docker">Docker</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="display:flex;"><span>(use-package dockerfile-mode
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"Dockerfile\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'dockerfile-mode</span> <span style="color:#e6db74">'smartparens-mode</span>))
|
||
</span></span></code></pre></div><h4 id="crontab">crontab</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="display:flex;"><span>(use-package crontab-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h3 id="shell">Shell</h3>
|
||
<h4 id="sh">sh</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="display:flex;"><span>(add-hook <span style="color:#e6db74">'sh-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span></code></pre></div><h4 id="fish">fish</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="display:flex;"><span>(use-package fish-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.fish\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'fish-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package lsp-java
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (lsp)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq lsp-java-jdt-download-url <span style="color:#e6db74">"https://download.eclipse.org/jdtls/milestones/0.57.0/jdt-language-server-0.57.0-202006172108.tar.gz"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'java-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (add-hook 'java-mode-hook #'hs-minor-mode)</span>
|
||
</span></span><span style="display:flex;"><span>(my/set-smartparens-indent <span style="color:#e6db74">'java-mode</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package go-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.go\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'go-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'go-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'go-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package csharp-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.cs\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq lsp-csharp-server-path (executable-find <span style="color:#e6db74">"omnisharp-wrapper"</span>))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'csharp-mode-hook</span> <span style="color:#a6e22e">#'</span>csharp-tree-sitter-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'csharp-tree-sitter-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'csharp-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'csharp-tree-sitter-mode</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package csproj-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.csproj\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'csproj-mode</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package haskell-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.hs\\'"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package lsp-haskell
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (lsp haskell-mode))
|
||
</span></span></code></pre></div><h3 id="nix">nix</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"><span style="display:flex;"><span>(use-package nix-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.nix\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'nix-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</span></span><span style="display:flex;"><span> (my/set-smartparens-indent <span style="color:#e6db74">'nix-mode</span>))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package lua-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode <span style="color:#e6db74">"\\.lua\\'"</span>
|
||
</span></span><span style="display:flex;"><span> :hook (lua-mode <span style="color:#f92672">.</span> smartparens-mode))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my/set-smartparens-indent <span style="color:#e6db74">'lua-mode</span>)
|
||
</span></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’ve made a simple function to switch dialects because I often alternate between them.</p>
|
||
<p>So far I didn’t find a nice SQL client for Emacs, but I occasionally run SQL queries in Org Mode, so this quite 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"><span style="display:flex;"><span>(setq my/sqlformatter-dialect-choice
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"db2"</span> <span style="color:#e6db74">"mariadb"</span> <span style="color:#e6db74">"mysql"</span> <span style="color:#e6db74">"n1ql"</span> <span style="color:#e6db74">"plsql"</span> <span style="color:#e6db74">"postgresql"</span> <span style="color:#e6db74">"redshift"</span> <span style="color:#e6db74">"spark"</span> <span style="color:#e6db74">"sql"</span> <span style="color:#e6db74">"tsql"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/sqlformatter-dialect <span style="color:#e6db74">"postgresql"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/sqlformatter-set-dialect ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Set dialect for sql-formatter"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (setq my/sqlformatter-dialect
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Dialect: "</span> my/sqlformatter-dialect-choice)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(reformatter-define sqlformat
|
||
</span></span><span style="display:flex;"><span> :program (executable-find <span style="color:#e6db74">"sql-formatter"</span>)
|
||
</span></span><span style="display:flex;"><span> :args <span style="color:#f92672">`</span>(<span style="color:#e6db74">"-l"</span> <span style="color:#f92672">,</span>my/sqlformatter-dialect, <span style="color:#e6db74">"-u"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(sql-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"rr"</span> <span style="color:#a6e22e">#'</span>sqlformat-buffer)
|
||
</span></span></code></pre></div><h3 id="sparql">SPARQL</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"><span style="display:flex;"><span>(use-package sparql-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h2 id="org-mode">Org Mode</h2>
|
||
<p><strong>Org mode</strong> is a tool that leverages plain-text files for various tasks, like making notes, literate programming, task management, etc.</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 & 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"><span style="display:flex;"><span>(use-package org
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq org-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Documents/org-mode"</span>))
|
||
</span></span><span style="display:flex;"><span> (unless (<span style="color:#a6e22e">file-exists-p</span> org-directory)
|
||
</span></span><span style="display:flex;"><span> (mkdir org-directory <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq org-startup-indented <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-return-follows-link <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-src-tab-acts-natively <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-agenda-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (visual-line-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (toggle-truncate-lines <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (rainbow-delimiters-mode <span style="color:#ae81ff">-1</span>)))
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'org-tempo</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-structure-template-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"el"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"src emacs-lisp"</span>))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-structure-template-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"py"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"src python"</span>))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-structure-template-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"sq"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"src sql"</span>))
|
||
</span></span><span style="display:flex;"><span> <<org-crypt-setup>>
|
||
</span></span><span style="display:flex;"><span> (unless my/is-termux
|
||
</span></span><span style="display:flex;"><span> <<org-lang-setup>>)
|
||
</span></span><span style="display:flex;"><span> <<org-ui-setup>>
|
||
</span></span><span style="display:flex;"><span> <<org-keys-setup>>
|
||
</span></span><span style="display:flex;"><span> <<org-productivity-setup>>)
|
||
</span></span></code></pre></div><h4 id="encryption">Encryption</h4>
|
||
<p>Setting up <code>org-crypt</code> to encrypt a part 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"><span style="display:flex;"><span>(require <span style="color:#e6db74">'org-crypt</span>)
|
||
</span></span><span style="display:flex;"><span>(org-crypt-use-before-save-magic)
|
||
</span></span><span style="display:flex;"><span>(setq org-tags-exclude-from-inheritance (quote (<span style="color:#e6db74">"crypt"</span>)))
|
||
</span></span><span style="display:flex;"><span>(setq org-crypt-key <span style="color:#e6db74">"C1EC867E478472439CC82410DE004F32AFA00205"</span>)
|
||
</span></span></code></pre></div><p>This enables encryption for Org segments which are tagged <code>:crypt:</code>.</p>
|
||
<p>Another way to encrypt org files is to save them with extension <code>.org.gpg</code>. That way by default epa always prompts for a key, which is not what I want when there is in fact only one key to select. So I make 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"><span style="display:flex;"><span>(defun my/epa--select-keys-around (fun prompt keys)
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">=</span> (seq-length keys) <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> keys
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">funcall</span> fun prompt keys)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'epa</span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>epa--select-keys :around <span style="color:#a6e22e">#'</span>my/epa--select-keys-around))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq epa-file-encrypt-to <span style="color:#f92672">'</span>(<span style="color:#e6db74">"DE004F32AFA00205"</span>))
|
||
</span></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>
|
||
<p>Excluding <code>org-contacts</code> from here because byte compilation breaks it for some reason.</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="display:flex;"><span>(use-package org-contrib
|
||
</span></span><span style="display:flex;"><span> :straight (org-contrib
|
||
</span></span><span style="display:flex;"><span> :type git
|
||
</span></span><span style="display:flex;"><span> :repo <span style="color:#e6db74">"https://git.sr.ht/~bzg/org-contrib"</span>
|
||
</span></span><span style="display:flex;"><span> :files (:defaults (:exclude <span style="color:#e6db74">"lisp/org-contacts.el"</span>))
|
||
</span></span><span style="display:flex;"><span> :build <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'ox-extra</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'ol-notmuch</span>)
|
||
</span></span><span style="display:flex;"><span> (ox-extras-activate <span style="color:#f92672">'</span>(latex-header-blocks ignore-headlines)))
|
||
</span></span></code></pre></div><h3 id="integration-with-evil">Integration with evil</h3>
|
||
<p>A package to add more evil-mode keybindings to 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"><span style="display:flex;"><span>(use-package evil-org
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :hook (org-mode <span style="color:#f92672">.</span> evil-org-mode)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'evil-org-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (evil-org-set-key-theme <span style="color:#f92672">'</span>(navigation <span style="color:#a6e22e">insert</span> textobjects additional calendar todo))))
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'evil-emacs-state-modes</span> <span style="color:#e6db74">'org-agenda-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'evil-org-agenda</span>)
|
||
</span></span><span style="display:flex;"><span> (evil-org-agenda-set-keys))
|
||
</span></span></code></pre></div><h3 id="literate-programing">Literate programing</h3>
|
||
<h4 id="python-and-jupyter">Python & 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"><span style="display:flex;"><span>(use-package jupyter
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :if (not my/is-termux)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ar"</span> <span style="color:#e6db74">'jupyter-run-repl</span>))
|
||
</span></span></code></pre></div><p>Refresh kernelspecs.</p>
|
||
<p>Kernelspecs by default are hashed, so even switching Anaconda environments doesn’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"><span style="display:flex;"><span>(defun my/jupyter-refresh-kernelspecs ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Refresh Jupyter kernelspecs"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (jupyter-available-kernelspecs <span style="color:#66d9ef">t</span>))
|
||
</span></span></code></pre></div><p>Also, if some kernel wasn’t present at the moment of the load of <code>emacs-jupyter</code>, it won’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’t been launched in this environment, I wouldn’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"><span style="display:flex;"><span>(defun my/jupyter-refesh-langs ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Refresh Jupyter languages"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (org-babel-jupyter-aliases-from-kernelspecs <span style="color:#66d9ef">t</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package ob-hy
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq my/org-view-html-tmp-dir <span style="color:#e6db74">"/tmp/org-html-preview/"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package f
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/org-view-html ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((elem (org-element-at-point))
|
||
</span></span><span style="display:flex;"><span> (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">".html"</span>)))
|
||
</span></span><span style="display:flex;"><span> (cond
|
||
</span></span><span style="display:flex;"><span> ((not (<span style="color:#a6e22e">eq</span> <span style="color:#e6db74">'export-block</span> (<span style="color:#a6e22e">car</span> elem)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Not in an export block!"</span>))
|
||
</span></span><span style="display:flex;"><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">"HTML"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Export block is not HTML!"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> (progn
|
||
</span></span><span style="display:flex;"><span> (f-mkdir my/org-view-html-tmp-dir)
|
||
</span></span><span style="display:flex;"><span> (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">'utf-8</span> temp-file-path)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">start-process</span> <span style="color:#e6db74">"org-html-preview"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"xdg-open"</span> temp-file-path))))))
|
||
</span></span></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"><span style="display:flex;"><span>(setq org-plantuml-executable-path <span style="color:#e6db74">"/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml"</span>)
|
||
</span></span><span style="display:flex;"><span>(setq org-plantuml-exec-mode <span style="color:#e6db74">'plantuml</span>)
|
||
</span></span><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'org-src-lang-modes</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"plantuml"</span> <span style="color:#f92672">.</span> plantuml))
|
||
</span></span></code></pre></div><h4 id="restclient">Restclient</h4>
|
||
<p><a href="https://github.com/pashky/restclient.el">restclient.el</a> is an Emacs package to send HTTP requests. <a href="https://github.com/alf/ob-restclient.el">ob-restclient</a> provides interaction with Org Babel.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://joseph8th.github.io/posts/wow-writing-literate-api-documentation-in-emacs-org-mode/">WOW! Writing Literate API Documentation in Emacs Org Mode</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"><span style="display:flex;"><span>(use-package restclient
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package ob-restclient
|
||
</span></span><span style="display:flex;"><span> :after (org restclient)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></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"><span style="display:flex;"><span>(org-babel-do-load-languages
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'org-babel-load-languages</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (python <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (sql <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (typescript .t)</span>
|
||
</span></span><span style="display:flex;"><span> (hy <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (plantuml <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (octave <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (jupyter <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (sparql <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'org-babel-after-execute-hook</span> <span style="color:#e6db74">'org-redisplay-inline-images</span>)
|
||
</span></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"><span style="display:flex;"><span>(org-babel-jupyter-override-src-block <span style="color:#e6db74">"python"</span>)
|
||
</span></span><span style="display:flex;"><span>(org-babel-jupyter-override-src-block <span style="color:#e6db74">"hy"</span>)
|
||
</span></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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'org-src-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (hs-minor-mode -1)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (electric-indent-local-mode -1)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (rainbow-delimiters-mode -1)</span>
|
||
</span></span><span style="display:flex;"><span> (highlight-indent-guides-mode <span style="color:#ae81ff">-1</span>)))
|
||
</span></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"><span style="display:flex;"><span>(use-package ob-async
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq ob-async-no-async-languages-alist <span style="color:#f92672">'</span>(<span style="color:#e6db74">"python"</span> <span style="color:#e6db74">"hy"</span> <span style="color:#e6db74">"jupyter-python"</span> <span style="color:#e6db74">"jupyter-octave"</span> <span style="color:#e6db74">"restclient"</span>)))
|
||
</span></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"><span style="display:flex;"><span>#+PROPERTY: header-args:python :session <path-to-kernel>
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/jupyter-runtime-folder (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/.local/share/jupyter/runtime"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/get-open-ports ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'string-to-number</span>
|
||
</span></span><span style="display:flex;"><span> (split-string (shell-command-to-string <span style="color:#e6db74">"ss -tulpnH | awk '{print $5}' | sed -e 's/.*://'"</span>) <span style="color:#e6db74">"\n"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/list-jupyter-kernel-files ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><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">'shell_port</span> (json-read-file (<span style="color:#a6e22e">car</span> file))))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">sort</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">directory-files-and-attributes</span> my/jupyter-runtime-folder <span style="color:#66d9ef">t</span> <span style="color:#e6db74">".*kernel.*json$"</span>)
|
||
</span></span><span style="display:flex;"><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)))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/select-jupyter-kernel ()
|
||
</span></span><span style="display:flex;"><span> (let ((ports (my/get-open-ports))
|
||
</span></span><span style="display:flex;"><span> (files (my/list-jupyter-kernel-files)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">completing-read</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Jupyter kernels: "</span>
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (file)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports))
|
||
</span></span><span style="display:flex;"><span> files))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/insert-jupyter-kernel ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Insert a path to an active Jupyter kernel into the buffer"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">insert</span> (my/select-jupyter-kernel)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/jupyter-connect-repl ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Open an emacs-jupyter REPL, connected to a Jupyter kernel"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (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>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/jupyter-qtconsole ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Open Jupyter QtConsole, connected to a Jupyter kernel"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">start-process</span> <span style="color:#e6db74">"jupyter-qtconsole"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"setsid"</span> <span style="color:#e6db74">"jupyter"</span> <span style="color:#e6db74">"qtconsole"</span> <span style="color:#e6db74">"--existing"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">file-name-nondirectory</span> (my/select-jupyter-kernel))))
|
||
</span></span></code></pre></div><p>I’ve also noticed that there are JSON files left in the runtime folder whenever the kernel isn’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"><span style="display:flex;"><span>(defun my/jupyter-cleanup-kernels ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let* ((ports (my/get-open-ports))
|
||
</span></span><span style="display:flex;"><span> (files (my/list-jupyter-kernel-files))
|
||
</span></span><span style="display:flex;"><span> (to-delete (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (file)
|
||
</span></span><span style="display:flex;"><span> (not (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports)))
|
||
</span></span><span style="display:flex;"><span> files)))
|
||
</span></span><span style="display:flex;"><span> (when (and (length> to-delete <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (y-or-n-p (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Delete %d files?"</span> (<span style="color:#a6e22e">length</span> to-delete))))
|
||
</span></span><span style="display:flex;"><span> (dolist (file to-delete)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">delete-file</span> (<span style="color:#a6e22e">car</span> file))))))
|
||
</span></span></code></pre></div><h4 id="output-post-processing">Output post-processing</h4>
|
||
<h5 id="do-not-wrap-the-output-in-emacs-jupyter">Do not wrap the output in emacs-jupyter</h5>
|
||
<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"><span style="display:flex;"><span>(defun my/jupyter-org-scalar (value)
|
||
</span></span><span style="display:flex;"><span> (cond
|
||
</span></span><span style="display:flex;"><span> ((<span style="color:#a6e22e">stringp</span> value) value)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> (jupyter-org-scalar value))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(define-minor-mode my/emacs-jupyter-raw-output
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Make emacs-jupyter do raw output"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/jupyter-org-scalar-around (fun value)
|
||
</span></span><span style="display:flex;"><span> (if my/emacs-jupyter-raw-output
|
||
</span></span><span style="display:flex;"><span> (my/jupyter-org-scalar value)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">funcall</span> fun value)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(advice-add <span style="color:#e6db74">'jupyter-org-scalar</span> :around <span style="color:#a6e22e">#'</span>my/jupyter-org-scalar-around)
|
||
</span></span></code></pre></div><h5 id="wrap-source-code-output">Wrap source code output</h5>
|
||
<p>A function to remove the :RESULTS: drawer from results. Once again, it’s necessary because emacs-jupyter doesn’t seem to respect <code>:results raw</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"><span style="display:flex;"><span>(defun my/org-strip-results (data)
|
||
</span></span><span style="display:flex;"><span> (replace-regexp-in-string <span style="color:#e6db74">":\\(RESULTS\\|END\\):\n"</span> <span style="color:#e6db74">""</span> data))
|
||
</span></span></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 the :RESULTS: drawer from the output, if necessary</li>
|
||
<li>wrap results in the <code>src</code> block</li>
|
||
</ul>
|
||
<p>As for now, it 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"><span style="display:flex;"><span>(defun my/org-caption-wrap (data <span style="color:#66d9ef">&optional</span> name caption attrs strip-drawer src-wrap)
|
||
</span></span><span style="display:flex;"><span> (let* ((data-s (if (and strip-drawer (not (string-empty-p strip-drawer)))
|
||
</span></span><span style="display:flex;"><span> (my/org-strip-results data)
|
||
</span></span><span style="display:flex;"><span> data))
|
||
</span></span><span style="display:flex;"><span> (drawer-start (if (string-match-p <span style="color:#e6db74">"^:RESULTS:.*"</span> data-s) <span style="color:#ae81ff">10</span> <span style="color:#ae81ff">0</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> data-s <span style="color:#ae81ff">0</span> drawer-start)
|
||
</span></span><span style="display:flex;"><span> (and name (not (string-empty-p name)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+NAME:"</span> name <span style="color:#e6db74">"\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (and caption (not (string-empty-p caption)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+CAPTION:"</span> caption <span style="color:#e6db74">"\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (and attrs (not (string-empty-p attrs)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+ATTR_LATEX:"</span> attrs <span style="color:#e6db74">"\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (if (and src-wrap (not (string-empty-p src-wrap)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+begin_src "</span> src-wrap <span style="color:#e6db74">"\n"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> data-s drawer-start)
|
||
</span></span><span style="display:flex;"><span> (when (not (string-match-p <span style="color:#e6db74">".*\n"</span> data-s)) <span style="color:#e6db74">"\n"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"#+end_src"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span> data-s drawer-start)))))
|
||
</span></span></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"><span style="display:flex;"><span>#+NAME: out_wrap
|
||
</span></span><span style="display:flex;"><span>#+begin_src emacs-lisp :var data="" caption="" name="" attrs="" strip-drawer="" src-wrap="" :tangle no :exports none
|
||
</span></span><span style="display:flex;"><span>(my/org-caption-wrap data name caption attrs strip-drawer src-wrap)
|
||
</span></span><span style="display:flex;"><span>#+end_src
|
||
</span></span></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"><span style="display:flex;"><span>:post out_wrap(name="fig:chart", caption="График", data=*this*)
|
||
</span></span></code></pre></div><h5 id="apply-ansi-color-codes">Apply ANSI color codes</h5>
|
||
<p><strong>SOURCE</strong>: <a href="https://emacs.stackexchange.com/questions/44664/apply-ansi-color-escape-sequences-for-org-babel-results">Apply ANSI color escape sequences for Org Babel results</a></p>
|
||
<p>A minor mode to apply ANSI color codes after execution.</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="display:flex;"><span>(defun my/babel-ansi ()
|
||
</span></span><span style="display:flex;"><span> (when-let ((beg (org-babel-where-is-src-block-result <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span>)))
|
||
</span></span><span style="display:flex;"><span> (save-excursion
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">goto-char</span> beg)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">looking-at</span> org-babel-result-regexp)
|
||
</span></span><span style="display:flex;"><span> (let ((end (org-babel-result-end))
|
||
</span></span><span style="display:flex;"><span> (ansi-color-context-region <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (ansi-color-apply-on-region beg end))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(define-minor-mode org-babel-ansi-colors-mode
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Apply ANSI color codes to Org Babel results."</span>
|
||
</span></span><span style="display:flex;"><span> :global <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after-hook
|
||
</span></span><span style="display:flex;"><span> (if org-babel-ansi-colors-mode
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-babel-after-execute-hook</span> <span style="color:#a6e22e">#'</span>my/babel-ansi)
|
||
</span></span><span style="display:flex;"><span> (remove-hook <span style="color:#e6db74">'org-babel-after-execute-hook</span> <span style="color:#a6e22e">#'</span>my/babel-ansi)))
|
||
</span></span></code></pre></div><h4 id="managing-a-literate-programming-project">Managing a literate programming project</h4>
|
||
<p>A few tricks to do literate programming.</p>
|
||
<p>I prefer to put the org files to a separate directory (e.g. <code>org</code>). So I’ve come up with the following solution to avoid manually prefixing the <code>:tangle</code> arguments.</p>
|
||
<p>Set up the following argument with the path to the project root:</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"><span style="display:flex;"><span>#+PROPERTY: PRJ-DIR ..
|
||
</span></span></code></pre></div><p>A function to do the prefixing:</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="display:flex;"><span>(defun my/org-prj-dir (path)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">expand-file-name</span> path (org-entry-get <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"PRJ-DIR"</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span></code></pre></div><p>Example usage is as follows:</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"><span style="display:flex;"><span>:tangle (my/org-prj-dir "sqrt_data/api/__init__.py")
|
||
</span></span></code></pre></div><h3 id="tools">Tools</h3>
|
||
<p>Various small packages.</p>
|
||
<h4 id="presentations">Presentations</h4>
|
||
<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"><span style="display:flex;"><span>(use-package hide-mode-line
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (org-present))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/present-next-with-latex ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (org-present-next)
|
||
</span></span><span style="display:flex;"><span> (org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/present-prev-with-latex ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (org-present-prev)
|
||
</span></span><span style="display:flex;"><span> (org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package org-present
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"rlister/org-present"</span>)
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :commands (org-present)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-present-mode-keymap</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<next>"</span> <span style="color:#e6db74">'my/present-next-with-latex</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<prior>"</span> <span style="color:#e6db74">'my/present-prev-with-latex</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-present-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (blink-cursor-mode <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (org-present-big)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (org-display-inline-images)</span>
|
||
</span></span><span style="display:flex;"><span> (org-present-hide-cursor)
|
||
</span></span><span style="display:flex;"><span> (org-present-read-only)
|
||
</span></span><span style="display:flex;"><span> (display-line-numbers-mode <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (hide-mode-line-mode <span style="color:#ae81ff">+1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local org-format-latex-options
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">plist-put</span> org-format-latex-options
|
||
</span></span><span style="display:flex;"><span> :scale (<span style="color:#a6e22e">*</span> org-present-text-scale my/org-latex-scale <span style="color:#ae81ff">0.5</span>)))
|
||
</span></span><span style="display:flex;"><span> (org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>))))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-present-mode-quit-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (blink-cursor-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (org-present-small)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (org-remove-inline-images)</span>
|
||
</span></span><span style="display:flex;"><span> (org-present-show-cursor)
|
||
</span></span><span style="display:flex;"><span> (org-present-read-write)
|
||
</span></span><span style="display:flex;"><span> (display-line-numbers-mode <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (hide-mode-line-mode <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
|
||
</span></span><span style="display:flex;"><span> (org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">64</span>)))))
|
||
</span></span></code></pre></div><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"><span style="display:flex;"><span>(use-package org-make-toc
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :commands
|
||
</span></span><span style="display:flex;"><span> (org-make-toc
|
||
</span></span><span style="display:flex;"><span> org-make-toc-insert
|
||
</span></span><span style="display:flex;"><span> org-make-toc-set
|
||
</span></span><span style="display:flex;"><span> org-make-toc-at-point)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package org-attach-screenshot
|
||
</span></span><span style="display:flex;"><span> :commands (org-attach-screenshot)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h4 id="transclusion">Transclusion</h4>
|
||
<p>A package that implements transclusions in Org Mode, that is rendering part of one file inside of another 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"><span style="display:flex;"><span>(use-package org-transclusion
|
||
</span></span><span style="display:flex;"><span> :after org
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"nobiot/org-transclusion"</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-transclusion-extensions</span> <span style="color:#e6db74">'org-transclusion-indent-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'org-transclusion-indent-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(org-transclusion-map)
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"RET"</span> <span style="color:#a6e22e">#'</span>org-transclusion-open-source
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gr"</span> <span style="color:#a6e22e">#'</span>org-transclusion-refresh)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(org-mode-map)
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#e6db74">'normal</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c t a"</span> <span style="color:#a6e22e">#'</span>org-transclusion-add
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c t A"</span> <span style="color:#a6e22e">#'</span>org-transclusion-add-all
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c t t"</span> <span style="color:#a6e22e">#'</span>org-transclusion-mode))
|
||
</span></span></code></pre></div><h3 id="productivity-and-knowledge-management">Productivity & 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_mode_workflow_preview/">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"><span style="display:flex;"><span>(setq org-roam-directory (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/roam"</span>))
|
||
</span></span><span style="display:flex;"><span>(setq org-agenda-files <span style="color:#f92672">'</span>(<span style="color:#e6db74">"inbox.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"projects/comp-stuff.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"projects/looking-forward.org"</span>))
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (setq org-default-notes-file (concat org-directory "/notes.org"))</span>
|
||
</span></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"><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"o"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-mode"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'org-capture</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'org-agenda</span>)
|
||
</span></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"><span style="display:flex;"><span>(setq org-refile-targets <span style="color:#f92672">'</span>())
|
||
</span></span><span style="display:flex;"><span>(setq org-refile-use-outline-path <span style="color:#e6db74">'file</span>)
|
||
</span></span><span style="display:flex;"><span>(setq org-outline-path-complete-in-steps <span style="color:#66d9ef">nil</span>)
|
||
</span></span></code></pre></div><h4 id="capture-templates-and-various-settings">Capture templates & 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"><span style="display:flex;"><span>(defun my/generate-inbox-note-name ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%s/inbox-notes/%s.org"</span>
|
||
</span></span><span style="display:flex;"><span> org-directory
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y%m%d%H%M%S"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq org-capture-templates
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"i"</span> <span style="color:#e6db74">"Inbox"</span> entry (file <span style="color:#e6db74">"inbox.org"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %?\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/Entered on/ %U"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">"email"</span> entry (file <span style="color:#e6db74">"inbox.org"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %:from %:subject \n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/Entered on/ %U\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/Received on/ %:date-timestamp-inactive\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%a\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"f"</span> <span style="color:#e6db74">"elfeed"</span> entry (file <span style="color:#e6db74">"inbox.org"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %:elfeed-entry-title\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/Entered on/ %U\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%a\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"n"</span> <span style="color:#e6db74">"note"</span> entry (file my/generate-inbox-note-name)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* %?\n"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/Entered on/ %U"</span>))))
|
||
</span></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"><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'org-global-properties</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"Effort_ALL"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"0 0:05 0:10 0:15 0:30 0:45 1:00 2:00 4:00"</span>))
|
||
</span></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"><span style="display:flex;"><span>(setq org-log-done <span style="color:#e6db74">'time</span>)
|
||
</span></span></code></pre></div><h4 id="off--trello-sync"><span class="org-todo done OFF">OFF</span> (OFF) Trello sync</h4>
|
||
<p>UPD <span class="timestamp-wrapper"><span class="timestamp"><2022-03-27 Sun></span></span>: disabling this for now.</p>
|
||
<p>Some of the projects I’m participating in are managed via Trello, so I use <a href="http://org-trello.github.io/">org-trello</a> to keep track of them. The package has a remarkably awkward keybindings setup, so my effort to call <code>my-leader-def</code> to set keybindings I like is no less awkward.</p>
|
||
<p>Also, trello files are huge and have a lot of information and tasks which do not concern me, so I don’t add them to <code>org-agenda-files</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"><span style="display:flex;"><span>(unless (<span style="color:#a6e22e">file-exists-p</span> (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello"</span>))
|
||
</span></span><span style="display:flex;"><span> (mkdir (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello"</span>) <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq org-trello-files
|
||
</span></span><span style="display:flex;"><span> (thread-last (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">directory-files</span>)
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (f) (string-match-p (rx <span style="color:#e6db74">".org"</span> eos) f)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (f) (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello/"</span> f)))))
|
||
</span></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"><span style="display:flex;"><span>(use-package org-trello
|
||
</span></span><span style="display:flex;"><span> :straight (:build (:not native-compile))
|
||
</span></span><span style="display:flex;"><span> :commands (org-trello-mode)
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq org-trello-current-prefix-keybinding <span style="color:#e6db74">"C-c o"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-trello-add-tags <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (when (string-match-p (rx <span style="color:#e6db74">"trello"</span>) (or (<span style="color:#a6e22e">buffer-file-name</span>) <span style="color:#e6db74">""</span>))
|
||
</span></span><span style="display:flex;"><span> (org-trello-mode))))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">eval</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"o t"</span>
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(org-trello-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"trello"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,@</span>(mapcan
|
||
</span></span><span style="display:flex;"><span> (lambda (b) (<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> b) (macroexp-quote (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> b))))
|
||
</span></span><span style="display:flex;"><span> org-trello-interactive-command-binding-couples))))
|
||
</span></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’m using it in my review workflow and for custom agenda views.</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="display:flex;"><span>(use-package org-ql
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :straight (:fetcher github
|
||
</span></span><span style="display:flex;"><span> :repo <span style="color:#e6db74">"alphapapa/org-ql"</span>
|
||
</span></span><span style="display:flex;"><span> :files (:defaults (:exclude <span style="color:#e6db74">"helm-org-ql.el"</span>))))
|
||
</span></span></code></pre></div><h4 id="custom-agendas">Custom agendas</h4>
|
||
<p>Some custom agendas to fit my workflow.</p>
|
||
<p>Despite the fact that I don’t add <code>org-trello-files</code> to <code>org-agenda-files</code> I still want to see them in agenda, so I use <code>org-ql-block</code> from <code>org-ql</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"><span style="display:flex;"><span>(defun my/org-scheduled-get-time ()
|
||
</span></span><span style="display:flex;"><span> (let ((scheduled (org-get-scheduled-time (<span style="color:#a6e22e">point</span>))))
|
||
</span></span><span style="display:flex;"><span> (if scheduled
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y-%m-%d"</span> scheduled)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq org-agenda-hide-tags-regexp (rx (or <span style="color:#e6db74">"org"</span> <span style="color:#e6db74">"log"</span> <span style="color:#e6db74">"log_here"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq org-agenda-custom-commands
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">"My outline"</span>
|
||
</span></span><span style="display:flex;"><span> ((agenda <span style="color:#e6db74">""</span>)
|
||
</span></span><span style="display:flex;"><span> (todo <span style="color:#e6db74">"NEXT"</span>
|
||
</span></span><span style="display:flex;"><span> ((org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c [%e] "</span>)
|
||
</span></span><span style="display:flex;"><span> (org-agenda-overriding-header <span style="color:#e6db74">"Next tasks"</span>)))
|
||
</span></span><span style="display:flex;"><span> (tags-todo <span style="color:#e6db74">"inbox"</span>
|
||
</span></span><span style="display:flex;"><span> ((org-agenda-overriding-header <span style="color:#e6db74">"Inbox"</span>)
|
||
</span></span><span style="display:flex;"><span> (org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c"</span>)
|
||
</span></span><span style="display:flex;"><span> (org-agenda-hide-tags-regexp <span style="color:#e6db74">"."</span>)))
|
||
</span></span><span style="display:flex;"><span> (tags-todo <span style="color:#e6db74">"+waitlist+SCHEDULED<=\"<+14d>\""</span>
|
||
</span></span><span style="display:flex;"><span> ((org-agenda-overriding-header <span style="color:#e6db74">"Waitlist"</span>)
|
||
</span></span><span style="display:flex;"><span> (org-agenda-hide-tags-regexp <span style="color:#e6db74">"waitlist"</span>)
|
||
</span></span><span style="display:flex;"><span> (org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c %-12(my/org-scheduled-get-time)"</span>)))))))
|
||
</span></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(ed) to have its entries separate from my knowledge base.</p>
|
||
<p>I’ve tried switching to Org Roam Dailies, but in the end decided that org-journal fits my workflow 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"><span style="display:flex;"><span>(use-package org-journal
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"oj"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-journal"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"j"</span> <span style="color:#e6db74">'org-journal-new-entry</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"o"</span> <span style="color:#e6db74">'org-journal-open-current-journal-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'org-journal-tags-status</span>)
|
||
</span></span><span style="display:flex;"><span> :after org
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq org-journal-dir (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/journal"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq org-journal-file-type <span style="color:#e6db74">'weekly</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-journal-file-format <span style="color:#e6db74">"%Y-%m-%d.org"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-journal-date-format <span style="color:#e6db74">"%A, %Y-%m-%d"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-journal-enable-encryption <span style="color:#66d9ef">t</span>))
|
||
</span></span></code></pre></div><p><a href="https://github.com/SqrtMinusOne/org-journal-tags">org-journal-tags</a> is my package that implements a tagging system for org-journal.</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="display:flex;"><span>(use-package org-journal-tags
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"SqrtMinusOne/org-journal-tags"</span>)
|
||
</span></span><span style="display:flex;"><span> :after (org-journal)
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (org-journal-tags-autosync-mode)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-journal-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c t"</span> <span style="color:#a6e22e">#'</span>org-journal-tags-insert-tag))
|
||
</span></span></code></pre></div><p>I also want to store some information in the journal as properties of the record. So below is a function that 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"><span style="display:flex;"><span>(defun my/set-journal-header ()
|
||
</span></span><span style="display:flex;"><span> (org-set-property <span style="color:#e6db74">"Emacs"</span> emacs-version)
|
||
</span></span><span style="display:flex;"><span> (org-set-property <span style="color:#e6db74">"Hostname"</span> <span style="color:#a6e22e">system-name</span>)
|
||
</span></span><span style="display:flex;"><span> (org-journal-tags-prop-apply-delta :add (<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"host.%s"</span> (<span style="color:#a6e22e">system-name</span>))))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/location</span>)
|
||
</span></span><span style="display:flex;"><span> (org-set-property <span style="color:#e6db74">"Location"</span> my/location))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/loc-tag</span>)
|
||
</span></span><span style="display:flex;"><span> (org-journal-tags-prop-apply-delta :add (<span style="color:#a6e22e">list</span> my/loc-tag)))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'emms-playlist-current-selected-track</span>)
|
||
</span></span><span style="display:flex;"><span> (let ((track (emms-playlist-current-selected-track)))
|
||
</span></span><span style="display:flex;"><span> (when track
|
||
</span></span><span style="display:flex;"><span> (let ((album (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-album</span> track)))
|
||
</span></span><span style="display:flex;"><span> (artist (or (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-albumartist</span> track))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-album</span> track))))
|
||
</span></span><span style="display:flex;"><span> (title (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-title</span> track)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string</span> <span style="color:#e6db74">""</span>))
|
||
</span></span><span style="display:flex;"><span> (when artist
|
||
</span></span><span style="display:flex;"><span> (setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> <span style="color:#e6db74">"["</span> artist <span style="color:#e6db74">"] "</span>)))
|
||
</span></span><span style="display:flex;"><span> (when album
|
||
</span></span><span style="display:flex;"><span> (setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> album <span style="color:#e6db74">" - "</span>)))
|
||
</span></span><span style="display:flex;"><span> (when title
|
||
</span></span><span style="display:flex;"><span> (setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> title)))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">></span> (<span style="color:#a6e22e">length</span> <span style="color:#a6e22e">string</span>) <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> (org-set-property <span style="color:#e6db74">"EMMS_Track"</span> <span style="color:#a6e22e">string</span>)))))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'org-journal-after-entry-create-hook</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'</span>my/set-journal-header)
|
||
</span></span></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>
|
||
<p>I tried to do various things with Org Roam, like <a href="https://systemcrafters.net/build-a-second-brain-in-emacs/5-org-roam-hacks/">managing projects</a>, but ended up prefferring plain Org for most of the stuff.</p>
|
||
<h5 id="basic-package-configuration">Basic package configuration</h5>
|
||
<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’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"><span style="display:flex;"><span>(use-package emacsql-sqlite
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :straight (:type built-in))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package org-roam
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"org-roam/org-roam"</span>
|
||
</span></span><span style="display:flex;"><span> :files (:defaults <span style="color:#e6db74">"extensions/*.el"</span>))
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :after org
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq org-roam-file-extensions <span style="color:#f92672">'</span>(<span style="color:#e6db74">"org"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq org-roam-v2-ack <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq orb-insert-interface <span style="color:#e6db74">'ivy-bibtex</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (org-roam-setup)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'org-roam-protocol</span>))
|
||
</span></span></code></pre></div><h5 id="capture-templates">Capture templates</h5>
|
||
<p>Capture templates for <code>org-roam-capture</code>. As for now, nothing too complicated here.</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="display:flex;"><span>(setq org-roam-capture-templates
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">"default"</span> plain <span style="color:#e6db74">"%?"</span>
|
||
</span></span><span style="display:flex;"><span> :if-new (file+head <span style="color:#e6db74">"%<%Y%m%d%H%M%S>-${slug}.org"</span> <span style="color:#e6db74">"#+title: ${title}\n"</span>)
|
||
</span></span><span style="display:flex;"><span> :unnarrowed <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">"encrypted"</span> plain <span style="color:#e6db74">"%?"</span>
|
||
</span></span><span style="display:flex;"><span> :if-new (file+head <span style="color:#e6db74">"%<%Y%m%d%H%M%S>-${slug}.org.gpg"</span> <span style="color:#e6db74">"#+title: ${title}\n"</span>)
|
||
</span></span><span style="display:flex;"><span> :unnarrowed <span style="color:#66d9ef">t</span>)))
|
||
</span></span></code></pre></div><h5 id="keybindings">Keybindings</h5>
|
||
<p>A set of keybindings to quickly access things in Org Roam.</p>
|
||
<p>I used to have multiple categories of nodes in Org Roam (projects, dailies, etc), but as of now, only Zettelkasten remains.</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="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"or"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-roam"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"i"</span> <span style="color:#e6db74">'org-roam-node-insert</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'org-roam-node-find</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"g"</span> <span style="color:#e6db74">'org-roam-graph</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'org-roam-capture</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'org-roam-buffer-toggle</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'org-roam</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-roam-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"TAB"</span> <span style="color:#a6e22e">#'</span>magit-section-toggle
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#a6e22e">#'</span>quit-window
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"k"</span> <span style="color:#a6e22e">#'</span>magit-section-backward
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"j"</span> <span style="color:#a6e22e">#'</span>magit-section-forward
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gr"</span> <span style="color:#a6e22e">#'</span>revert-buffer
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"RET"</span> <span style="color:#a6e22e">#'</span>org-roam-buffer-visit-thing))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'org</span>
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :keymap <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"or"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'org-roam-tag-add</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"T"</span> <span style="color:#e6db74">'org-toam-tag-remove</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'org-roam-db-autosync-mode</span>)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymap <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c i"</span> <span style="color:#e6db74">'org-id-get-create</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c l o"</span> <span style="color:#e6db74">'org-roam-node-insert</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package org-roam-ui
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"org-roam/org-roam-ui"</span> :branch <span style="color:#e6db74">"main"</span> :files (<span style="color:#e6db74">"*.el"</span> <span style="color:#e6db74">"out"</span>))
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :after org-roam
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; :hook (org-roam . org-roam-ui-mode)</span>
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"oru"</span> <span style="color:#a6e22e">#'</span>org-roam-ui-mode))
|
||
</span></span></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>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#66d9ef">[Desktop Entry]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Name</span><span style="color:#f92672">=</span><span style="color:#e6db74">Org-Protocol</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Exec</span><span style="color:#f92672">=</span><span style="color:#e6db74">emacsclient %u</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Icon</span><span style="color:#f92672">=</span><span style="color:#e6db74">emacs-icon</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Type</span><span style="color:#f92672">=</span><span style="color:#e6db74">Application</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Terminal</span><span style="color:#f92672">=</span><span style="color:#e6db74">false</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">MimeType</span><span style="color:#f92672">=</span><span style="color:#e6db74">x-scheme-handler/org-protocol</span>
|
||
</span></span></code></pre></div><p>Don’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"><span style="display:flex;"><span>xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
|
||
</span></span></code></pre></div><h4 id="review-workflow">Review workflow</h4>
|
||
<p>UPD <span class="timestamp-wrapper"><span class="timestamp"><2022-03-27 Sun></span></span>. Out of action for now</p>
|
||
<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’m doing reviews regularly, but the time intervals still may vary, hence this flexibility.</p>
|
||
<p>This section has seen some updates over time.</p>
|
||
<h5 id="data-from-git">Data from git</h5>
|
||
<p>First, as I have <a href="/configs/console/#autocommit">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’m interested in a form like <code>@{2021-08-30}</code>.</p>
|
||
<p>Also in principle, Org Roam DB also stores stuff like creation time and modification time, but I started this section before I started using Org Roam extensively, so git works fine 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="display:flex;"><span>(setq my/git-diff-status
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"A"</span> <span style="color:#f92672">.</span> added)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"C"</span> <span style="color:#f92672">.</span> copied)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"D"</span> <span style="color:#f92672">.</span> deleted)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"M"</span> <span style="color:#f92672">.</span> modified)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"R"</span> <span style="color:#f92672">.</span> renamed)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"T"</span> <span style="color:#f92672">.</span> type-changed)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"U"</span> <span style="color:#f92672">.</span> unmerged)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/get-files-status (rev)
|
||
</span></span><span style="display:flex;"><span> (let ((files (shell-command-to-string (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"git diff --name-status "</span> rev))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (file)
|
||
</span></span><span style="display:flex;"><span> (let ((elems (split-string file <span style="color:#e6db74">"\t"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cons</span>
|
||
</span></span><span style="display:flex;"><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></span><span style="display:flex;"><span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elems))))
|
||
</span></span><span style="display:flex;"><span> (split-string files <span style="color:#e6db74">"\n"</span> <span style="color:#66d9ef">t</span>))))
|
||
</span></span></code></pre></div><p>I’ll use it to get a list of added and changed files in the Org directory since the last review. The date should 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"><span style="display:flex;"><span>(defun my/org-changed-files-since-date (date)
|
||
</span></span><span style="display:flex;"><span> (let ((default-directory org-directory))
|
||
</span></span><span style="display:flex;"><span> (my/get-files-status (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"@{%s}"</span> date))))
|
||
</span></span></code></pre></div><h5 id="data-from-org-roam">Data from org-roam</h5>
|
||
<p>Now that we have the list of new & changed files, I want to sort into a bunch of categories: projects, log entries, etc. The categories are defined by tags.</p>
|
||
<p>So here is a list of plists that sets these categories. The properties are as follows:</p>
|
||
<ul>
|
||
<li><code>:status</code> is a git status for the file</li>
|
||
<li><code>:tags</code> is a plist that sets up the following conditions for the Roam node
|
||
<ul>
|
||
<li><code>:include</code> - should be empty or one of these should be present</li>
|
||
<li><code>:exclude</code> - should be empty or none of these should be present</li>
|
||
</ul>
|
||
</li>
|
||
<li><code>:title</code> is the name of category as I want it to be seen in the review template</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"><span style="display:flex;"><span>(setq my/org-review-roam-queries
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((:status added
|
||
</span></span><span style="display:flex;"><span> :tags (:include (<span style="color:#e6db74">"org"</span>))
|
||
</span></span><span style="display:flex;"><span> :title <span style="color:#e6db74">"New Project Entries"</span>)
|
||
</span></span><span style="display:flex;"><span> (:status changed
|
||
</span></span><span style="display:flex;"><span> :tags (:include (<span style="color:#e6db74">"org"</span>))
|
||
</span></span><span style="display:flex;"><span> :title <span style="color:#e6db74">"Changed Project Entries"</span>)
|
||
</span></span><span style="display:flex;"><span> (:status added
|
||
</span></span><span style="display:flex;"><span> :tags (:exclude (<span style="color:#e6db74">"org"</span>))
|
||
</span></span><span style="display:flex;"><span> :title <span style="color:#e6db74">"New Zettelkasten Entries"</span>)
|
||
</span></span><span style="display:flex;"><span> (:status changed
|
||
</span></span><span style="display:flex;"><span> :tags (:exclude (<span style="color:#e6db74">"org"</span>))
|
||
</span></span><span style="display:flex;"><span> :title <span style="color:#e6db74">"Changed Zettelkasten Entries"</span>)))
|
||
</span></span></code></pre></div><p>This list is used to extract & format the relevant section of the review template.</p>
|
||
<p><code>cl-loop</code> seems pretty good as a control flow structure, but I’ll see if it is also pretty good at producing poorly maintainable code. At least at the moment of this writing, the function below looks rather concise.</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="display:flex;"><span>(defun my/org-review-format-roam (changes)
|
||
</span></span><span style="display:flex;"><span> (cl-loop for query in my/org-review-roam-queries
|
||
</span></span><span style="display:flex;"><span> with nodes <span style="color:#a6e22e">=</span> (org-roam-node-list)
|
||
</span></span><span style="display:flex;"><span> with node-tags <span style="color:#a6e22e">=</span> (<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'</span>org-roam-node-tags nodes)
|
||
</span></span><span style="display:flex;"><span> for include-tags <span style="color:#a6e22e">=</span> (<span style="color:#a6e22e">plist-get</span> (<span style="color:#a6e22e">plist-get</span> query :tags) :include)
|
||
</span></span><span style="display:flex;"><span> for exclude-tags <span style="color:#a6e22e">=</span> (<span style="color:#a6e22e">plist-get</span> (<span style="color:#a6e22e">plist-get</span> query :tags) :exclude)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; List of nodes filtered by :tags in query</span>
|
||
</span></span><span style="display:flex;"><span> for filtered-nodes <span style="color:#a6e22e">=</span>
|
||
</span></span><span style="display:flex;"><span> (cl-loop for node in nodes
|
||
</span></span><span style="display:flex;"><span> for tags in node-tags
|
||
</span></span><span style="display:flex;"><span> if (and
|
||
</span></span><span style="display:flex;"><span> (or (seq-empty-p include-tags)
|
||
</span></span><span style="display:flex;"><span> (seq-intersection include-tags tags))
|
||
</span></span><span style="display:flex;"><span> (or (seq-empty-p exclude-tags)
|
||
</span></span><span style="display:flex;"><span> (not (seq-intersection exclude-tags tags))))
|
||
</span></span><span style="display:flex;"><span> collect node)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; List of changes filtered by :status in query</span>
|
||
</span></span><span style="display:flex;"><span> for filtered-changes <span style="color:#a6e22e">=</span>
|
||
</span></span><span style="display:flex;"><span> (cl-loop for change in changes
|
||
</span></span><span style="display:flex;"><span> if (and (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">car</span> change) (<span style="color:#a6e22e">plist-get</span> query :status))
|
||
</span></span><span style="display:flex;"><span> (string-match-p (rx bos <span style="color:#e6db74">"roam"</span>) (<span style="color:#a6e22e">cdr</span> change)))
|
||
</span></span><span style="display:flex;"><span> collect (<span style="color:#a6e22e">cdr</span> change))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Intersection of the two filtered lists</span>
|
||
</span></span><span style="display:flex;"><span> for final-nodes <span style="color:#a6e22e">=</span>
|
||
</span></span><span style="display:flex;"><span> (cl-loop for node in filtered-nodes
|
||
</span></span><span style="display:flex;"><span> for path <span style="color:#a6e22e">=</span> (file-relative-name (org-roam-node-file node)
|
||
</span></span><span style="display:flex;"><span> org-directory)
|
||
</span></span><span style="display:flex;"><span> if (<span style="color:#a6e22e">member</span> path filtered-changes)
|
||
</span></span><span style="display:flex;"><span> collect node)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; If the intersction list is not empty, format it to the result</span>
|
||
</span></span><span style="display:flex;"><span> if final-nodes
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"** %s\n"</span> (<span style="color:#a6e22e">plist-get</span> query :title))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; FInal list of links, sorted by title</span>
|
||
</span></span><span style="display:flex;"><span> and <span style="color:#a6e22e">concat</span> (cl-loop for node in (seq-sort
|
||
</span></span><span style="display:flex;"><span> (lambda (node1 node2)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-lessp</span>
|
||
</span></span><span style="display:flex;"><span> (org-roam-node-title node1)
|
||
</span></span><span style="display:flex;"><span> (org-roam-node-title node2)))
|
||
</span></span><span style="display:flex;"><span> final-nodes)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"- [[id:%s][%s]]\n"</span>
|
||
</span></span><span style="display:flex;"><span> (org-roam-node-id node)
|
||
</span></span><span style="display:flex;"><span> (org-roam-node-title node)))))
|
||
</span></span></code></pre></div><h5 id="data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</h5>
|
||
<p><del>Third</del> second, I want to list some changes in my agenda. This section will change depending on what I’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"><span style="display:flex;"><span>(setq my/org-ql-review-queries
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"Waitlist"</span> scheduled scheduled
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (done)
|
||
</span></span><span style="display:flex;"><span> (tags-inherited <span style="color:#e6db74">"waitlist"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"Personal tasks done"</span> closed <span style="color:#f92672">,</span><span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (tags-inherited <span style="color:#e6db74">"personal"</span>)
|
||
</span></span><span style="display:flex;"><span> (todo <span style="color:#e6db74">"DONE"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"Attended meetings"</span> closed scheduled
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (tags-inherited <span style="color:#e6db74">"meeting"</span>)
|
||
</span></span><span style="display:flex;"><span> (todo <span style="color:#e6db74">"PASSED"</span>)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"Done project tasks"</span> closed deadline
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (todo <span style="color:#e6db74">"DONE"</span>)
|
||
</span></span><span style="display:flex;"><span> (ancestors
|
||
</span></span><span style="display:flex;"><span> (heading <span style="color:#e6db74">"Tasks"</span>))))))
|
||
</span></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"><span style="display:flex;"><span>(defun my/org-review-exec-ql (saved rev-date)
|
||
</span></span><span style="display:flex;"><span> (let ((query <span style="color:#f92672">`</span>(and
|
||
</span></span><span style="display:flex;"><span> (<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></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">3</span> saved))))
|
||
</span></span><span style="display:flex;"><span> (org-ql-query
|
||
</span></span><span style="display:flex;"><span> :select <span style="color:#a6e22e">#'</span>element
|
||
</span></span><span style="display:flex;"><span> :from (org-agenda-files)
|
||
</span></span><span style="display:flex;"><span> :where query
|
||
</span></span><span style="display:flex;"><span> :order-by (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> saved))))
|
||
</span></span></code></pre></div><p>Format one element of the 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"><span style="display:flex;"><span>(defun my/org-review-format-element (elem)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (string-pad
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">plist-get</span> (cadr elem) :raw-value)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">40</span>)
|
||
</span></span><span style="display:flex;"><span> (when-let (scheduled (<span style="color:#a6e22e">plist-get</span> (cadr elem) :scheduled))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">" [SCHEDULED: "</span> (<span style="color:#a6e22e">plist-get</span> (cadr scheduled) :raw-value) <span style="color:#e6db74">"]"</span>))
|
||
</span></span><span style="display:flex;"><span> (when-let (deadline (<span style="color:#a6e22e">plist-get</span> (cadr elem) :deadline))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">" [DEADLINE: "</span> (<span style="color:#a6e22e">plist-get</span> (cadr deadline) :raw-value) <span style="color:#e6db74">"]"</span>))))
|
||
</span></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"><span style="display:flex;"><span>(defun my/org-review-format-queries (rev-date)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapconcat</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (results)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"** "</span> (<span style="color:#a6e22e">car</span> results) <span style="color:#e6db74">"\n"</span>
|
||
</span></span><span style="display:flex;"><span> (string-join
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span> (lambda (r) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"- "</span> r)) (<span style="color:#a6e22e">cdr</span> results))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\n"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\n"</span>))
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (result)
|
||
</span></span><span style="display:flex;"><span> (not (seq-empty-p (<span style="color:#a6e22e">cdr</span> result))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (saved)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cons</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">car</span> saved)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'</span>my/org-review-format-element
|
||
</span></span><span style="display:flex;"><span> (my/org-review-exec-ql saved rev-date))))
|
||
</span></span><span style="display:flex;"><span> my/org-ql-review-queries))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\n"</span>))
|
||
</span></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><del>I’ll use a separate directory for the review files, just like for org-journal and org-roam.</del> I’ll store the review files in org-roam. Time will tell if that’s a good idea. 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 two week. Also featuring the most awkward date transformation I’ve ever done just to add one date.</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="display:flex;"><span>(setq my/org-review-directory <span style="color:#e6db74">"review"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/get-last-review-date ()
|
||
</span></span><span style="display:flex;"><span> (->
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span>
|
||
</span></span><span style="display:flex;"><span> (or
|
||
</span></span><span style="display:flex;"><span> (-max-by
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'string-greaterp</span>
|
||
</span></span><span style="display:flex;"><span> (-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (f) (not (or (<span style="color:#a6e22e">string-equal</span> f <span style="color:#e6db74">"."</span>) (<span style="color:#a6e22e">string-equal</span> f <span style="color:#e6db74">".."</span>))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">directory-files</span> (f-join org-roam-directory my/org-review-directory))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format-time-string</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%Y-%m-%d"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">time-subtract</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">current-time</span>)
|
||
</span></span><span style="display:flex;"><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">14</span>)))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0</span> <span style="color:#ae81ff">10</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"T00:00:00-00:00"</span>)
|
||
</span></span><span style="display:flex;"><span> parse-time-string
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">encode-time</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">time-add</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></span><span style="display:flex;"><span> ((lambda (time)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y-%m-%d"</span> time)))))
|
||
</span></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"><span style="display:flex;"><span>(setq my/org-review-capture-template
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">"Review"</span> plain
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(string-join
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"#+title: %<%Y-%m-%d>: REVIEW"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"#+category: REVIEW"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"#+filetags: log review"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"#+STARTUP: overview"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Last review date: %(org-timestamp-translate (org-timestamp-from-string (format \"<%s>\" (my/get-last-review-date))))"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"* Roam"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%(my/org-review-format-roam (my/org-changed-files-since-date (my/get-last-review-date)))"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"* Agenda"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%(my/org-review-format-queries (my/get-last-review-date))"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"* Thoughts"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"%?"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\n"</span>)
|
||
</span></span><span style="display:flex;"><span> :if-new (file <span style="color:#e6db74">"review/%<%Y-%m-%d>.org.gpg"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/org-roam-capture-review ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (org-roam-capture- :node (org-roam-node-create)
|
||
</span></span><span style="display:flex;"><span> :templates <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>my/org-review-capture-template)))
|
||
</span></span></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 & 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’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"><span style="display:flex;"><span>(use-package org-ref
|
||
</span></span><span style="display:flex;"><span> :straight (:files (:defaults (:exclude <span style="color:#e6db74">"*helm*"</span>)))
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq org-ref-completion-library <span style="color:#e6db74">'org-ref-ivy-cite</span>)
|
||
</span></span><span style="display:flex;"><span> (setq bibtex-dialect <span style="color:#e6db74">'biblatex</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-ref-default-bibliography <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/Documents/org-mode/bibliography.bib"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq reftex-default-bibliography org-ref-default-bibliography)
|
||
</span></span><span style="display:flex;"><span> (setq bibtex-completion-bibliography org-ref-default-bibliography)
|
||
</span></span><span style="display:flex;"><span> :after (org)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c l"</span> <span style="color:#a6e22e">#'</span>org-ref-insert-link-hydra/body)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'bibtex-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-RET"</span> <span style="color:#e6db74">'org-ref-bibtex-hydra/body</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (add-to-list 'orhc-candidate-formats</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; '("online" . " |${=key=}| ${title} ${url}"))</span>
|
||
</span></span><span style="display:flex;"><span> )
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/org-ref-select-bibliograhy ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (setq-local org-ref-default-bibliography
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(read-file-name <span style="color:#e6db74">"Bibliograhy: "</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span> (setq-local reftex-default-bibliography org-ref-default-bibliography)
|
||
</span></span><span style="display:flex;"><span> (setq-local bibtex-completion-bibliography org-ref-default-bibliography))
|
||
</span></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"><span style="display:flex;"><span>(use-package org-roam-bibtex
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"org-roam/org-roam-bibtex"</span>)
|
||
</span></span><span style="display:flex;"><span> :after (org-roam org-ref)
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (org-roam-bibtex-mode))
|
||
</span></span></code></pre></div><h4 id="org-contacts">org-contacts</h4>
|
||
<p><code>org-contacts</code> is an <code>org-contrib</code> package to store contacts in an org file. The package is somewhat outdated, for instance it uses <code>lexical-let</code>, so I have to <code>(require 'cl)</code>.</p>
|
||
<p>I think it will take some more work to tune the package exactly to my liking, but it seems to perform the original function just 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"><span style="display:flex;"><span>(use-package org-contacts
|
||
</span></span><span style="display:flex;"><span> :straight (:type git
|
||
</span></span><span style="display:flex;"><span> :repo <span style="color:#e6db74">"https://git.sr.ht/~bzg/org-contrib"</span>
|
||
</span></span><span style="display:flex;"><span> :files (<span style="color:#e6db74">"lisp/org-contacts.el"</span>)
|
||
</span></span><span style="display:flex;"><span> :build (:not compile))
|
||
</span></span><span style="display:flex;"><span> :after (notmuch)
|
||
</span></span><span style="display:flex;"><span> :commands (org-contacts)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'cl</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-contacts-files (<span style="color:#a6e22e">list</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/contacts.org"</span>))))
|
||
</span></span></code></pre></div><p>An example contact entry can look 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"><span style="display:flex;"><span>* Pavel Korytov
|
||
</span></span><span style="display:flex;"><span>:PROPERTIES:
|
||
</span></span><span style="display:flex;"><span>:TYPE: person
|
||
</span></span><span style="display:flex;"><span>:EMAIL: thexcloud@gmail.com
|
||
</span></span><span style="display:flex;"><span>:EMAIL+: pvkorytov@etu.ru
|
||
</span></span><span style="display:flex;"><span>:BIRTHDAY: [1998-08-14]
|
||
</span></span><span style="display:flex;"><span>:END:
|
||
</span></span></code></pre></div><h4 id="managing-tables">Managing tables</h4>
|
||
<p>I use Org to manage some small tables which I want to process further. So here is a function that saves each table to a CSV 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"><span style="display:flex;"><span>(defun my/export-org-tables-to-csv ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (org-table-map-tables
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (when-let
|
||
</span></span><span style="display:flex;"><span> (name
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">plist-get</span> (cadr (org-element-at-point)) :name))
|
||
</span></span><span style="display:flex;"><span> (org-table-export
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">file-name-directory</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">buffer-file-name</span>))
|
||
</span></span><span style="display:flex;"><span> name <span style="color:#e6db74">".csv"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"orgtbl-to-csv"</span>)))))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package org-latex-impatient
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"yangsheng6810/org-latex-impatient"</span>
|
||
</span></span><span style="display:flex;"><span> :branch <span style="color:#e6db74">"master"</span>
|
||
</span></span><span style="display:flex;"><span> :host github)
|
||
</span></span><span style="display:flex;"><span> :hook (org-mode <span style="color:#f92672">.</span> org-latex-impatient-mode)
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-impatient-tex2svg-bin
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Programs/miniconda3/lib/node_modules/mathjax-node-cli/bin/tex2svg"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-impatient-scale <span style="color:#ae81ff">1.75</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-impatient-delay <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-impatient-border-color <span style="color:#e6db74">"#ffffff"</span>))
|
||
</span></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"><span style="display:flex;"><span>(defun my/enable-org-latex ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (customize-set-variable <span style="color:#e6db74">'org-highlight-latex-and-related</span> <span style="color:#f92672">'</span>(native))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'org-mode-hook</span> (lambda () (yas-activate-extra-mode <span style="color:#e6db74">'LaTeX-mode</span>)))
|
||
</span></span><span style="display:flex;"><span> (sp-local-pair <span style="color:#e6db74">'org-mode</span> <span style="color:#e6db74">"$"</span> <span style="color:#e6db74">"$"</span>)
|
||
</span></span><span style="display:flex;"><span> (sp--remove-local-pair <span style="color:#e6db74">"'"</span>))
|
||
</span></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"><span style="display:flex;"><span>(setq my/org-latex-scale <span style="color:#ae81ff">1.75</span>)
|
||
</span></span><span style="display:flex;"><span>(setq org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
|
||
</span></span></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"><span style="display:flex;"><span>(setq my/latex-preview-header <span style="color:#e6db74">"\\documentclass{article}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage[usenames]{color}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{graphicx}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{grffile}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{longtable}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{wrapfig}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{rotating}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage[normalem]{ulem}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{amsmath}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{textcomp}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{amssymb}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{capt-of}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\usepackage{hyperref}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\\pagestyle{empty}"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq org-preview-latex-process-alist
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (item)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cons</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">car</span> item)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">plist-put</span> (<span style="color:#a6e22e">cdr</span> item) :latex-header my/latex-preview-header)))
|
||
</span></span><span style="display:flex;"><span> org-preview-latex-process-alist))
|
||
</span></span></code></pre></div><h4 id="better-headers">Better headers</h4>
|
||
<p><a href="https://github.com/integral-dw/org-superstar-mode">org-superstar-mode</a> is a package that makes Org heading lines look a bit prettier.</p>
|
||
<p>Disabled it for now because of overlapping functionality with org-bars.</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="display:flex;"><span>(use-package org-superstar
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :hook (org-mode <span style="color:#f92672">.</span> org-superstar-mode))
|
||
</span></span></code></pre></div><p><a href="https://github.com/tonyaldon/org-bars">org-bars</a> highlights Org indentation with bars.</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="display:flex;"><span>(use-package org-bars
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"tonyaldon/org-bars"</span> :host github)
|
||
</span></span><span style="display:flex;"><span> :if (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> :hook (org-mode <span style="color:#f92672">.</span> org-bars-mode))
|
||
</span></span></code></pre></div><p>Remove the ellipsis at the end of folded headlines. The ellipsis seems unnecessary with org-bars.</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="display:flex;"><span>(defun my/org-no-ellipsis-in-headlines ()
|
||
</span></span><span style="display:flex;"><span> (remove-from-invisibility-spec <span style="color:#f92672">'</span>(outline <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (add-to-invisibility-spec <span style="color:#e6db74">'outline</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'org-mode-hook</span> <span style="color:#a6e22e">#'</span>my/org-no-ellipsis-in-headlines)
|
||
</span></span></code></pre></div><h4 id="override-colors">Override colors</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="display:flex;"><span>(my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span> (org-block :background (color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>))
|
||
</span></span><span style="display:flex;"><span> (org-block-begin-line :background (color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>)
|
||
</span></span><span style="display:flex;"><span> :foreground (doom-color <span style="color:#e6db74">'grey</span>)))
|
||
</span></span></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"><span style="display:flex;"><span><span style="color:#75715e">;; (setq org-export-backends '(md html latex beamer org))</span>
|
||
</span></span></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"><span style="display:flex;"><span>(use-package ox-hugo
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after ox)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package ox-ipynb
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"jkitchin/ox-ipynb"</span>)
|
||
</span></span><span style="display:flex;"><span> :after ox)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package htmlize
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after ox
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq org-html-htmlize-output-type <span style="color:#e6db74">'css</span>))
|
||
</span></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"><span style="display:flex;"><span>(defun my/setup-org-latex ()
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-prefer-user-labels <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-compiler <span style="color:#e6db74">"xelatex"</span>) <span style="color:#75715e">;; Probably not necessary</span>
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-pdf-process <span style="color:#f92672">'</span>(<span style="color:#e6db74">"latexmk -outdir=%o %f"</span>)) <span style="color:#75715e">;; Use latexmk</span>
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-listings <span style="color:#e6db74">'minted</span>) <span style="color:#75715e">;; Use minted to highlight source code</span>
|
||
</span></span><span style="display:flex;"><span> (setq org-latex-minted-options <span style="color:#75715e">;; Some minted options I like</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"breaklines"</span> <span style="color:#e6db74">"true"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"tabsize"</span> <span style="color:#e6db74">"4"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"autogobble"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"linenos"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"numbersep"</span> <span style="color:#e6db74">"0.5cm"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"xleftmargin"</span> <span style="color:#e6db74">"1cm"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"frame"</span> <span style="color:#e6db74">"single"</span>)))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Use extarticle without the default packages</span>
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-latex-classes</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"org-plain-extarticle"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\\documentclass{extarticle}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[PACKAGES]
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[EXTRA]"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\section{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\subsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\subsubsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\paragraph{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\paragraph*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\subparagraph{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subparagraph*{%s}"</span>)))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Use beamer without the default packages</span>
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'org-latex-classes</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"org-latex-beamer"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\\documentclass{beamer}
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[PACKAGES]
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">[EXTRA]"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"beamer"</span> <span style="color:#e6db74">"\\documentclass[presentation]{beamer}"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\section{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\subsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection*{%s}"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"\\subsubsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection*{%s}"</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; Make sure to eval the function when org-latex-classes list already exists</span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'ox-latex</span>
|
||
</span></span><span style="display:flex;"><span> (my/setup-org-latex))
|
||
</span></span></code></pre></div><h3 id="keybindings-and-stuff">Keybindings & stuff</h3>
|
||
<h4 id="general-keybindings">General 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"><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c d"</span> <span style="color:#e6db74">'org-decrypt-entry</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c e"</span> <span style="color:#e6db74">'org-encrypt-entry</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-p"</span> <span style="color:#e6db74">'org-latex-preview</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-o"</span> <span style="color:#e6db74">'org-redisplay-inline-images</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"L"</span> <span style="color:#e6db74">'org-shiftright</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"H"</span> <span style="color:#e6db74">'org-shiftleft</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"S-<next>"</span> <span style="color:#e6db74">'org-next-visible-heading</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"S-<prior>"</span> <span style="color:#e6db74">'org-previous-visible-heading</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-0"</span> <span style="color:#e6db74">'org-next-visible-heading</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-9"</span> <span style="color:#e6db74">'org-previous-visible-heading</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-]"</span> <span style="color:#e6db74">'org-babel-next-src-block</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-["</span> <span style="color:#e6db74">'org-babel-previous-src-block</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'org-agenda-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-]"</span> <span style="color:#e6db74">'org-agenda-later</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-["</span> <span style="color:#e6db74">'org-agenda-earlier</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)</span>
|
||
</span></span><span style="display:flex;"><span>(general-nmap :keymaps <span style="color:#e6db74">'org-mode-map</span> <span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'org-ctrl-c-ctrl-c</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; (my-leader-def "aa" 'org-agenda)</span>
|
||
</span></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"><span style="display:flex;"><span>(defun my/org-link-copy (<span style="color:#66d9ef">&optional</span> arg)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Extract URL from org-mode link and add it to kill ring."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive <span style="color:#e6db74">"P"</span>)
|
||
</span></span><span style="display:flex;"><span> (let* ((link (org-element-lineage (org-element-context) <span style="color:#f92672">'</span>(link) <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (type (org-element-property :type link))
|
||
</span></span><span style="display:flex;"><span> (url (org-element-property :path link))
|
||
</span></span><span style="display:flex;"><span> (url (<span style="color:#a6e22e">concat</span> type <span style="color:#e6db74">":"</span> url)))
|
||
</span></span><span style="display:flex;"><span> (kill-new url)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Copied URL: "</span> url))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-nmap :keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-x C-l"</span> <span style="color:#e6db74">'my/org-link-copy</span>)
|
||
</span></span></code></pre></div><h4 id="open-a-file-from-org-directory">Open a file from <code>org-directory</code></h4>
|
||
<p>A function to open a file from <code>org-directory</code>, excluding a few directories like <code>roam</code> and <code>journal</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"><span style="display:flex;"><span>(defun my/org-file-open ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let* ((default-directory org-directory)
|
||
</span></span><span style="display:flex;"><span> (project-files
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (f)
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (string-match-p (rx (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">".org"</span> eos) f)
|
||
</span></span><span style="display:flex;"><span> (not (string-match-p (rx (| <span style="color:#e6db74">"journal"</span> <span style="color:#e6db74">"roam"</span> <span style="color:#e6db74">"review"</span> <span style="color:#e6db74">"archive"</span>)) f))))
|
||
</span></span><span style="display:flex;"><span> (projectile-current-project-files))))
|
||
</span></span><span style="display:flex;"><span> (find-file
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/"</span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Org file: "</span> project-files)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"o o"</span> <span style="color:#e6db74">'my/org-file-open</span>)
|
||
</span></span></code></pre></div><h3 id="system-configuration">System configuration</h3>
|
||
<p>Functions related to literate configuration.</p>
|
||
<h4 id="tables-for-guix-dependencies">Tables for Guix Dependencies</h4>
|
||
<p>This section deals with using <a href="https://guix.gnu.org/en/cookbook/en/html_node/Advanced-package-management.html#Advanced-package-management">using profiles in GNU Guix</a>.</p>
|
||
<p>A “profile” in Guix is a way to group package installations. For instance, I have a “music” profile that has software like <a href="https://www.musicpd.org/">MPD</a>, <a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp</a> that I’m still occasionally using because of its tag editor, etc. Corresponding to that profile, there’s a manifest named <code>music.scm</code> that 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-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#a6e22e">specifications->manifest</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"flac"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"cuetools"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"shntool"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"mpd-mpc"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"mpd-watcher"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"picard"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ncmpcpp"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"mpd"</span>))
|
||
</span></span></code></pre></div><p>I could generate this file with <code>org-babel</code> as any other, but that is often not so convenient. For example, I have a <a href="https://github.com/polybar/polybar">polybar</a> module that uses <a href="https://github.com/risacher/sunwait">sunwait</a> to show sunset and sunrise times, and ideally, I want to declare <code>sunwait</code> to be in the “desktop-polybar” profile in the same section that has the polybar module definition and the bash script.</p>
|
||
<p>So here’s an approach I came up with. The relevant section of the config 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"><span style="display:flex;"><span>*** sun
|
||
</span></span><span style="display:flex;"><span>| Category | Guix dependency |
|
||
</span></span><span style="display:flex;"><span>|-----------------+-----------------|
|
||
</span></span><span style="display:flex;"><span>| desktop-polybar | sunwait |
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>Prints out the time of sunrise/sunset. Uses [[https://github.com/risacher/sunwait][sunwait]]
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>#+begin_src bash :tangle ./bin/polybar/sun.sh :noweb no-export
|
||
</span></span><span style="display:flex;"><span>...script...
|
||
</span></span><span style="display:flex;"><span>#+end_src
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>#+begin_src ini :noweb no-export
|
||
</span></span><span style="display:flex;"><span>...polybar module definition...
|
||
</span></span><span style="display:flex;"><span>#+end_src
|
||
</span></span></code></pre></div><p>So <code>sunwait</code> is declared in an Org table with <code>Guix dependency</code> in the header. Such tables are spread through my configuration files.</p>
|
||
<p>Thus I made a function that extracts packages from all such tables from the current Org buffer. The rules are as follows:</p>
|
||
<ul>
|
||
<li>If a column name matches <code>[G|g]uix.*dep</code>, its contents are added to the result.</li>
|
||
<li>If <code>CATEGORY</code> is passed, a column with name <code>[C|c]ategory</code> is used to filter results. That way, one Org file can be used to produce multiple manifests.</li>
|
||
<li>If <code>CATEGORY</code> is not passed, entries with the non-empty category are filtered out</li>
|
||
<li>If there is a <code>[D|d]isabled</code> column, entries that have a non-empty value in this column are filtered out.</li>
|
||
</ul>
|
||
<p>And here is the implementation:</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="display:flex;"><span>(defun my/extract-guix-dependencies (<span style="color:#66d9ef">&optional</span> category)
|
||
</span></span><span style="display:flex;"><span> (let ((dependencies <span style="color:#f92672">'</span>()))
|
||
</span></span><span style="display:flex;"><span> (org-table-map-tables
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (let* ((table
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (q) (not (<span style="color:#a6e22e">eq</span> q <span style="color:#e6db74">'hline</span>)))
|
||
</span></span><span style="display:flex;"><span> (org-table-to-lisp)))
|
||
</span></span><span style="display:flex;"><span> (dep-name-index
|
||
</span></span><span style="display:flex;"><span> (cl-position
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
|
||
</span></span><span style="display:flex;"><span> :test (lambda (_ elem)
|
||
</span></span><span style="display:flex;"><span> (string-match-p <span style="color:#e6db74">"[G|g]uix.*dep"</span> elem))))
|
||
</span></span><span style="display:flex;"><span> (category-name-index
|
||
</span></span><span style="display:flex;"><span> (cl-position
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
|
||
</span></span><span style="display:flex;"><span> :test (lambda (_ elem)
|
||
</span></span><span style="display:flex;"><span> (string-match-p <span style="color:#e6db74">".*[C|c]ategory.*"</span> elem))))
|
||
</span></span><span style="display:flex;"><span> (disabled-name-index
|
||
</span></span><span style="display:flex;"><span> (cl-position
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
|
||
</span></span><span style="display:flex;"><span> :test (lambda (_ elem)
|
||
</span></span><span style="display:flex;"><span> (string-match-p <span style="color:#e6db74">".*[D|d]isabled.*"</span> elem)))))
|
||
</span></span><span style="display:flex;"><span> (when dep-name-index
|
||
</span></span><span style="display:flex;"><span> (dolist (elem (<span style="color:#a6e22e">cdr</span> table))
|
||
</span></span><span style="display:flex;"><span> (when
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Category</span>
|
||
</span></span><span style="display:flex;"><span> (or
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Category not set and not present in the table</span>
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> (or (not category) (string-empty-p category))
|
||
</span></span><span style="display:flex;"><span> (not category-name-index))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Category is set and present in the table</span>
|
||
</span></span><span style="display:flex;"><span> (and
|
||
</span></span><span style="display:flex;"><span> category-name-index
|
||
</span></span><span style="display:flex;"><span> (not (string-empty-p category))
|
||
</span></span><span style="display:flex;"><span> (string-match-p category (<span style="color:#a6e22e">nth</span> category-name-index elem))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; Not disabled</span>
|
||
</span></span><span style="display:flex;"><span> (or
|
||
</span></span><span style="display:flex;"><span> (not disabled-name-index)
|
||
</span></span><span style="display:flex;"><span> (string-empty-p (<span style="color:#a6e22e">nth</span> disabled-name-index elem))))
|
||
</span></span><span style="display:flex;"><span> (add-to-list
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'dependencies</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">nth</span> dep-name-index elem)))))))))
|
||
</span></span><span style="display:flex;"><span> dependencies))
|
||
</span></span></code></pre></div><p>To make it work in the configuration, it is necessary to format the list so that Scheme could read 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="display:flex;"><span>(defun my/format-guix-dependencies (<span style="color:#66d9ef">&optional</span> category)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapconcat</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (e) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"\""</span> e <span style="color:#e6db74">"\""</span>))
|
||
</span></span><span style="display:flex;"><span> (my/extract-guix-dependencies category)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"\n"</span>))
|
||
</span></span></code></pre></div><p>And we need an Org snippet such as 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"><span style="display:flex;"><span>#+NAME: packages
|
||
</span></span><span style="display:flex;"><span>#+begin_src emacs-lisp :tangle no :var category=""
|
||
</span></span><span style="display:flex;"><span>(my/format-guix-dependencies category)
|
||
</span></span><span style="display:flex;"><span>#+end_src
|
||
</span></span></code></pre></div><p>Now, creating a manifest, for example, for the <code>desktop-polybar</code> profile is as simple as:</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"><span style="display:flex;"><span>#+begin_src scheme :tangle ~/.config/guix/manifests/desktop-polybar.scm :noweb no-export
|
||
</span></span><span style="display:flex;"><span>(specifications->manifest
|
||
</span></span><span style="display:flex;"><span> '(
|
||
</span></span><span style="display:flex;"><span> <<packages("desktop-polybar")>>))
|
||
</span></span><span style="display:flex;"><span>#+end_src
|
||
</span></span></code></pre></div><p>There’s a newline symbol between “(” and <code><<packages("desktop-polybar")>></code> because whenever a noweb expression expands into multiple lines, for each new line noweb duplicates contents between the start of the line and the start of the expression.</p>
|
||
<p>One reason this is so is to support languages where indentation is a part of the syntax, for instance, 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-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TestClass</span>:
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><<</span>class<span style="color:#f92672">-</span>contents<span style="color:#f92672">>></span>
|
||
</span></span></code></pre></div><p>So every line of <code><<class-contents>></code> will be indented appropriately. In our case though, it is a minor inconvenience to be aware of.</p>
|
||
<h4 id="noweb-evaluations">Noweb evaluations</h4>
|
||
<p>One note is that by default running these commands will require the user to confirm evaluation of each code block. To avoid that, I set <code>org-confirm-babel-evaluate</code> to <code>nil</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"><span style="display:flex;"><span>(setq my/org-config-files
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"/home/pavel/Emacs.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Desktop.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Console.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Guix.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Mail.org"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">buffer-file-name</span>) my/org-config-files)
|
||
</span></span><span style="display:flex;"><span> (setq-local org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>))))
|
||
</span></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"><span style="display:flex;"><span>(require <span style="color:#e6db74">'org</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(org-babel-do-load-languages
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'org-babel-load-languages</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; Do not ask to confirm evaluations</span>
|
||
</span></span><span style="display:flex;"><span>(setq org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><<guix-tables>>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; A few dummy modes to avoid being prompted for comment systax</span>
|
||
</span></span><span style="display:flex;"><span>(define-derived-mode fish-mode prog-mode <span style="color:#e6db74">"Fish"</span>
|
||
</span></span><span style="display:flex;"><span> (setq-local comment-start <span style="color:#e6db74">"# "</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local comment-start-skip <span style="color:#e6db74">"#+[\t ]*"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(define-derived-mode yaml-mode text-mode <span style="color:#e6db74">"YAML"</span>
|
||
</span></span><span style="display:flex;"><span> (setq-local comment-start <span style="color:#e6db74">"# "</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local comment-start-skip <span style="color:#e6db74">"#+ *"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'</span>org-babel-tangle-file
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"/home/pavel/Emacs.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Desktop.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Console.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Guix.org"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"/home/pavel/Mail.org"</span>))
|
||
</span></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"><span style="display:flex;"><span>emacs -Q --batch -l run-tangle.el
|
||
</span></span></code></pre></div><p>I have added this line to yadm’s <code>post_alt</code> hook, so tangle is run after <code>yadm alt</code></p>
|
||
<h2 id="applications">Applications</h2>
|
||
<h3 id="dired">Dired</h3>
|
||
<p>Dired is a built-in file manager. I currently use it as my primary file manager.</p>
|
||
<h4 id="basic-config-and-keybindings">Basic config & keybindings</h4>
|
||
<p>My config mostly follows ranger’s and vifm’s keybindings which I’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"><span style="display:flex;"><span>(use-package dired
|
||
</span></span><span style="display:flex;"><span> :ensure <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :custom ((dired-listing-switches <span style="color:#e6db74">"-alh --group-directories-first"</span>))
|
||
</span></span><span style="display:flex;"><span> :commands (dired)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq dired-dwim-target <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq wdired-allow-to-change-permissions <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq wdired-create-parent-directories <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq dired-recursive-copies <span style="color:#e6db74">'always</span>)
|
||
</span></span><span style="display:flex;"><span> (setq dired-recursive-deletes <span style="color:#e6db74">'always</span>)
|
||
</span></span><span style="display:flex;"><span> (setq dired-kill-when-opening-new-dired-buffer <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'dired-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (setq truncate-lines <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (visual-line-mode <span style="color:#66d9ef">nil</span>)))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'dired-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'dired-up-directory</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'dired-find-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"="</span> <span style="color:#e6db74">'dired-narrow</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"-"</span> <span style="color:#e6db74">'dired-create-empty-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'vterm</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<left>"</span> <span style="color:#e6db74">'dired-up-directory</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<right>"</span> <span style="color:#e6db74">'dired-find-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<return>"</span> <span style="color:#e6db74">'dired-open-xdg</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/dired-home ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Open dired at $HOME"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (dired (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~"</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ad"</span> <span style="color:#a6e22e">#'</span>dired)
|
||
</span></span></code></pre></div><h4 id="addons">Addons</h4>
|
||
<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"><span style="display:flex;"><span>(use-package diredfl
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (dired)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (diredfl-global-mode <span style="color:#ae81ff">1</span>))
|
||
</span></span></code></pre></div><p><a href="https://github.com/Fuco1/dired-hacks#dired-subtree">dired-subtree</a> is a package that enables managing Dired buffers in a tree-like manner. By default <code>evil-collection</code> maps <code>dired-subtree-toggle</code> to <code>TAB</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"><span style="display:flex;"><span>(use-package dired-subtree
|
||
</span></span><span style="display:flex;"><span> :after (dired)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><p><a href="https://github.com/jojojames/dired-sidebar">dired-sidebar</a> enables opening Dired in sidebar. For me, with dired-subtree this makes dired a better option than Treemacs.</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="display:flex;"><span>(use-package dired-sidebar
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (dired)
|
||
</span></span><span style="display:flex;"><span> :commands (dired-sidebar-toggle-sidebar)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(normal override global)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-n"</span> <span style="color:#e6db74">'dired-sidebar-toggle-sidebar</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (defun my/dired-sidebar-setup ()
|
||
</span></span><span style="display:flex;"><span> (toggle-truncate-lines <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span> (display-line-numbers-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local dired-subtree-use-backgrounds <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'dired-sidebar-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'dired-sidebar-find-file</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'dired-sidebar-up-directory</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"="</span> <span style="color:#e6db74">'dired-narrow</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'dired-sidebar-mode-hook</span> <span style="color:#a6e22e">#'</span>my/dired-sidebar-setup))
|
||
</span></span></code></pre></div><p><a href="https://github.com/vifon/dired-recent.el">dired-recent.el</a> adds history to dired.</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="display:flex;"><span>(use-package dired-recent
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after dired
|
||
</span></span><span style="display:flex;"><span> :commands (dired-recent-open)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (dired-recent-mode)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'dired-recent-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-x C-d"</span> <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"aD"</span> <span style="color:#f92672">'</span>(dired-recent-open :wk <span style="color:#e6db74">"dired history"</span>)))
|
||
</span></span></code></pre></div><p><del>Reuse the current dired buffer instead of spamming new ones.</del> Looks like not necessary 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"><span style="display:flex;"><span>(use-package dired-single
|
||
</span></span><span style="display:flex;"><span> :after dired
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package all-the-icons-dired
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not (or my/lowpower my/slow-ssh (not (display-graphic-p))))
|
||
</span></span><span style="display:flex;"><span> :hook (dired-mode <span style="color:#f92672">.</span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (unless (string-match-p <span style="color:#e6db74">"/gnu/store"</span> default-directory)
|
||
</span></span><span style="display:flex;"><span> (all-the-icons-dired-mode))))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dired-add-entry</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dired-remove-entry</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'dired-kill-subdir</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package dired-open
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (dired-open-xdg))
|
||
</span></span></code></pre></div><p><a href="https://elpa.gnu.org/packages/dired-du.html">dired-du</a> is a package that shows directory sizes</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="display:flex;"><span>(use-package dired-du
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (dired-du-mode)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq dired-du-size-format <span style="color:#66d9ef">t</span>))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package dired-narrow
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (dired-narrow)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'dired-narrow-map</span>
|
||
</span></span><span style="display:flex;"><span> [escape] <span style="color:#e6db74">'keyboard-quit</span>))
|
||
</span></span></code></pre></div><p>Display git info, such as the last commit for file and stuff. It’s pretty useful but also slows down Dired a bit, hence I don’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"><span style="display:flex;"><span>(use-package dired-git-info
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after dired
|
||
</span></span><span style="display:flex;"><span> :if (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymap <span style="color:#e6db74">'dired-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal emacs)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">")"</span> <span style="color:#e6db74">'dired-git-info-mode</span>))
|
||
</span></span></code></pre></div><h4 id="subdirectories">Subdirectories</h4>
|
||
<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"><span style="display:flex;"><span>(defun my/dired-open-this-subdir ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (dired (dired-current-directory)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/dired-kill-all-subdirs ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((dir dired-directory))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
|
||
</span></span><span style="display:flex;"><span> (dired dir)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'dired</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'dired-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ss"</span> <span style="color:#e6db74">'dired-maybe-insert-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sl"</span> <span style="color:#e6db74">'dired-maybe-insert-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sq"</span> <span style="color:#e6db74">'dired-kill-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sk"</span> <span style="color:#e6db74">'dired-prev-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sj"</span> <span style="color:#e6db74">'dired-next-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sS"</span> <span style="color:#e6db74">'my/dired-open-this-subdir</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"sQ"</span> <span style="color:#e6db74">'my/dired-kill-all-subdirs</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"TAB"</span>) <span style="color:#e6db74">'dired-hide-subdir</span>))
|
||
</span></span></code></pre></div><h4 id="tramp">TRAMP</h4>
|
||
<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"><span style="display:flex;"><span>(setq tramp-verbose <span style="color:#ae81ff">1</span>)
|
||
</span></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’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’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"><span style="display:flex;"><span>(setq remote-file-name-inhibit-cache <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>(setq vc-ignore-dir-regexp
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"\\(%s\\)\\|\\(%s\\)"</span>
|
||
</span></span><span style="display:flex;"><span> vc-ignore-dir-regexp
|
||
</span></span><span style="display:flex;"><span> tramp-file-name-regexp))
|
||
</span></span></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"><span style="display:flex;"><span>(when (or my/remote-server my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> (setq explicit-shell-file-name <span style="color:#e6db74">"/bin/bash"</span>))
|
||
</span></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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'tramp</span>
|
||
</span></span><span style="display:flex;"><span> (setq tramp-remote-path
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">append</span> tramp-remote-path
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(tramp-own-remote-path))))
|
||
</span></span></code></pre></div><h4 id="bookmarks">Bookmarks</h4>
|
||
<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/private.el">private.el</a> file, which has an expression 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"><span style="display:flex;"><span>(setq my/dired-bookmarks
|
||
</span></span><span style="display:flex;"><span> '(("sudo" . "/sudo::/")))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/dired-bookmark-open ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((bookmarks
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%-30s %s"</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
|
||
</span></span><span style="display:flex;"><span> my/dired-bookmarks)))
|
||
</span></span><span style="display:flex;"><span> (dired
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">assoc</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Dired: "</span> bookmarks <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"^"</span>)
|
||
</span></span><span style="display:flex;"><span> bookmarks)))))
|
||
</span></span></code></pre></div><h3 id="shells">Shells</h3>
|
||
<h4 id="vterm">vterm</h4>
|
||
<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>
|
||
<h5 id="configuration">Configuration</h5>
|
||
<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"><span style="display:flex;"><span>(use-package vterm
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; :straight t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (vterm vterm-other-window)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq vterm-kill-buffer-on-exit <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'vterm-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (setq-local global-display-line-numbers-mode <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'evil-collection-vterm-insert</span>
|
||
</span></span><span style="display:flex;"><span> :before (lambda (<span style="color:#66d9ef">&rest</span> args)
|
||
</span></span><span style="display:flex;"><span> (ignore-errors
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'</span>vterm-reset-cursor-point args))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-q"</span> <span style="color:#e6db74">'vterm-send-escape</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<right>"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<left>"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<up>"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-<down>"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<left>"</span> <span style="color:#e6db74">'vterm-send-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<right>"</span> <span style="color:#e6db74">'vterm-send-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<up>"</span> <span style="color:#e6db74">'vterm-send-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-<down>"</span> <span style="color:#e6db74">'vterm-send-down</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<home>"</span> <span style="color:#e6db74">'vterm-beginning-of-line</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<end>"</span> <span style="color:#e6db74">'vterm-end-of-line</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-r"</span> <span style="color:#e6db74">'vterm-send-C-r</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'vterm-send-C-k</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'vterm-send-C-j</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-l"</span> <span style="color:#e6db74">'vterm-send-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-h"</span> <span style="color:#e6db74">'vterm-send-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-k"</span> <span style="color:#e6db74">'vterm-send-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"M-j"</span> <span style="color:#e6db74">'vterm-send-down</span>))
|
||
</span></span></code></pre></div><h5 id="subterminal">Subterminal</h5>
|
||
<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"><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'display-buffer-alist</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span><span style="color:#e6db74">"vterm-subterminal.*"</span>
|
||
</span></span><span style="display:flex;"><span> (display-buffer-reuse-window
|
||
</span></span><span style="display:flex;"><span> display-buffer-in-side-window)
|
||
</span></span><span style="display:flex;"><span> (side <span style="color:#f92672">.</span> bottom)
|
||
</span></span><span style="display:flex;"><span> (reusable-frames <span style="color:#f92672">.</span> visible)
|
||
</span></span><span style="display:flex;"><span> (window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/toggle-vterm-subteminal ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Toogle subteminal."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let
|
||
</span></span><span style="display:flex;"><span> ((vterm-window
|
||
</span></span><span style="display:flex;"><span> (seq-find
|
||
</span></span><span style="display:flex;"><span> (lambda (window)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-match</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"vterm-subterminal.*"</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">buffer-name</span> (<span style="color:#a6e22e">window-buffer</span> window))))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">window-list</span>))))
|
||
</span></span><span style="display:flex;"><span> (if vterm-window
|
||
</span></span><span style="display:flex;"><span> (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></span><span style="display:flex;"><span> (<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">select-window</span> vterm-window))
|
||
</span></span><span style="display:flex;"><span> (vterm-other-window <span style="color:#e6db74">"vterm-subterminal"</span>))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(unless my/slow-ssh
|
||
</span></span><span style="display:flex;"><span> (general-nmap <span style="color:#e6db74">"`"</span> <span style="color:#e6db74">'my/toggle-vterm-subteminal</span>)
|
||
</span></span><span style="display:flex;"><span> (general-nmap <span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'vterm</span>))
|
||
</span></span></code></pre></div><h5 id="dired-integration">Dired integration</h5>
|
||
<p>A function to get pwd for vterm. Couldn’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"><span style="display:flex;"><span>(defun my/vterm-get-pwd ()
|
||
</span></span><span style="display:flex;"><span> (if vterm--process
|
||
</span></span><span style="display:flex;"><span> (file-truename (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"/proc/%d/cwd"</span> (<span style="color:#a6e22e">process-id</span> vterm--process)))
|
||
</span></span><span style="display:flex;"><span> default-directory))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/vterm-dired-other-window ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Open dired in vterm pwd in other window"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (dired-other-window (my/vterm-get-pwd)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/vterm-dired-replace ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Replace vterm with dired"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((pwd (my/vterm-get-pwd)))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">kill-process</span> vterm--process)
|
||
</span></span><span style="display:flex;"><span> (dired pwd)))
|
||
</span></span></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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'vterm</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gd"</span> <span style="color:#a6e22e">#'</span>my/vterm-dired-other-window
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gD"</span> <span style="color:#a6e22e">#'</span>my/vterm-dired-replace))
|
||
</span></span></code></pre></div><h5 id="with-editor-integration">With-editor integration</h5>
|
||
<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/#functions">this function</a>, I can just write <code>e <filename></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"><span style="display:flex;"><span>(use-package with-editor
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (vterm)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'vterm-mode-hook</span> <span style="color:#e6db74">'with-editor-export-editor</span>))
|
||
</span></span></code></pre></div><h4 id="eshell">Eshell</h4>
|
||
<p>A shell written in Emacs lisp. I don’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"><span style="display:flex;"><span>(defun my/configure-eshell ()
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'eshell-pre-command-hook</span> <span style="color:#e6db74">'eshell-save-some-history</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'eshell-output-filter-functions</span> <span style="color:#e6db74">'eshell-truncate-buffer</span>)
|
||
</span></span><span style="display:flex;"><span> (setq eshell-history-size <span style="color:#ae81ff">10000</span>)
|
||
</span></span><span style="display:flex;"><span> (setq eshell-hist-ingnoredups <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq eshell-buffer-maximum-lines <span style="color:#ae81ff">10000</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (evil-define-key <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span> visual) eshell-mode-map (kbd <span style="color:#e6db74">"<home>"</span>) <span style="color:#e6db74">'eshell-bol</span>)
|
||
</span></span><span style="display:flex;"><span> (evil-define-key <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span> visual) eshell-mode-map (kbd <span style="color:#e6db74">"C-r"</span>) <span style="color:#e6db74">'counsel-esh-history</span>)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'eshell-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"C-h"</span>) <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"C-l"</span>) <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"C-k"</span>) <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"C-j"</span>) <span style="color:#e6db74">'evil-window-down</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package eshell
|
||
</span></span><span style="display:flex;"><span> :ensure <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :after evil-collection
|
||
</span></span><span style="display:flex;"><span> :commands (eshell)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span> (epe-pipeline-delimiter-face :foreground (doom-color <span style="color:#e6db74">'green</span>))
|
||
</span></span><span style="display:flex;"><span> (epe-pipeline-host-face :foreground (doom-color <span style="color:#e6db74">'blue</span>))
|
||
</span></span><span style="display:flex;"><span> (epe-pipeline-time-face :foreground (doom-color <span style="color:#e6db74">'yellow</span>))
|
||
</span></span><span style="display:flex;"><span> (epe-pipeline-user-face :foreground (doom-color <span style="color:#e6db74">'red</span>)))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'eshell-first-time-mode-hook</span> <span style="color:#e6db74">'my/configure-eshell</span> <span style="color:#ae81ff">90</span>)
|
||
</span></span><span style="display:flex;"><span> (when my/slow-ssh
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'eshell-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (setq-local company-idle-delay <span style="color:#ae81ff">1000</span>))))
|
||
</span></span><span style="display:flex;"><span> (setq eshell-banner-message <span style="color:#e6db74">""</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package aweshell
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"manateelazycat/aweshell"</span> :host github)
|
||
</span></span><span style="display:flex;"><span> :after eshell
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span> (aweshell-alert-buffer-face :background (color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>))
|
||
</span></span><span style="display:flex;"><span> (aweshell-alert-command-face :foreground (doom-color <span style="color:#e6db74">'red</span>) :weight <span style="color:#e6db74">'bold</span>))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq eshell-highlight-prompt <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (setq eshell-prompt-function <span style="color:#e6db74">'epe-theme-pipeline</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package eshell-info-banner
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> :straight (eshell-info-banner :type git
|
||
</span></span><span style="display:flex;"><span> :host github
|
||
</span></span><span style="display:flex;"><span> :repo <span style="color:#e6db74">"phundrak/eshell-info-banner.el"</span>)
|
||
</span></span><span style="display:flex;"><span> :hook (eshell-banner-load <span style="color:#f92672">.</span> eshell-info-banner-update-banner))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(when my/slow-ssh
|
||
</span></span><span style="display:flex;"><span> (general-nmap <span style="color:#e6db74">"`"</span> <span style="color:#e6db74">'aweshell-dedicated-toggle</span>)
|
||
</span></span><span style="display:flex;"><span> (general-nmap <span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'eshell</span>))
|
||
</span></span></code></pre></div><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"><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; "C-c c" (my/command-in-persp "Emacs.org" "conf" 1 (find-file "~/Emacs.org"))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c c"</span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(lambda () (interactive) (find-file <span style="color:#e6db74">"~/Emacs.org"</span>)) :wk <span style="color:#e6db74">"Emacs.org"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"c"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"configuration"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; "c" (my/command-in-persp "Emacs.org" "conf" 1 (find-file "~/Emacs.org"))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(lambda () (interactive) (find-file <span style="color:#e6db74">"~/Emacs.org"</span>)) :wk <span style="color:#e6db74">"Emacs.org"</span>))
|
||
</span></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_magit/">https://www.reddit.com/r/emacs/comments/gjukb3/yadm_magit/</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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'tramp</span>
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'tramp-methods</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(<span style="color:#e6db74">"yadm"</span>
|
||
</span></span><span style="display:flex;"><span> (tramp-login-program <span style="color:#e6db74">"yadm"</span>)
|
||
</span></span><span style="display:flex;"><span> (tramp-login-args ((<span style="color:#e6db74">"enter"</span>)))
|
||
</span></span><span style="display:flex;"><span> (tramp-login-env ((<span style="color:#e6db74">"SHELL"</span>) <span style="color:#e6db74">"/bin/sh"</span>))
|
||
</span></span><span style="display:flex;"><span> (tramp-remote-shell <span style="color:#e6db74">"/bin/sh"</span>)
|
||
</span></span><span style="display:flex;"><span> (tramp-remote-shell-args (<span style="color:#e6db74">"-c"</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/yadm-magit ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (magit-status <span style="color:#e6db74">"/yadm::"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"cm"</span> <span style="color:#e6db74">'my/yadm-magit</span>)
|
||
</span></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"><span style="display:flex;"><span>(defun my/open-yadm-file ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Open a file managed by yadm"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (find-file
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">file-name-as-directory</span> (getenv <span style="color:#e6db74">"HOME"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">completing-read</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"yadm files: "</span>
|
||
</span></span><span style="display:flex;"><span> (split-string
|
||
</span></span><span style="display:flex;"><span> (shell-command-to-string <span style="color:#e6db74">"yadm ls-files $HOME --full-name"</span>) <span style="color:#e6db74">"\n"</span>)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-c f"</span> <span style="color:#f92672">'</span>(my/open-yadm-file :wk <span style="color:#e6db74">"yadm file"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"cf"</span> <span style="color:#f92672">'</span>(my/open-yadm-file :wk <span style="color:#e6db74">"yadm file"</span>))
|
||
</span></span></code></pre></div><h3 id="internet-and-multimedia">Internet & 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"><span style="display:flex;"><span>(unless (or my/is-termux my/remote-server)
|
||
</span></span><span style="display:flex;"><span> (let ((mail-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"mail.el"</span> user-emacs-directory)))
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">file-exists-p</span> mail-file)
|
||
</span></span><span style="display:flex;"><span> (load-file mail-file)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Can't load mail.el"</span>))))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package elfeed
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"SqrtMinusOne/elfeed"</span> :host github)
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :commands (elfeed)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ae"</span> (my/command-in-persp <span style="color:#e6db74">"elfeed"</span> <span style="color:#e6db74">"elfeed"</span> <span style="color:#ae81ff">0</span> (elfeed-summary)))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-db-directory <span style="color:#e6db74">"~/.elfeed"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-enclosure-default-dir (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Downloads"</span>))
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>elfeed-insert-html
|
||
</span></span><span style="display:flex;"><span> :around
|
||
</span></span><span style="display:flex;"><span> (lambda (fun <span style="color:#66d9ef">&rest</span> r)
|
||
</span></span><span style="display:flex;"><span> (let ((shr-use-fonts <span style="color:#66d9ef">nil</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> fun r))))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'elfeed-search-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"o"</span> <span style="color:#a6e22e">#'</span>my/elfeed-search-filter-source
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"c"</span> <span style="color:#a6e22e">#'</span>elfeed-search-clear-filter
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gl"</span> (lambda () (interactive) (elfeed-search-set-filter <span style="color:#e6db74">"+later"</span>)))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'elfeed-show-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ge"</span> <span style="color:#a6e22e">#'</span>my/elfeed-show-visit-eww))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package elfeed-org
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (elfeed)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq rmh-elfeed-org-files <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/.emacs.d/private.org"</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-org))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/elfeed-search-filter-source (entry)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Filter elfeed search buffer by the feed under cursor."</span>
|
||
</span></span><span style="display:flex;"><span> (interactive (<span style="color:#a6e22e">list</span> (elfeed-search-selected :ignore-region)))
|
||
</span></span><span style="display:flex;"><span> (when (elfeed-entry-p entry)
|
||
</span></span><span style="display:flex;"><span> (elfeed-search-set-filter
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"@6-months-ago "</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"+unread "</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"="</span>
|
||
</span></span><span style="display:flex;"><span> (replace-regexp-in-string
|
||
</span></span><span style="display:flex;"><span> (rx <span style="color:#e6db74">"?"</span> (<span style="color:#a6e22e">*</span> not-newline) eos)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span>
|
||
</span></span><span style="display:flex;"><span> (elfeed-feed-url (elfeed-entry-feed entry)))))))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/elfeed-show-visit-eww ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Visit the current entry in eww"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((link (elfeed-entry-link elfeed-show-entry)))
|
||
</span></span><span style="display:flex;"><span> (when link
|
||
</span></span><span style="display:flex;"><span> (eww link))))
|
||
</span></span></code></pre></div><h5 id="custom-faces">Custom faces</h5>
|
||
<p>Setting up custom faces for certain tags to make the feed look a bit nicer.</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="display:flex;"><span>(defface elfeed-videos-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tag \"videos\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defface elfeed-twitter-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tah \"twitter\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defface elfeed-emacs-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tah \"emacs\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defface elfeed-music-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tah \"music\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defface elfeed-podcasts-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tag \"podcasts\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defface elfeed-blogs-entry <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Face for the elfeed entries with tag \"blogs\""</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my/use-doom-colors
|
||
</span></span><span style="display:flex;"><span>(elfeed-search-tag-face :foreground (doom-color <span style="color:#e6db74">'yellow</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-videos-entry :foreground (doom-color <span style="color:#e6db74">'red</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-twitter-entry :foreground (doom-color <span style="color:#e6db74">'blue</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-emacs-entry :foreground (doom-color <span style="color:#e6db74">'magenta</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-music-entry :foreground (doom-color <span style="color:#e6db74">'green</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-podcasts-entry :foreground (doom-color <span style="color:#e6db74">'yellow</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-blogs-entry :foreground (doom-color <span style="color:#e6db74">'orange</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'elfeed</span>
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-search-face-alist
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((twitter elfeed-twitter-entry)
|
||
</span></span><span style="display:flex;"><span> (podcasts elfeed-podcasts-entry)
|
||
</span></span><span style="display:flex;"><span> (music elfeed-music-entry)
|
||
</span></span><span style="display:flex;"><span> (videos elfeed-videos-entry)
|
||
</span></span><span style="display:flex;"><span> (emacs elfeed-emacs-entry)
|
||
</span></span><span style="display:flex;"><span> (blogs elfeed-blogs-entry)
|
||
</span></span><span style="display:flex;"><span> (unread elfeed-search-unread-title-face))))
|
||
</span></span></code></pre></div><p>Also, a function to automatically adjust these colors with the Doom theme.</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="display:flex;"><span>(defun my/update-my-theme-elfeed (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (custom-theme-set-faces
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'my-theme-1</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-videos-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'red</span>))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-twitter-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'blue</span>))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-emacs-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'magenta</span>))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-music-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'green</span>))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-podcasts-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>(elfeed-blogs-entry ((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'orange</span>)))))
|
||
</span></span><span style="display:flex;"><span> (enable-theme <span style="color:#e6db74">'my-theme-1</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(advice-add <span style="color:#e6db74">'load-theme</span> :after <span style="color:#a6e22e">#'</span>my/update-my-theme-elfeed)
|
||
</span></span><span style="display:flex;"><span>(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'doom-color</span>)
|
||
</span></span><span style="display:flex;"><span> (my/update-my-theme-elfeed))
|
||
</span></span></code></pre></div><h5 id="elfeed-summary">elfeed-summary</h5>
|
||
<p><a href="https://github.com/SqrtMinusOne/elfeed-summary">elfeed-summary</a> is my package that provides a feed summary interface for elfeed.</p>
|
||
<p>The default interface of elfeed is just a list of all entries, so it gets hard to navigate when there are a lot of sources with varying frequencies of posts. This is my attempt to address this 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"><span style="display:flex;"><span>(use-package elfeed-summary
|
||
</span></span><span style="display:flex;"><span> :commands (elfeed-summary)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></span></code></pre></div><h5 id="elfeed-score">elfeed-score</h5>
|
||
<p><a href="https://github.com/sp1ff/elfeed-score">elfeed-score</a> is a package that implements scoring for the elfeed entries. Entries are scored by a set of rules for tags/title/content/etc and sorted by that score.</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="display:flex;"><span>(defun my/elfeed-toggle-score-sort ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-search-sort-function
|
||
</span></span><span style="display:flex;"><span> (if elfeed-search-sort-function
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">#'</span>elfeed-score-sort))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Sorting by score: %S"</span> (if elfeed-search-sort-function <span style="color:#e6db74">"ON"</span> <span style="color:#e6db74">"OFF"</span>))
|
||
</span></span><span style="display:flex;"><span> (elfeed-search-update--force))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package elfeed-score
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (elfeed)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-score-serde-score-file <span style="color:#e6db74">"~/.emacs.d/elfeed.score"</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (elfeed-score-enable)
|
||
</span></span><span style="display:flex;"><span> (setq elfeed-search-print-entry-function <span style="color:#a6e22e">#'</span>elfeed-score-print-entry)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(elfeed-search-mode-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"="</span> elfeed-score-map)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#f92672">'</span>(elfeed-score-map)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"="</span> <span style="color:#a6e22e">#'</span>my/elfeed-toggle-score-sort))
|
||
</span></span></code></pre></div><h5 id="youtube-podcasts-and-emms">YouTube, podcasts & EMMS</h5>
|
||
<p>Previously this block was opening MPV with <code>start-process</code>, but now I’ve managed to hook up MPV with EMMS. So there is the EMMS+elfeed “integration”.</p>
|
||
<p>There are multiple kinds of entries that I want to be opened by EMMS. First, a function that returns a YouTube URL:</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="display:flex;"><span>(defun my/get-youtube-url (entry)
|
||
</span></span><span style="display:flex;"><span> (let ((watch-id (cadr
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">"watch?v"</span>
|
||
</span></span><span style="display:flex;"><span> (url-parse-query-string
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">substring</span>
|
||
</span></span><span style="display:flex;"><span> (url-filename
|
||
</span></span><span style="display:flex;"><span> (url-generic-parse-url (elfeed-entry-link entry)))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">1</span>))))))
|
||
</span></span><span style="display:flex;"><span> (when watch-id
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"https://www.youtube.com/watch?v="</span> watch-id))))
|
||
</span></span></code></pre></div><p>Second, a function that returns a URL to an enclosure. This is generally how podcasts are distributed.</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="display:flex;"><span>(defun my/get-enclosures-url (entry)
|
||
</span></span><span style="display:flex;"><span> (caar (elfeed-entry-enclosures entry)))
|
||
</span></span></code></pre></div><p>Now, a function to add a 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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
</span></span><span style="display:flex;"><span> (define-emms-source elfeed (entry)
|
||
</span></span><span style="display:flex;"><span> (let ((url (or (my/get-enclosures-url entry)
|
||
</span></span><span style="display:flex;"><span> (my/get-youtube-url entry))))
|
||
</span></span><span style="display:flex;"><span> (unless url
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">error</span> <span style="color:#e6db74">"URL not found"</span>))
|
||
</span></span><span style="display:flex;"><span> (let ((track (emms-track <span style="color:#e6db74">'url</span> url)))
|
||
</span></span><span style="display:flex;"><span> (emms-track-set track <span style="color:#e6db74">'info-title</span> (elfeed-entry-title entry))
|
||
</span></span><span style="display:flex;"><span> (emms-playlist-insert-track track)))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/elfeed-add-emms ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (emms-add-elfeed elfeed-show-entry)
|
||
</span></span><span style="display:flex;"><span> (elfeed-tag elfeed-show-entry <span style="color:#e6db74">'watched</span>)
|
||
</span></span><span style="display:flex;"><span> (elfeed-show-refresh))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'elfeed</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'elfeed-show-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gm"</span> <span style="color:#a6e22e">#'</span>my/elfeed-add-emms))
|
||
</span></span></code></pre></div><h4 id="emms">EMMS</h4>
|
||
<p>EMMS is the Emacs Multi-Media System. I use it to control MPD & 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’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"><span style="display:flex;"><span>(use-package emms
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (not my/remote-server)
|
||
</span></span><span style="display:flex;"><span> :commands (emms-smart-browse
|
||
</span></span><span style="display:flex;"><span> emms-browser
|
||
</span></span><span style="display:flex;"><span> emms-add-url
|
||
</span></span><span style="display:flex;"><span> emms-add-file
|
||
</span></span><span style="display:flex;"><span> emms-add-find)
|
||
</span></span><span style="display:flex;"><span> :if (not my/is-termux)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"as"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"emms"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> (my/command-in-persp <span style="color:#e6db74">"emms"</span> <span style="color:#e6db74">"EMMS"</span> <span style="color:#ae81ff">0</span> (emms-smart-browse))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'emms-browser</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'emms-pause</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'emms-stop</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'emms-previous</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'emms-next</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'emms-player-mpd-connect</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ww"</span> <span style="color:#e6db74">'emms-lyrics</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"wb"</span> <span style="color:#e6db74">'emms-lyrics-toggle-display-on-minibuffer</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"wm"</span> <span style="color:#e6db74">'emms-lyrics-toggle-display-on-modeline</span>)
|
||
</span></span><span style="display:flex;"><span> (setq emms-mode-line-icon-enabled-p <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'emms-setup</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'emms-player-mpd</span>)
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'emms-player-mpv</span>)
|
||
</span></span><span style="display:flex;"><span> (emms-all)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; MPD setup</span>
|
||
</span></span><span style="display:flex;"><span> <<emms-mpd-setup>>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; MPV setup</span>
|
||
</span></span><span style="display:flex;"><span> <<emms-mpv-setup>>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; evil-lion and evil-commentary shadow some gX bindings</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (add-hook 'emms-browser-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (lambda ()</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (evil-lion-mode -1)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; (evil-commentary-mode -1)</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; ))</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; I have everything I need in polybar</span>
|
||
</span></span><span style="display:flex;"><span> (emms-mode-line-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (emms-playing-time-display-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> <<emms-fixes>>)
|
||
</span></span></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"><span style="display:flex;"><span>(setq emms-source-file-default-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Music/"</span>))
|
||
</span></span><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'emms-info-functions</span> <span style="color:#e6db74">'emms-info-mpd</span>)
|
||
</span></span><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'emms-player-list</span> <span style="color:#e6db74">'emms-player-mpd</span>)
|
||
</span></span><span style="display:flex;"><span>(setq emms-player-mpd-server-name <span style="color:#e6db74">"localhost"</span>)
|
||
</span></span><span style="display:flex;"><span>(setq emms-player-mpd-server-port <span style="color:#e6db74">"6600"</span>)
|
||
</span></span><span style="display:flex;"><span>(setq emms-player-mpd-music-directory <span style="color:#e6db74">"~/Music"</span>)
|
||
</span></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"><span style="display:flex;"><span>(emms-player-mpd-connect)
|
||
</span></span></code></pre></div><p>Clear MPD playlist on clearing EMMS playlist. IDK if this is fine for MPD library playlist, I don’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"><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'emms-playlist-cleared-hook</span> <span style="color:#e6db74">'emms-player-mpd-clear</span>)
|
||
</span></span></code></pre></div><p>Set a custom regex for MPD. EMMS sets up the default one from MPD’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"><span style="display:flex;"><span>(emms-player-set emms-player-mpd
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'regex</span>
|
||
</span></span><span style="display:flex;"><span> (rx (or (<span style="color:#f92672">:</span> <span style="color:#e6db74">"https://"</span> (<span style="color:#a6e22e">*</span> nonl) (or <span style="color:#e6db74">"acast.com"</span>) (<span style="color:#a6e22e">*</span> nonl))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">+</span> (<span style="color:#e6db74">? </span>(or <span style="color:#e6db74">"https://"</span> <span style="color:#e6db74">"http://"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">*</span> nonl)
|
||
</span></span><span style="display:flex;"><span> (regexp (<span style="color:#a6e22e">eval</span> (emms-player-simple-regexp
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"m3u"</span> <span style="color:#e6db74">"ogg"</span> <span style="color:#e6db74">"flac"</span> <span style="color:#e6db74">"mp3"</span> <span style="color:#e6db74">"wav"</span> <span style="color:#e6db74">"mod"</span> <span style="color:#e6db74">"au"</span> <span style="color:#e6db74">"aiff"</span> <span style="color:#e6db74">"m4a"</span>)))))))
|
||
</span></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>yt-dlp</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 <del>youtube-dl</del> yt-dlp.</p>
|
||
<p>It looks like YouTube has started to throttle youtube-dl, and yt-dlp has a workaround for that particular case. Just don’t forget to add the following like to the mpv 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="display:flex;"><span><span style="color:#a6e22e">script-opts</span><span style="color:#f92672">=</span><span style="color:#e6db74">ytdl_hook-ytdl_path=yt-dlp</span>
|
||
</span></span></code></pre></div><p>It seems a bit strange to keep the MPV config in this file, but I don’t use the program outside 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"><span style="display:flex;"><span>(add-to-list <span style="color:#e6db74">'emms-player-list</span> <span style="color:#e6db74">'emms-player-mpv</span>)
|
||
</span></span></code></pre></div><p>Also a custom regex. My demands for MPV include running <code>yt-dlp</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"><span style="display:flex;"><span>(emms-player-set emms-player-mpv
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'regex</span>
|
||
</span></span><span style="display:flex;"><span> (rx (or (<span style="color:#f92672">:</span> <span style="color:#e6db74">"https://"</span> (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">"youtube.com"</span> (<span style="color:#a6e22e">*</span> nonl))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">+</span> (<span style="color:#e6db74">? </span>(or <span style="color:#e6db74">"https://"</span> <span style="color:#e6db74">"http://"</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">*</span> nonl)
|
||
</span></span><span style="display:flex;"><span> (regexp (<span style="color:#a6e22e">eval</span> (emms-player-simple-regexp
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"mp4"</span> <span style="color:#e6db74">"mov"</span> <span style="color:#e6db74">"wmv"</span> <span style="color:#e6db74">"webm"</span> <span style="color:#e6db74">"flv"</span> <span style="color:#e6db74">"avi"</span> <span style="color:#e6db74">"mkv"</span>)))))))
|
||
</span></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"><span style="display:flex;"><span>(setq my/youtube-dl-quality-list
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"bestvideo[height<=720]+bestaudio/best[height<=720]"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"bestvideo[height<=480]+bestaudio/best[height<=480]"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"bestvideo[height<=1080]+bestaudio/best[height<=1080]"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq my/default-emms-player-mpv-parameters
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"--quiet"</span> <span style="color:#e6db74">"--really-quiet"</span> <span style="color:#e6db74">"--no-audio-display"</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/set-emms-mpd-youtube-quality (quality)
|
||
</span></span><span style="display:flex;"><span> (interactive <span style="color:#e6db74">"P"</span>)
|
||
</span></span><span style="display:flex;"><span> (unless quality
|
||
</span></span><span style="display:flex;"><span> (setq quality (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Quality: "</span> my/youtube-dl-quality-list <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)))
|
||
</span></span><span style="display:flex;"><span> (setq emms-player-mpv-parameters
|
||
</span></span><span style="display:flex;"><span> <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">"--ytdl-format=%s"</span> quality))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my/set-emms-mpd-youtube-quality (<span style="color:#a6e22e">car</span> my/youtube-dl-quality-list))
|
||
</span></span></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’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"><span style="display:flex;"><span>(defun my/emms-cleanup-urls ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (let ((keys-to-delete <span style="color:#f92672">'</span>()))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">maphash</span> (lambda (key value)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'type</span> value)) <span style="color:#e6db74">'url</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'keys-to-delete</span> key)))
|
||
</span></span><span style="display:flex;"><span> emms-cache-db)
|
||
</span></span><span style="display:flex;"><span> (dolist (key keys-to-delete)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">remhash</span> key emms-cache-db)))
|
||
</span></span><span style="display:flex;"><span> (setq emms-cache-dirty <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"asc"</span> <span style="color:#a6e22e">#'</span>my/emms-cleanup-urls)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package lyrics-fetcher
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (emms)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"ast"</span> <span style="color:#a6e22e">#'</span>lyrics-fetcher-show-lyrics
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"asT"</span> <span style="color:#a6e22e">#'</span>lyrics-fetcher-show-lyrics-query)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq lyrics-fetcher-genius-access-token
|
||
</span></span><span style="display:flex;"><span> (password-store-get <span style="color:#e6db74">"My_Online/APIs/genius.com"</span>))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(emacs normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'emms-browser-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gl"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-show-at-point</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"gC"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-fetch-covers-at-point</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"go"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-open-large-cover-at-point</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>emms-lyrics-mode-line
|
||
</span></span><span style="display:flex;"><span> :override <span style="color:#a6e22e">#'</span>my/emms-lyrics-mode-line-override))
|
||
</span></span></code></pre></div><p>Also advice to change the location of the lyrics in the mode 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"><span style="display:flex;"><span>(defun my/emms-lyrics-mode-line-override ()
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'global-mode-string</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(:eval emms-lyrics-mode-line-string)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/emms-lyrics-restore-mode-line-override ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Restore the mode line."</span>
|
||
</span></span><span style="display:flex;"><span> (setq global-mode-string
|
||
</span></span><span style="display:flex;"><span> (remove <span style="color:#f92672">'</span>(:eval emms-lyrics-mode-line-string) global-mode-string))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">force-mode-line-update</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'emms-lyrics</span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>emms-lyrics-mode-line
|
||
</span></span><span style="display:flex;"><span> :override <span style="color:#a6e22e">#'</span>my/emms-lyrics-mode-line-override)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>emms-lyrics-restore-mode-line
|
||
</span></span><span style="display:flex;"><span> :override <span style="color:#a6e22e">#'</span>my/emms-lyrics-restore-mode-line-override))
|
||
</span></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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'emms-browser</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'emms-browser-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'quit-window</span>))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'emms-playlist-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'quit-window</span>))
|
||
</span></span></code></pre></div><h5 id="emms-and-mpd-fixes">EMMS & mpd Fixes</h5>
|
||
<p><del>Some fixes until I submit a patch.</del> I’ve submitted a patch for with these fixes, so I’ll remove this section eventually.</p>
|
||
<p>For some reason EMMS doesn’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"><span style="display:flex;"><span>(defun emms-info-mpd-process (track info)
|
||
</span></span><span style="display:flex;"><span> (dolist (data info)
|
||
</span></span><span style="display:flex;"><span> (let ((name (<span style="color:#a6e22e">car</span> data))
|
||
</span></span><span style="display:flex;"><span> (value (<span style="color:#a6e22e">cdr</span> data)))
|
||
</span></span><span style="display:flex;"><span> (setq name (cond ((string= name <span style="color:#e6db74">"artist"</span>) <span style="color:#e6db74">'info-artist</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"albumartist"</span>) <span style="color:#e6db74">'info-albumartist</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"composer"</span>) <span style="color:#e6db74">'info-composer</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"performer"</span>) <span style="color:#e6db74">'info-performer</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"title"</span>) <span style="color:#e6db74">'info-title</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"album"</span>) <span style="color:#e6db74">'info-album</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"track"</span>) <span style="color:#e6db74">'info-tracknumber</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"disc"</span>) <span style="color:#e6db74">'info-discnumber</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"date"</span>) <span style="color:#e6db74">'info-year</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"genre"</span>) <span style="color:#e6db74">'info-genre</span>)
|
||
</span></span><span style="display:flex;"><span> ((string= name <span style="color:#e6db74">"time"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq value (<span style="color:#a6e22e">string-to-number</span> value))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'info-playing-time</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> <span style="color:#66d9ef">nil</span>)))
|
||
</span></span><span style="display:flex;"><span> (when name
|
||
</span></span><span style="display:flex;"><span> (emms-track-set track name value)))))
|
||
</span></span></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"><span style="display:flex;"><span>tag1: value1
|
||
</span></span><span style="display:flex;"><span>tag2: value2
|
||
</span></span><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span>tag1: value1'
|
||
</span></span><span style="display:flex;"><span>tag2: value2'
|
||
</span></span></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"><span style="display:flex;"><span>(("tag1" . "value1"
|
||
</span></span><span style="display:flex;"><span> "tag2" . "value2")
|
||
</span></span><span style="display:flex;"><span> ("tag1" . "value1'"
|
||
</span></span><span style="display:flex;"><span> ("tag2" . "value2'")))
|
||
</span></span></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’t work too well if some tags don’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’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"><span style="display:flex;"><span>(defun emms-player-mpd-get-alists (info)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Turn the given parsed INFO from MusicPD into an list of alists.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">The list will be in reverse order."</span>
|
||
</span></span><span style="display:flex;"><span> (when (and info
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">null</span> (<span style="color:#a6e22e">car</span> info)) <span style="color:#75715e">; no error has occurred</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span> info)) <span style="color:#75715e">; data exists</span>
|
||
</span></span><span style="display:flex;"><span> (let ((alists <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (alist <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> cell)
|
||
</span></span><span style="display:flex;"><span> (dolist (line (<span style="color:#a6e22e">cdr</span> info))
|
||
</span></span><span style="display:flex;"><span> (when (setq cell (emms-player-mpd-parse-line line))
|
||
</span></span><span style="display:flex;"><span> (if (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">car</span> cell) <span style="color:#f92672">'</span>(<span style="color:#e6db74">"file"</span> <span style="color:#e6db74">"directory"</span> <span style="color:#e6db74">"playlist"</span>))
|
||
</span></span><span style="display:flex;"><span> (setq alists (<span style="color:#a6e22e">cons</span> alist alists)
|
||
</span></span><span style="display:flex;"><span> alist (<span style="color:#a6e22e">list</span> cell))
|
||
</span></span><span style="display:flex;"><span> (setq alist (<span style="color:#a6e22e">cons</span> cell alist)))))
|
||
</span></span><span style="display:flex;"><span> (when alist
|
||
</span></span><span style="display:flex;"><span> (setq alists (<span style="color:#a6e22e">cons</span> alist alists)))
|
||
</span></span><span style="display:flex;"><span> alists)))
|
||
</span></span></code></pre></div><h4 id="ytel">ytel</h4>
|
||
<p><a href="https://github.com/gRastello/ytel">ytel</a> is a YouTube (actually Invidious) frontend, which lets one search YouTube (whereas the setup with elfeed just lets one view the pre-defined subscriptions).</p>
|
||
<p>The package doesn’t provide evil bindings, so I define my own.</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="display:flex;"><span>(use-package ytel
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (ytel)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq ytel-invidious-api-url <span style="color:#e6db74">"https://invidio.xamh.de/"</span>)
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'ytel-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#a6e22e">#'</span>ytel-quit
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"s"</span> <span style="color:#a6e22e">#'</span>ytel-search
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"L"</span> <span style="color:#a6e22e">#'</span>ytel-search-next-page
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"H"</span> <span style="color:#a6e22e">#'</span>ytel-search-previous-page
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"RET"</span> <span style="color:#a6e22e">#'</span>my/ytel-add-emms))
|
||
</span></span></code></pre></div><p>And here is the same kind of integration with EMMS as in the elfeed 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-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
</span></span><span style="display:flex;"><span> (define-emms-source ytel (video)
|
||
</span></span><span style="display:flex;"><span> (let ((track (emms-track
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">'url</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"https://www.youtube.com/watch?v="</span>
|
||
</span></span><span style="display:flex;"><span> (ytel-video-id video)))))
|
||
</span></span><span style="display:flex;"><span> (emms-track-set track <span style="color:#e6db74">'info-title</span> (ytel-video-title video))
|
||
</span></span><span style="display:flex;"><span> (emms-track-set track <span style="color:#e6db74">'info-artist</span> (ytel-video-author video))
|
||
</span></span><span style="display:flex;"><span> (emms-playlist-insert-track track))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/ytel-add-emms ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (emms-add-ytel (ytel-get-current-video)))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/toggle-shr-use-fonts ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Toggle the shr-use-fonts variable in buffer"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (setq-local shr-use-fonts (not shr-use-fonts)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"aw"</span> <span style="color:#e6db74">'eww</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'eww-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"+"</span> <span style="color:#e6db74">'text-scale-increase</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"-"</span> <span style="color:#e6db74">'text-scale-decrease</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package erc
|
||
</span></span><span style="display:flex;"><span> :commands (erc erc-tls)
|
||
</span></span><span style="display:flex;"><span> :straight (:type built-in)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq erc-log-channels-directory <span style="color:#e6db74">"~/.erc/logs"</span>)
|
||
</span></span><span style="display:flex;"><span> (setq erc-save-buffer-on-part <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'erc-modules</span> <span style="color:#e6db74">'autojoin</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'erc-modules</span> <span style="color:#e6db74">'log</span>)
|
||
</span></span><span style="display:flex;"><span> (erc-update-modules)
|
||
</span></span><span style="display:flex;"><span> (setq erc-autojoin-channels-alist
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">"libera.chat"</span>) <span style="color:#e6db74">"#systemcrafters"</span>)))
|
||
</span></span><span style="display:flex;"><span> (setq erc-kill-buffer-on-part <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (setq erc-track-shorten-start <span style="color:#ae81ff">8</span>))
|
||
</span></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"><span style="display:flex;"><span>(setq erc-track-exclude-types <span style="color:#f92672">'</span>(<span style="color:#e6db74">"NICK"</span> <span style="color:#e6db74">"JOIN"</span> <span style="color:#e6db74">"LEAVE"</span> <span style="color:#e6db74">"QUIT"</span> <span style="color:#e6db74">"PART"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"301"</span> <span style="color:#75715e">; away notice</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"305"</span> <span style="color:#75715e">; return from awayness</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"306"</span> <span style="color:#75715e">; set awayness</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"324"</span> <span style="color:#75715e">; modes</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"329"</span> <span style="color:#75715e">; channel creation date</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"332"</span> <span style="color:#75715e">; topic notice</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"333"</span> <span style="color:#75715e">; who set the topic</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"353"</span> <span style="color:#75715e">; Names notice</span>
|
||
</span></span><span style="display:flex;"><span> ))
|
||
</span></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"><span style="display:flex;"><span>(use-package erc-hl-nicks
|
||
</span></span><span style="display:flex;"><span> :hook (erc-mode <span style="color:#f92672">.</span> erc-hl-nicks-mode)
|
||
</span></span><span style="display:flex;"><span> :after (erc)
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package znc
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (znc-erc)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ai"</span> (my/command-in-persp <span style="color:#e6db74">"erc"</span> <span style="color:#e6db74">"ERC"</span> <span style="color:#ae81ff">0</span> (znc-erc)))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq znc-servers
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">"sqrtminusone.xyz"</span> <span style="color:#ae81ff">6697</span> <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> ((libera <span style="color:#e6db74">"sqrtminusone"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,</span>(password-store-get <span style="color:#e6db74">"Selfhosted/ZNC"</span>)))))))
|
||
</span></span></code></pre></div><h4 id="off--jabber"><span class="org-todo done OFF">OFF</span> (OFF) jabber</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="display:flex;"><span>(use-package srv
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package fsm
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :defer <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package emacs-jabber
|
||
</span></span><span style="display:flex;"><span> :straight (jabber :host <span style="color:#66d9ef">nil</span> :repo
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"https://tildegit.org/wgreenhouse/emacs-jabber"</span>))
|
||
</span></span></code></pre></div><h4 id="google-translate">Google Translate</h4>
|
||
<p>Emacs interface to Google Translate.</p>
|
||
<p>Can’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"><span style="display:flex;"><span>(use-package google-translate
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :functions (my-google-translate-at-point google-translate--search-tkk)
|
||
</span></span><span style="display:flex;"><span> :custom
|
||
</span></span><span style="display:flex;"><span> (google-translate-backend-method <span style="color:#e6db74">'curl</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (require <span style="color:#e6db74">'facemenu</span>)
|
||
</span></span><span style="display:flex;"><span> (defun google-translate--search-tkk ()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Search TKK."</span>
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">list</span> <span style="color:#ae81ff">430675</span> <span style="color:#ae81ff">2721866130</span>))
|
||
</span></span><span style="display:flex;"><span> (defun my-google-translate-at-point()
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"reverse translate if prefix"</span>
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (if current-prefix-arg
|
||
</span></span><span style="display:flex;"><span> (google-translate-at-point)
|
||
</span></span><span style="display:flex;"><span> (google-translate-at-point-reverse)))
|
||
</span></span><span style="display:flex;"><span> (setq google-translate-translation-directions-alist
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>((<span style="color:#e6db74">"en"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"ru"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#e6db74">"ru"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"en"</span>))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def
|
||
</span></span><span style="display:flex;"><span> :infix <span style="color:#e6db74">"at"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"google translate"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'google-translate-at-point</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"P"</span> <span style="color:#e6db74">'google-translate-at-point-reverse</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'google-translate-query-translate</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"Q"</span> <span style="color:#e6db74">'google-translate-query-translate-reverse</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'google-translate-smooth-translate</span>)
|
||
</span></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"><span style="display:flex;"><span>(use-package tldr
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (tldr)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq tldr-source-zip-url <span style="color:#e6db74">"https://github.com/tldr-pages/tldr/archive/refs/heads/main.zip"</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> (defun tldr-update-docs ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"curl -L %s --output %s"</span> tldr-source-zip-url tldr-saved-zip-path))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">"/tmp/tldr"</span>)
|
||
</span></span><span style="display:flex;"><span> (delete-directory <span style="color:#e6db74">"/tmp/tldr"</span> <span style="color:#66d9ef">t</span>))
|
||
</span></span><span style="display:flex;"><span> (shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"unzip -d /tmp/tldr/ %s"</span> tldr-saved-zip-path))
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">file-exists-p</span> tldr-directory-path)
|
||
</span></span><span style="display:flex;"><span> (delete-directory tldr-directory-path <span style="color:#e6db74">'recursive</span> <span style="color:#e6db74">'no-trash</span>))
|
||
</span></span><span style="display:flex;"><span> (shell-command-to-string (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"mv %s %s"</span> <span style="color:#e6db74">"/tmp/tldr/tldr-main"</span> tldr-directory-path))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"hT"</span> <span style="color:#e6db74">'tldr</span>)
|
||
</span></span></code></pre></div><h4 id="man-and-info">man & 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"><span style="display:flex;"><span>(setq Man-width-max <span style="color:#ae81ff">180</span>)
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"hM"</span> <span style="color:#e6db74">'man</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'Info-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> (kbd <span style="color:#e6db74">"RET"</span>) <span style="color:#e6db74">'Info-follow-nearest-node</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/man-fix-width (<span style="color:#66d9ef">&rest</span> _)
|
||
</span></span><span style="display:flex;"><span> (setq-local Man-width (<span style="color:#a6e22e">-</span> (window-width) <span style="color:#ae81ff">4</span>)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(advice-add <span style="color:#a6e22e">#'</span>Man-update-manpage :before <span style="color:#a6e22e">#'</span>my/man-fix-width)
|
||
</span></span></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"><span style="display:flex;"><span>(use-package devdocs
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (devdocs-install devdocs-lookup)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"he"</span> <span style="color:#a6e22e">#'</span>devdocs-lookup
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"hE"</span> <span style="color:#a6e22e">#'</span>devdocs-install))
|
||
</span></span></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>This package is pretty good to manage the password database. I use <a href="https://github.com/SqrtMinusOne/password-store-ivy">password-store-ivy</a> (another package of mine) to actually type passwords. <a href="https://github.com/carnager/rofi-pass">rofi-pass</a> is another good option.</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="display:flex;"><span>(use-package pass
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (pass)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ak"</span> <span style="color:#a6e22e">#'</span>pass)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq pass-show-keybindings <span style="color:#66d9ef">nil</span>))
|
||
</span></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"><span style="display:flex;"><span>(use-package docker
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (docker)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ao"</span> <span style="color:#e6db74">'docker</span>))
|
||
</span></span></code></pre></div><p>By default, docker commands are run in <code>default-directory</code>. Even worse, transient doesn’t allow to set <code>default-directory</code> temporarily, via <code>let</code>. But often I don’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"><span style="display:flex;"><span>(setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/docker-override-dir (fun <span style="color:#66d9ef">&rest</span> args)
|
||
</span></span><span style="display:flex;"><span> (let ((default-directory (or my/selected-docker-directory default-directory)))
|
||
</span></span><span style="display:flex;"><span> (setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">apply</span> fun args)))
|
||
</span></span></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"><span style="display:flex;"><span>(with-eval-after-load <span style="color:#e6db74">'docker</span>
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>docker-compose-run-docker-compose-async :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>docker-compose-run-docker-compose :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>docker-run-docker-async :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#a6e22e">#'</span>docker-run-docker :around <span style="color:#a6e22e">#'</span>my/docker-override-dir))
|
||
</span></span></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"><span style="display:flex;"><span>(defun my/docker-from-dir ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/docker-directories</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"prodigy-config"</span>)))
|
||
</span></span><span style="display:flex;"><span> (let* ((directories
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%-30s %s"</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
|
||
</span></span><span style="display:flex;"><span> my/docker-directories))
|
||
</span></span><span style="display:flex;"><span> (selected-directory
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Docker: "</span> directories <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"^"</span>)
|
||
</span></span><span style="display:flex;"><span> directories))))
|
||
</span></span><span style="display:flex;"><span> (setq my/selected-docker-directory selected-directory)
|
||
</span></span><span style="display:flex;"><span> (docker)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"aO"</span> <span style="color:#e6db74">'my/docker-from-dir</span>)
|
||
</span></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’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"><span style="display:flex;"><span>(use-package prodigy
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (prodigy)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"aP"</span> <span style="color:#e6db74">'prodigy</span>)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/docker-directories</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"prodigy-config"</span>)))
|
||
</span></span><span style="display:flex;"><span> (general-define-key
|
||
</span></span><span style="display:flex;"><span> :states <span style="color:#f92672">'</span>(normal)
|
||
</span></span><span style="display:flex;"><span> :keymaps <span style="color:#e6db74">'prodigy-view-mode-map</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>))
|
||
</span></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"><span style="display:flex;"><span>(defun my/get-apps-on-ports ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">mapcar</span>
|
||
</span></span><span style="display:flex;"><span> (lambda (line)
|
||
</span></span><span style="display:flex;"><span> (let* ((split (split-string line (rx (| (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">" "</span>) (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">"\t"</span>)))))
|
||
</span></span><span style="display:flex;"><span> (process (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">6</span>)))
|
||
</span></span><span style="display:flex;"><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>))
|
||
</span></span><span style="display:flex;"><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>))
|
||
</span></span><span style="display:flex;"><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>))
|
||
</span></span><span style="display:flex;"><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></span><span style="display:flex;"><span> <span style="color:#f92672">,@</span>(let ((data (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">4</span>)))
|
||
</span></span><span style="display:flex;"><span> (save-match-data
|
||
</span></span><span style="display:flex;"><span> (<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">":"</span> (group-n <span style="color:#ae81ff">2</span> (or (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">"*"</span>))) data)
|
||
</span></span><span style="display:flex;"><span> <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))
|
||
</span></span><span style="display:flex;"><span> (local-port <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(match-string <span style="color:#ae81ff">2</span> data)))))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">,@</span>(unless (string-empty-p process)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">`</span>((pid <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(save-match-data
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">string-match</span> (rx <span style="color:#e6db74">"pid="</span> (<span style="color:#a6e22e">+</span> num)) process)
|
||
</span></span><span style="display:flex;"><span> (<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>)))))))))
|
||
</span></span><span style="display:flex;"><span> (seq-filter
|
||
</span></span><span style="display:flex;"><span> (lambda (s) (not (string-empty-p s)))
|
||
</span></span><span style="display:flex;"><span> (split-string
|
||
</span></span><span style="display:flex;"><span> (shell-command-to-string <span style="color:#e6db74">"ss -tulpnH | grep LISTEN"</span>) <span style="color:#e6db74">"\n"</span>))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/kill-app-on-port (port <span style="color:#66d9ef">&optional</span> <span style="color:#a6e22e">signal</span>)
|
||
</span></span><span style="display:flex;"><span> (let ((apps (my/get-apps-on-ports)))
|
||
</span></span><span style="display:flex;"><span> (dolist (app apps)
|
||
</span></span><span style="display:flex;"><span> (when (<span style="color:#a6e22e">string-equal</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'local-port</span> app)) port)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">signal-process</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'pid</span> app)) (or <span style="color:#a6e22e">signal</span> <span style="color:#ae81ff">15</span>))
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Sent %d to %d"</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">'pid</span> app)))))))
|
||
</span></span></code></pre></div><h4 id="screenshot-dot-el">screenshot.el</h4>
|
||
<p>Tecosaur’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"><span style="display:flex;"><span>(use-package screenshot
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"tecosaur/screenshot"</span>
|
||
</span></span><span style="display:flex;"><span> :host github
|
||
</span></span><span style="display:flex;"><span> :build (:not compile))
|
||
</span></span><span style="display:flex;"><span> :if (display-graphic-p)
|
||
</span></span><span style="display:flex;"><span> :commands (screenshot)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"S"</span> <span style="color:#e6db74">'screenshot</span>))
|
||
</span></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"><span style="display:flex;"><span>(my-leader-def <span style="color:#e6db74">"ah"</span> <span style="color:#e6db74">'proced</span>)
|
||
</span></span><span style="display:flex;"><span>(setq proced-auto-update-interval <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>(add-hook <span style="color:#e6db74">'proced-mode-hook</span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (visual-line-mode <span style="color:#ae81ff">-1</span>)
|
||
</span></span><span style="display:flex;"><span> (setq-local truncate-lines <span style="color:#66d9ef">t</span>)
|
||
</span></span><span style="display:flex;"><span> (proced-toggle-auto-update <span style="color:#ae81ff">1</span>)))
|
||
</span></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"><span style="display:flex;"><span>(use-package guix
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :commands (guix)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ag"</span> <span style="color:#e6db74">'guix</span>))
|
||
</span></span></code></pre></div><h3 id="productivity">Productivity</h3>
|
||
<h4 id="pomm">pomm</h4>
|
||
<p>My package for doing Pomodoro 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"><span style="display:flex;"><span>(use-package pomm
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"SqrtMinusOne/pomm.el"</span> :files (:defaults <span style="color:#e6db74">"resources"</span>))
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">;; :straight (:local-repo "~/Code/Emacs/pomm" :files (:defaults "resources"))</span>
|
||
</span></span><span style="display:flex;"><span> :commands (pomm)
|
||
</span></span><span style="display:flex;"><span> :init
|
||
</span></span><span style="display:flex;"><span> (my-leader-def <span style="color:#e6db74">"ap"</span> <span style="color:#a6e22e">#'</span>pomm)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq alert-default-style <span style="color:#e6db74">'libnotify</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'pomm-on-tick-hook</span> <span style="color:#e6db74">'pomm-update-mode-line-string</span>)
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'pomm-on-status-changed-hook</span> <span style="color:#e6db74">'pomm-update-mode-line-string</span>))
|
||
</span></span></code></pre></div><h4 id="hledger">hledger</h4>
|
||
<p>is a plain-text double-entry accounting software. I use it for managing my personal finances, and thus far it’s great.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>hledger</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"><span style="display:flex;"><span>(use-package hledger-mode
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :mode (rx <span style="color:#e6db74">".journal"</span> eos)
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq hledger-jfile (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/ledger/ledger.journal"</span>))
|
||
</span></span><span style="display:flex;"><span> (add-hook <span style="color:#e6db74">'hledger-mode-hook</span>
|
||
</span></span><span style="display:flex;"><span> (lambda ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">make-local-variable</span> <span style="color:#e6db74">'company-backends</span>)
|
||
</span></span><span style="display:flex;"><span> (add-to-list <span style="color:#e6db74">'company-backends</span> <span style="color:#e6db74">'hledger-company</span>))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(use-package flycheck-hledger
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :after (hledger-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(setq calendar-date-style <span style="color:#e6db74">'iso</span>) <span style="color:#75715e">;; YYYY/mm/dd</span>
|
||
</span></span><span style="display:flex;"><span>(setq calendar-week-start-day <span style="color:#ae81ff">1</span>)
|
||
</span></span><span style="display:flex;"><span>(setq calendar-time-display-form <span style="color:#f92672">'</span>(24-hours <span style="color:#e6db74">":"</span> minutes))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(setq calendar-latitude <span style="color:#ae81ff">59.9375</span>)
|
||
</span></span><span style="display:flex;"><span>(setq calendar-longitude <span style="color:#ae81ff">30.308611</span>)
|
||
</span></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">Discord rich presence</a>.</p>
|
||
<p>Some functions to override the displayed message:</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="display:flex;"><span>(defun my/elcord-mask-buffer-name (name)
|
||
</span></span><span style="display:flex;"><span> (cond
|
||
</span></span><span style="display:flex;"><span> ((string-match-p (rx bos (<span style="color:#e6db74">? </span><span style="color:#e6db74">"CAPTURE-"</span>) (<span style="color:#a6e22e">=</span> <span style="color:#ae81ff">14</span> num) <span style="color:#e6db74">"-"</span> (<span style="color:#a6e22e">*</span> not-newline) <span style="color:#e6db74">".org"</span> eos) name)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<ORG-ROAM>"</span>)
|
||
</span></span><span style="display:flex;"><span> ((string-match-p (rx bos (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">"-"</span> (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">"-"</span> (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">".org"</span> eos) name)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<ORG-JOURNAL>"</span>)
|
||
</span></span><span style="display:flex;"><span> ((string-match-p (rx bos <span style="color:#e6db74">"EXWM"</span>) name)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"<EXWM>"</span>)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#66d9ef">t</span> name)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/elcord-buffer-details-format-functions ()
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Editing %s"</span> (my/elcord-mask-buffer-name (<span style="color:#a6e22e">buffer-name</span>))))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/elcord-update-presence-mask-advice (r)
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">list</span> (my/elcord-mask-buffer-name (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> r)) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> r)))
|
||
</span></span></code></pre></div><p>And the package 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"><span style="display:flex;"><span>(use-package elcord
|
||
</span></span><span style="display:flex;"><span> :straight <span style="color:#66d9ef">t</span>
|
||
</span></span><span style="display:flex;"><span> :if (and (or
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"indigo"</span>)
|
||
</span></span><span style="display:flex;"><span> (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"eminence"</span>))
|
||
</span></span><span style="display:flex;"><span> (not my/slow-ssh)
|
||
</span></span><span style="display:flex;"><span> (not my/remote-server))
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq elcord-buffer-details-format-function <span style="color:#a6e22e">#'</span>my/elcord-buffer-details-format-functions)
|
||
</span></span><span style="display:flex;"><span> (advice-add <span style="color:#e6db74">'elcord--try-update-presence</span> :filter-args <span style="color:#a6e22e">#'</span>my/elcord-update-presence-mask-advice)
|
||
</span></span><span style="display:flex;"><span> (elcord-mode))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package snow
|
||
</span></span><span style="display:flex;"><span> :straight (:repo <span style="color:#e6db74">"alphapapa/snow.el"</span> :host github)
|
||
</span></span><span style="display:flex;"><span> :commands (snow))
|
||
</span></span></code></pre></div><h4 id="power-mode">Power mode</h4>
|
||
<p>When Emacs doesn’t feel powerful enough.</p>
|
||
<p>Watch out if you are using EXWM.</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="display:flex;"><span>(use-package power-mode
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"elizagamedev/power-mode.el"</span>)
|
||
</span></span><span style="display:flex;"><span> :disabled
|
||
</span></span><span style="display:flex;"><span> :commands (power-mode))
|
||
</span></span></code></pre></div><h4 id="redacted">Redacted</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="display:flex;"><span>(use-package redacted
|
||
</span></span><span style="display:flex;"><span> :commands (redacted-mode)
|
||
</span></span><span style="display:flex;"><span> :straight (:host github :repo <span style="color:#e6db74">"bkaestner/redacted.el"</span>))
|
||
</span></span></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"><span style="display:flex;"><span>(use-package zone
|
||
</span></span><span style="display:flex;"><span> :ensure <span style="color:#66d9ef">nil</span>
|
||
</span></span><span style="display:flex;"><span> :config
|
||
</span></span><span style="display:flex;"><span> (setq original-zone-programs (<span style="color:#a6e22e">copy-sequence</span> zone-programs)))
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>(defun my/zone-with-select ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (ivy-read <span style="color:#e6db74">"Zone programs"</span>
|
||
</span></span><span style="display:flex;"><span> (cl-pairlis
|
||
</span></span><span style="display:flex;"><span> (cl-mapcar <span style="color:#e6db74">'symbol-name</span> original-zone-programs)
|
||
</span></span><span style="display:flex;"><span> original-zone-programs)
|
||
</span></span><span style="display:flex;"><span> :action (lambda (elem)
|
||
</span></span><span style="display:flex;"><span> (setq zone-programs (<span style="color:#a6e22e">vector</span> (<span style="color:#a6e22e">cdr</span> elem)))
|
||
</span></span><span style="display:flex;"><span> (zone))))
|
||
</span></span></code></pre></div><p>Also, a function to copy a URL to the video under 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"><span style="display:flex;"><span>(defun my/ytel-kill-url ()
|
||
</span></span><span style="display:flex;"><span> (interactive)
|
||
</span></span><span style="display:flex;"><span> (kill-new
|
||
</span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">concat</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">"https://www.youtube.com/watch?v="</span>
|
||
</span></span><span style="display:flex;"><span> (ytel-video-id (ytel-get-current-video)))))
|
||
</span></span></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"><span style="display:flex;"><span>(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#a6e22e">#'</span>my/format-guix-dependencies)
|
||
</span></span><span style="display:flex;"><span> (my/format-guix-dependencies))
|
||
</span></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-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#a6e22e">specifications->manifest</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"emacs-native-comp"</span>
|
||
</span></span><span style="display:flex;"><span> <<packages()>>))
|
||
</span></span></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, 2022"><small>Pavel Korytov, 2022</small></a>
|
||
</div>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|