mirror of
https://github.com/SqrtMinusOne/sqrtminusone.github.io.git
synced 2025-12-11 16:13:03 +03:00
5715 lines
435 KiB
HTML
5715 lines
435 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">
|
||
<p>#+begin_quote
|
||
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'.</p>
|
||
<div class="ox-hugo-toc toc">
|
||
<div></div>
|
||
<div class="heading">Table of Contents</div>
|
||
<ul>
|
||
<li><a href="#primary-setup">Primary setup</a>
|
||
<ul>
|
||
<li><a href="#measure-startup-speed">Measure startup speed</a></li>
|
||
<li><a href="#straight-dot-el">straight.el</a></li>
|
||
<li><a href="#use-package">use-package</a></li>
|
||
<li><a href="#config-variants-and-environment">Config variants & environment</a></li>
|
||
<li><a href="#performance">Performance</a>
|
||
<ul>
|
||
<li><a href="#garbage-collection">Garbage collection</a></li>
|
||
<li><a href="#run-garbage-collection-when-emacs-is-unfocused">Run garbage collection when Emacs is unfocused</a></li>
|
||
<li><a href="#native-compilation">Native compilation</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#anaconda">Anaconda</a></li>
|
||
<li><a href="#custom-file-location">Custom file location</a></li>
|
||
<li><a href="#private-config">Private config</a></li>
|
||
<li><a href="#no-littering">No littering</a></li>
|
||
<li><a href="#prevent-emacs-from-closing">Prevent Emacs from closing</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#global-editing-configuration">Global editing configuration</a>
|
||
<ul>
|
||
<li><a href="#general-keybindings-stuff">General keybindings stuff</a>
|
||
<ul>
|
||
<li><a href="#general-dot-el">general.el</a></li>
|
||
<li><a href="#which-key">which-key</a>
|
||
<ul>
|
||
<li><a href="#dump-keybindings">dump keybindings</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#evil-mode">Evil mode</a>
|
||
<ul>
|
||
<li><a href="#evil">evil</a></li>
|
||
<li><a href="#addons">Addons</a></li>
|
||
<li><a href="#evil-collection">evil-collection</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#more-keybindings">More keybindings</a>
|
||
<ul>
|
||
<li><a href="#escape-key">Escape key</a></li>
|
||
<li><a href="#home-and-end">Home & end</a></li>
|
||
<li><a href="#my-leader">My leader</a></li>
|
||
<li><a href="#universal-argument">Universal argument</a></li>
|
||
<li><a href="#profiler">Profiler</a></li>
|
||
<li><a href="#buffer-switching">Buffer switching</a></li>
|
||
<li><a href="#buffer-management">Buffer management</a></li>
|
||
<li><a href="#xref">xref</a></li>
|
||
<li><a href="#folding">Folding</a></li>
|
||
<li><a href="#zoom">Zoom</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#i3-integration">i3 integration</a></li>
|
||
<li><a href="#editing-helpers">Editing helpers</a>
|
||
<ul>
|
||
<li><a href="#visual-fill-column-mode">Visual fill column mode</a></li>
|
||
<li><a href="#smartparens">smartparens</a></li>
|
||
<li><a href="#aggressive-indent">Aggressive Indent</a></li>
|
||
<li><a href="#delete-trailing-whitespace">Delete trailing whitespace</a></li>
|
||
<li><a href="#expand-region">Expand region</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#various-settings">Various settings</a>
|
||
<ul>
|
||
<li><a href="#tabs">Tabs</a></li>
|
||
<li><a href="#scrolling-config">Scrolling config</a></li>
|
||
<li><a href="#clipboard">Clipboard</a></li>
|
||
<li><a href="#backups">Backups</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#undo-tree">Undo Tree</a></li>
|
||
<li><a href="#help">Help</a></li>
|
||
<li><a href="#ivy-counsel-swiper">Ivy, counsel, swiper</a>
|
||
<ul>
|
||
<li><a href="#ivy-rich">ivy-rich</a></li>
|
||
<li><a href="#prescient">prescient</a></li>
|
||
<li><a href="#keybindings">Keybindings</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#treemacs">Treemacs</a>
|
||
<ul>
|
||
<li><a href="#helper-functions">Helper functions</a></li>
|
||
<li><a href="#custom-icons">Custom icons</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#projectile">Projectile</a></li>
|
||
<li><a href="#company">Company</a></li>
|
||
<li><a href="#git-and-magit">Git & Magit</a></li>
|
||
<li><a href="#editorconfig">Editorconfig</a></li>
|
||
<li><a href="#snippets">Snippets</a></li>
|
||
<li><a href="#time-trackers">Time trackers</a>
|
||
<ul>
|
||
<li><a href="#wakatime">WakaTime</a></li>
|
||
<li><a href="#activitywatch">ActivityWatch</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#ui">UI</a>
|
||
<ul>
|
||
<li><a href="#general-ui-and-gui-settings">General UI & GUI Settings</a></li>
|
||
<li><a href="#theme-and-global-stuff">Theme & global stuff</a>
|
||
<ul>
|
||
<li><a href="#custom-theme">Custom theme</a></li>
|
||
<li><a href="#font">Font</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#custom-frame-title">Custom frame title</a></li>
|
||
<li><a href="#perspective-dot-el">perspective.el</a>
|
||
<ul>
|
||
<li><a href="#some-functions">Some functions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#off--tab-bar"><span class="org-todo done OFF">OFF</span> (OFF) Tab bar</a>
|
||
<ul>
|
||
<li><a href="#setup">Setup</a></li>
|
||
<li><a href="#my-title">My title</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#doom-modeline">Doom Modeline</a></li>
|
||
<li><a href="#off--spaceline"><span class="org-todo done OFF">OFF</span> (OFF) Spaceline</a>
|
||
<ul>
|
||
<li><a href="#perspectives">Perspectives</a></li>
|
||
<li><a href="#exwm-workspace">EXWM workspace</a></li>
|
||
<li><a href="#debug">Debug</a></li>
|
||
<li><a href="#my-theme">My theme</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#font-stuff">Font stuff</a>
|
||
<ul>
|
||
<li><a href="#ligatures">Ligatures</a></li>
|
||
<li><a href="#icons">Icons</a></li>
|
||
<li><a href="#highlight-todo">Highlight todo</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#text-highlight-improvements">Text highlight improvements</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#dired">Dired</a>
|
||
<ul>
|
||
<li><a href="#basic-config-and-keybindings">Basic config & keybindings</a></li>
|
||
<li><a href="#addons">Addons</a></li>
|
||
<li><a href="#subdirectories">Subdirectories</a></li>
|
||
<li><a href="#tramp">TRAMP</a></li>
|
||
<li><a href="#bookmarks">Bookmarks</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#shells">Shells</a>
|
||
<ul>
|
||
<li><a href="#vterm">vterm</a>
|
||
<ul>
|
||
<li><a href="#configuration">Configuration</a></li>
|
||
<li><a href="#subterminal">Subterminal</a></li>
|
||
<li><a href="#dired-integration">Dired integration</a></li>
|
||
<li><a href="#with-editor-integration">With-editor integration</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#eshell">Eshell</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#org-mode">Org Mode</a>
|
||
<ul>
|
||
<li><a href="#installation-and-basic-settings">Installation & 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="#setup">Setup</a></li>
|
||
<li><a href="#managing-jupyter-kernels">Managing Jupyter kernels</a></li>
|
||
<li><a href="#do-not-wrap-the-output-in-emacs-jupyter">Do not wrap the output in emacs-jupyter</a></li>
|
||
<li><a href="#wrap-source-code-output">Wrap source code output</a></li>
|
||
<li><a href="#managing-a-literate-programming-project">Managing a literate programming project</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="#trello-sync">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="#review-workflow">Review workflow</a>
|
||
<ul>
|
||
<li><a href="#data-from-git-and-org-roam">Data from git & org-roam</a></li>
|
||
<li><a href="#data-from-org-journal">Data from org-journal</a></li>
|
||
<li><a href="#data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</a></li>
|
||
<li><a href="#capture-template">Capture template</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#org-journal">Org Journal</a></li>
|
||
<li><a href="#org-roam">Org Roam</a>
|
||
<ul>
|
||
<li><a href="#org-roam-ui">org-roam-ui</a></li>
|
||
<li><a href="#org-roam-protocol">org-roam-protocol</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#org-ref">org-ref</a></li>
|
||
<li><a href="#org-roam-bibtex">org-roam-bibtex</a></li>
|
||
<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="#org-agenda-icons">Org Agenda Icons</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#export">Export</a>
|
||
<ul>
|
||
<li><a href="#general-settings">General settings</a></li>
|
||
<li><a href="#hugo">Hugo</a></li>
|
||
<li><a href="#jupyter-notebook">Jupyter Notebook</a></li>
|
||
<li><a href="#html-export">Html export</a></li>
|
||
<li><a href="#latex">LaTeX</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#keybindings-and-stuff">Keybindings & stuff</a>
|
||
<ul>
|
||
<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="#presentations">Presentations</a></li>
|
||
<li><a href="#tools">Tools</a>
|
||
<ul>
|
||
<li><a href="#toc">TOC</a></li>
|
||
<li><a href="#screenshots">Screenshots</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#system-configuration">System configuration</a>
|
||
<ul>
|
||
<li><a href="#tables-for-guix-dependencies">Tables for Guix Dependencies</a></li>
|
||
<li><a href="#noweb-evaluations">Noweb evaluations</a></li>
|
||
<li><a href="#yadm-hook">yadm hook</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#programming">Programming</a>
|
||
<ul>
|
||
<li><a href="#general-setup">General setup</a>
|
||
<ul>
|
||
<li><a href="#lsp">LSP</a>
|
||
<ul>
|
||
<li><a href="#setup">Setup</a></li>
|
||
<li><a href="#integrations">Integrations</a></li>
|
||
<li><a href="#keybindings">Keybindings</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#flycheck">Flycheck</a></li>
|
||
<li><a href="#tree-sitter">Tree Sitter</a></li>
|
||
<li><a href="#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="#debug-templates">Debug templates</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#off--tabnine"><span class="org-todo done OFF">OFF</span> (OFF) TabNine</a></li>
|
||
<li><a href="#off--code-compass"><span class="org-todo done OFF">OFF</span> (OFF) Code Compass</a>
|
||
<ul>
|
||
<li><a href="#dependencies">Dependencies</a></li>
|
||
<li><a href="#plugin">Plugin</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#reformatter">Reformatter</a></li>
|
||
<li><a href="#general-additional-config">General additional config</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#web-development">Web development</a>
|
||
<ul>
|
||
<li><a href="#emmet">Emmet</a></li>
|
||
<li><a href="#prettier">Prettier</a></li>
|
||
<li><a href="#typescript">TypeScript</a></li>
|
||
<li><a href="#javascript">JavaScript</a></li>
|
||
<li><a href="#jest">Jest</a></li>
|
||
<li><a href="#web-mode">web-mode</a></li>
|
||
<li><a href="#off--vue-dot-js"><span class="org-todo done OFF">OFF</span> (OFF) Vue.js</a>
|
||
<ul>
|
||
<li><a href="#mmm-mode-fix">mmm-mode fix</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#off--svelte"><span class="org-todo done OFF">OFF</span> (OFF) Svelte</a></li>
|
||
<li><a href="#scss">SCSS</a></li>
|
||
<li><a href="#php">PHP</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#latex">LaTeX</a>
|
||
<ul>
|
||
<li><a href="#auctex">AUCTeX</a></li>
|
||
<li><a href="#bibtex">BibTeX</a></li>
|
||
<li><a href="#import-dot-sty">Import *.sty</a></li>
|
||
<li><a href="#snippets">Snippets</a>
|
||
<ul>
|
||
<li><a href="#greek-letters">Greek letters</a></li>
|
||
<li><a href="#english-letters">English letters</a></li>
|
||
<li><a href="#math-symbols">Math symbols</a></li>
|
||
<li><a href="#section-snippets">Section snippets</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#other-markup-languages">Other markup languages</a>
|
||
<ul>
|
||
<li><a href="#markdown">Markdown</a></li>
|
||
<li><a href="#plantuml">PlantUML</a></li>
|
||
<li><a href="#languagetool">LanguageTool</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#lisp">Lisp</a>
|
||
<ul>
|
||
<li><a href="#meta-lisp">Meta Lisp</a></li>
|
||
<li><a href="#emacs-lisp">Emacs Lisp</a>
|
||
<ul>
|
||
<li><a href="#package-lint">Package Lint</a></li>
|
||
<li><a href="#general-settings">General settings</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#common-lisp">Common lisp</a>
|
||
<ul>
|
||
<li><a href="#slime">SLIME</a></li>
|
||
<li><a href="#general-settings">General settings</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#clojure">Clojure</a></li>
|
||
<li><a href="#hy">Hy</a></li>
|
||
<li><a href="#scheme">Scheme</a></li>
|
||
<li><a href="#clips">CLIPS</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#python">Python</a>
|
||
<ul>
|
||
<li><a href="#pipenv">pipenv</a></li>
|
||
<li><a href="#yapf">yapf</a></li>
|
||
<li><a href="#isort">isort</a></li>
|
||
<li><a href="#sphinx-doc">sphinx-doc</a></li>
|
||
<li><a href="#pytest">pytest</a>
|
||
<ul>
|
||
<li><a href="#fix-comint-buffer-width">Fix comint buffer width</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#code-cells">code-cells</a></li>
|
||
<li><a href="#tensorboard">tensorboard</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#java">Java</a></li>
|
||
<li><a href="#go">Go</a></li>
|
||
<li><a href="#dot-net">.NET</a>
|
||
<ul>
|
||
<li><a href="#c">C#</a></li>
|
||
<li><a href="#msbuild">MSBuild</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#fish">fish</a></li>
|
||
<li><a href="#sh">sh</a></li>
|
||
<li><a href="#haskell">Haskell</a></li>
|
||
<li><a href="#lua">Lua</a></li>
|
||
<li><a href="#json">JSON</a></li>
|
||
<li><a href="#sql">SQL</a></li>
|
||
<li><a href="#yaml">YAML</a></li>
|
||
<li><a href="#dot-env">.env</a></li>
|
||
<li><a href="#csv">CSV</a></li>
|
||
<li><a href="#off--pdf"><span class="org-todo done OFF">OFF</span> (OFF) PDF</a></li>
|
||
<li><a href="#docker">Docker</a></li>
|
||
<li><a href="#crontab">crontab</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#apps-and-misc">Apps & Misc</a>
|
||
<ul>
|
||
<li><a href="#managing-dotfiles">Managing dotfiles</a>
|
||
<ul>
|
||
<li><a href="#open-emacs-config">Open Emacs config</a></li>
|
||
<li><a href="#open-magit-for-yadm">Open Magit for yadm</a></li>
|
||
<li><a href="#open-a-dotfile">Open a dotfile</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#internet-and-multimedia">Internet & 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-score">elfeed-score</a></li>
|
||
<li><a href="#youtube-and-emms">YouTube & 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="#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="#off--pomidor"><span class="org-todo done OFF">OFF</span> (OFF) Pomidor</a></li>
|
||
<li><a href="#calendar">Calendar</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#fun">Fun</a>
|
||
<ul>
|
||
<li><a href="#discord-integration">Discord integration</a></li>
|
||
<li><a href="#snow">Snow</a></li>
|
||
<li><a href="#zone">Zone</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#guix-settings">Guix settings</a></li>
|
||
</ul>
|
||
</div>
|
||
<!--endtoc-->
|
||
<h2 id="primary-setup">Primary setup</h2>
|
||
<h3 id="measure-startup-speed">Measure startup speed</h3>
|
||
<p>A small function to print out the loading time and number of GCs during the loading. Can be useful as a point of data for optimizing Emacs startup time.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'emacs-startup-hook</span>
|
||
(lambda ()
|
||
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"*** Emacs loaded in %s with %d garbage collections."</span>
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%.2f seconds"</span>
|
||
(<span style="color:#a6e22e">float-time</span>
|
||
(<span style="color:#a6e22e">time-subtract</span> after-init-time before-init-time)))
|
||
gcs-done)))
|
||
</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="color:#75715e">;; (setq use-package-verbose t)</span>
|
||
</code></pre></div><h3 id="straight-dot-el">straight.el</h3>
|
||
<p>Straight.el is my Emacs package manager of choice. Its advantages & disadvantages over other options are listed pretty thoroughly in the README file in the repo.</p>
|
||
<p>The following is a straight.el bootstrap script.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/raxod502/straight.el">straight.el repo</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defvar bootstrap-version)
|
||
(let ((bootstrap-file
|
||
(<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"straight/repos/straight.el/bootstrap.el"</span> user-emacs-directory))
|
||
(bootstrap-version <span style="color:#ae81ff">5</span>))
|
||
(unless (<span style="color:#a6e22e">file-exists-p</span> bootstrap-file)
|
||
(with-current-buffer
|
||
(url-retrieve-synchronously
|
||
<span style="color:#e6db74">"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"</span>
|
||
<span style="color:#e6db74">'silent</span> <span style="color:#e6db74">'inhibit-cookies</span>)
|
||
(<span style="color:#a6e22e">goto-char</span> (<span style="color:#a6e22e">point-max</span>))
|
||
(eval-print-last-sexp)))
|
||
(<span style="color:#a6e22e">load</span> bootstrap-file <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">'nomessage</span>))
|
||
</code></pre></div><h3 id="use-package">use-package</h3>
|
||
<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">(straight-use-package <span style="color:#e6db74">'use-package</span>)
|
||
(eval-when-compile (require <span style="color:#e6db74">'use-package</span>))
|
||
</code></pre></div><h3 id="config-variants-and-environment">Config variants & environment</h3>
|
||
<p>This section is about optionating 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">(setq my/lowpower (string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"azure"</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">(setq my/slow-ssh
|
||
(or
|
||
(string= (getenv <span style="color:#e6db74">"IS_TRAMP"</span>) <span style="color:#e6db74">"true"</span>)
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"dev-digital"</span>)
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"violet"</span>)))
|
||
</code></pre></div><p>The following is true is Emacs is ran 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">(setq my/remote-server
|
||
(or (string= (getenv <span style="color:#e6db74">"IS_REMOTE"</span>) <span style="color:#e6db74">"true"</span>)
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"dev-digital"</span>)
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"violet"</span>)))
|
||
</code></pre></div><p>And the following is true if Emacs is run from termux on Android.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/is-termux (string-match-p (rx (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">"com.termux"</span> (<span style="color:#a6e22e">*</span> nonl)) (getenv <span style="color:#e6db74">"HOME"</span>)))
|
||
</code></pre></div><p>Also, I sometimes need to know if a program is running inside Emacs (say, inside a terminal emulator). To do that, I set the following environment variable:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setenv <span style="color:#e6db74">"IS_EMACS"</span> <span style="color:#e6db74">"true"</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"><<minimal>>
|
||
</code></pre></div><p>To launch Emacs with this config, run</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">emacs -q -l ~/.emacs.d/init-minimal.el
|
||
</code></pre></div><h3 id="performance">Performance</h3>
|
||
<h4 id="garbage-collection">Garbage collection</h4>
|
||
<p>Just setting <code>gc-cons-treshold</code> to a larger value.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq gc-cons-threshold <span style="color:#ae81ff">80000000</span>)
|
||
(setq read-process-output-max (<span style="color:#a6e22e">*</span> <span style="color:#ae81ff">1024</span> <span style="color:#ae81ff">1024</span>))
|
||
</code></pre></div><h4 id="run-garbage-collection-when-emacs-is-unfocused">Run garbage collection when Emacs is unfocused</h4>
|
||
<p>Run GC when Emacs loses focus. <del>Time will tell if that’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">(add-hook <span style="color:#e6db74">'emacs-startup-hook</span>
|
||
(lambda ()
|
||
(if (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'after-focus-change-function</span>)
|
||
(add-function :after after-focus-change-function
|
||
(lambda ()
|
||
(unless (frame-focus-state)
|
||
(<span style="color:#a6e22e">garbage-collect</span>))))
|
||
(add-hook <span style="color:#e6db74">'after-focus-change-function</span> <span style="color:#e6db74">'garbage-collect</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">(when my/lowpower
|
||
(setq comp-async-jobs-number <span style="color:#ae81ff">1</span>))
|
||
</code></pre></div><h3 id="anaconda">Anaconda</h3>
|
||
<p><a href="https://www.anaconda.com/">Anaconda</a> is a free package and environment manager. I currently use it to manage multiple versions of Python and Node.js. Take a look at <a href="/configs/guix/">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 auxililary environment variable. This variable is used in the <a href="/configs/console/">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">(use-package conda
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (executable-find <span style="color:#e6db74">"conda"</span>)
|
||
:config
|
||
(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>)))
|
||
(setq conda-env-home-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/.conda/"</span>))
|
||
(setq conda-env-subdirectory <span style="color:#e6db74">"envs"</span>)
|
||
(setenv <span style="color:#e6db74">"INIT_CONDA"</span> <span style="color:#e6db74">"true"</span>)
|
||
(advice-add <span style="color:#e6db74">'conda-env-activate</span> :after
|
||
(lambda (<span style="color:#66d9ef">&rest</span> _) (setenv <span style="color:#e6db74">"EMACS_CONDA_ENV"</span> conda-env-current-name)))
|
||
(unless (getenv <span style="color:#e6db74">"CONDA_DEFAULT_ENV"</span>)
|
||
(conda-env-activate <span style="color:#e6db74">"general"</span>)))
|
||
</code></pre></div><h3 id="custom-file-location">Custom file location</h3>
|
||
<p>By default, custom writes stuff to <code>init.el</code>, which is somewhat annoying. The following makes 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">(setq custom-file (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"custom.el"</span>))
|
||
(<span style="color:#a6e22e">load</span> custom-file <span style="color:#e6db74">'noerror</span>)
|
||
</code></pre></div><h3 id="private-config">Private config</h3>
|
||
<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">(let ((private-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"private.el"</span> user-emacs-directory)))
|
||
|
||
(load-file private-file))
|
||
</code></pre></div><h3 id="no-littering">No littering</h3>
|
||
<p>By default Mmacs 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">(use-package no-littering
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h3 id="prevent-emacs-from-closing">Prevent Emacs from closing</h3>
|
||
<p>This adds a confirmation to avoid accidental Emacs closing.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq confirm-kill-emacs <span style="color:#e6db74">'y-or-n-p</span>)
|
||
</code></pre></div><h2 id="global-editing-configuration">Global editing configuration</h2>
|
||
<h3 id="general-keybindings-stuff">General keybindings stuff</h3>
|
||
<h4 id="general-dot-el">general.el</h4>
|
||
<p>general.el provides a convenient interface to manage Emacs keybindings.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/noctuid/general.el">general.el repo</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package general
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(general-evil-setup))
|
||
</code></pre></div><h4 id="which-key">which-key</h4>
|
||
<p>A package that displays the available keybindings in a popup. 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">(use-package which-key
|
||
:config
|
||
(setq which-key-idle-delay (if my/lowpower <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">0.3</span>))
|
||
(setq which-key-popup-type <span style="color:#e6db74">'frame</span>)
|
||
(which-key-mode)
|
||
(which-key-setup-side-window-bottom)
|
||
(set-face-attribute <span style="color:#e6db74">'which-key-local-map-description-face</span> <span style="color:#66d9ef">nil</span>
|
||
:weight <span style="color:#e6db74">'bold</span>)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h5 id="dump-keybindings">dump keybindings</h5>
|
||
<p>A function to dump keybindings starting with a prefix to a buffer in tree-like form.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dump-bindings-recursive (prefix <span style="color:#66d9ef">&optional</span> level)
|
||
(dolist (key (which-key--get-bindings (kbd prefix)))
|
||
(when level
|
||
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">make-string</span> level <span style="color:#e6db74">? </span>)))
|
||
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'format</span> <span style="color:#e6db74">"%s%s%s\n"</span> key))
|
||
(when (string-match-p
|
||
(rx bos <span style="color:#e6db74">"+"</span> (<span style="color:#a6e22e">*</span> nonl))
|
||
(<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">elt</span> key <span style="color:#ae81ff">2</span>)))
|
||
(my/dump-bindings-recursive
|
||
(<span style="color:#a6e22e">concat</span> prefix <span style="color:#e6db74">" "</span> (<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">car</span> key)))
|
||
(<span style="color:#a6e22e">+</span> <span style="color:#ae81ff">2</span> (or level <span style="color:#ae81ff">0</span>))))))
|
||
|
||
(defun my/dump-bindings (prefix)
|
||
<span style="color:#e6db74">"Dump keybindings starting with PREFIX in tree-like form."</span>
|
||
(interactive <span style="color:#e6db74">"sPrefix: "</span>)
|
||
(with-current-buffer (<span style="color:#a6e22e">get-buffer-create</span> <span style="color:#e6db74">"bindings"</span>)
|
||
(<span style="color:#a6e22e">point-max</span>)
|
||
(<span style="color:#a6e22e">erase-buffer</span>)
|
||
(save-excursion
|
||
(my/dump-bindings-recursive prefix)))
|
||
(switch-to-buffer-other-window <span style="color:#e6db74">"bindings"</span>))
|
||
</code></pre></div><h3 id="evil-mode">Evil mode</h3>
|
||
<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>
|
||
<h4 id="evil">evil</h4>
|
||
<p>Basic evil configuration.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:init
|
||
(setq evil-want-integration <span style="color:#66d9ef">t</span>)
|
||
(setq evil-want-C-u-scroll <span style="color:#66d9ef">t</span>)
|
||
(setq evil-want-keybinding <span style="color:#66d9ef">nil</span>)
|
||
(setq evil-search-module <span style="color:#e6db74">'evil-search</span>)
|
||
(setq evil-split-window-below <span style="color:#66d9ef">t</span>)
|
||
(setq evil-vsplit-window-right <span style="color:#66d9ef">t</span>)
|
||
:config
|
||
(evil-mode <span style="color:#ae81ff">1</span>)
|
||
<span style="color:#75715e">;; (setq evil-respect-visual-line-mode t)</span>
|
||
(evil-set-undo-system <span style="color:#e6db74">'undo-tree</span>))
|
||
</code></pre></div><h4 id="addons">Addons</h4>
|
||
<p><a href="https://github.com/emacs-evil/evil-surround">evil-surround</a> emulates one of my favorite vim plugins, surround.vim. Adds a lot of parentheses management options.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-surround
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after evil
|
||
:config
|
||
(global-evil-surround-mode <span style="color:#ae81ff">1</span>))
|
||
</code></pre></div><p><a href="https://github.com/linktohack/evil-commentary">evil-commentary</a> emulates commentary.vim. It gives 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">(use-package evil-commentary
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after evil
|
||
:config
|
||
(evil-commentary-mode))
|
||
</code></pre></div><p><a href="https://github.com/blorbx/evil-quickscope">evil-quickscope</a> emulates quickscope.vim. It highlights the important target characters for f, F, t, T keys.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-quickscope
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after evil
|
||
:config
|
||
:hook ((prog-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
|
||
(LaTeX-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)
|
||
(org-mode <span style="color:#f92672">.</span> turn-on-evil-quickscope-mode)))
|
||
</code></pre></div><p><a href="https://github.com/cofi/evil-numbers">evil-numbers</a> allows incrementing and decrementing numbers at the point.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-numbers
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (evil-numbers/inc-at-pt evil-numbers/dec-at-pt)
|
||
:init
|
||
(general-nmap
|
||
<span style="color:#e6db74">"g+"</span> <span style="color:#e6db74">'evil-numbers/inc-at-pt</span>
|
||
<span style="color:#e6db74">"g-"</span> <span style="color:#e6db74">'evil-numbers/dec-at-pt</span>))
|
||
</code></pre></div><p><a href="https://github.com/edkolev/evil-lion">evil-lion</a> provides alignment operators, somewhat similar to vim-easyalign.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-lion
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(setq evil-lion-left-align-key (kbd <span style="color:#e6db74">"g a"</span>))
|
||
(setq evil-lion-right-align-key (kbd <span style="color:#e6db74">"g A"</span>))
|
||
(evil-lion-mode))
|
||
</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 occasionally 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">(use-package evil-matchit
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(global-evil-matchit-mode <span style="color:#ae81ff">1</span>))
|
||
</code></pre></div><h4 id="evil-collection">evil-collection</h4>
|
||
<p><a href="https://github.com/emacs-evil/evil-collection">evil-collection</a> is a package that provides evil bindings for a lot of different packages. One can see the 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">(use-package evil-collection
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after evil
|
||
:config
|
||
(evil-collection-init
|
||
<span style="color:#f92672">'</span>(eww
|
||
devdocs
|
||
proced
|
||
emms
|
||
pass
|
||
calendar
|
||
dired
|
||
ivy
|
||
debug
|
||
guix
|
||
calc
|
||
docker
|
||
ibuffer
|
||
geiser
|
||
pdf
|
||
info
|
||
elfeed
|
||
edebug
|
||
bookmark
|
||
company
|
||
vterm
|
||
flycheck
|
||
profiler
|
||
cider
|
||
explain-pause-mode
|
||
notmuch
|
||
custom
|
||
xref
|
||
eshell
|
||
helpful
|
||
compile
|
||
comint
|
||
git-timemachine
|
||
magit
|
||
prodigy
|
||
slime)))
|
||
</code></pre></div><h3 id="more-keybindings">More keybindings</h3>
|
||
<p>The main keybindings setup is positioned after evil mode to take the latter into account.</p>
|
||
<h4 id="escape-key">Escape key</h4>
|
||
<p>Use the escape key instead of <code>C-g</code> whenever possible.</p>
|
||
<p>I must have copied it from somewhere, but as I googled to find out the source, I discovered quite a number of variations of the following code over time. I wonder if Richard Dawkins was inspired by something like this a few decades ago.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun minibuffer-keyboard-quit ()
|
||
<span style="color:#e6db74">"Abort recursive edit.
|
||
</span><span style="color:#e6db74">In Delete Selection mode, if the mark is active, just deactivate it;
|
||
</span><span style="color:#e6db74">then it takes a second \\[keyboard-quit] to abort the minibuffer."</span>
|
||
(interactive)
|
||
(if (and delete-selection-mode transient-mark-mode mark-active)
|
||
(setq deactivate-mark <span style="color:#66d9ef">t</span>)
|
||
(when (<span style="color:#a6e22e">get-buffer</span> <span style="color:#e6db74">"*Completions*"</span>) (delete-windows-on <span style="color:#e6db74">"*Completions*"</span>))
|
||
(<span style="color:#a6e22e">abort-recursive-edit</span>)))
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(normal visual global)
|
||
[escape] <span style="color:#e6db74">'keyboard-quit</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(minibuffer-local-map
|
||
minibuffer-local-ns-map
|
||
minibuffer-local-completion-map
|
||
minibuffer-local-must-match-map
|
||
minibuffer-local-isearch-map)
|
||
[escape] <span style="color:#e6db74">'minibuffer-keyboard-quit</span>)
|
||
</code></pre></div><h4 id="home-and-end">Home & end</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-def :states <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span> visual)
|
||
<span style="color:#e6db74">"<home>"</span> <span style="color:#e6db74">'beginning-of-line</span>
|
||
<span style="color:#e6db74">"<end>"</span> <span style="color:#e6db74">'end-of-line</span>)
|
||
</code></pre></div><h4 id="my-leader">My leader</h4>
|
||
<p>Using the <code>SPC</code> key as a leader key, like in Doom Emacs or Spacemacs.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-create-definer my-leader-def
|
||
:keymaps <span style="color:#e6db74">'override</span>
|
||
:prefix <span style="color:#e6db74">"SPC"</span>
|
||
:states <span style="color:#f92672">'</span>(normal motion emacs))
|
||
|
||
(general-def :states <span style="color:#f92672">'</span>(normal motion emacs)
|
||
<span style="color:#e6db74">"SPC"</span> <span style="color:#66d9ef">nil</span>
|
||
<span style="color:#e6db74">"M-SPC"</span> (general-key <span style="color:#e6db74">"SPC"</span>))
|
||
|
||
(general-def :states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span>)
|
||
<span style="color:#e6db74">"M-SPC"</span> (general-key <span style="color:#e6db74">"SPC"</span> :state <span style="color:#e6db74">'normal</span>))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"?"</span> <span style="color:#e6db74">'which-key-show-top-level</span>)
|
||
(my-leader-def <span style="color:#e6db74">"E"</span> <span style="color:#e6db74">'eval-expression</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">(my-leader-def
|
||
<span style="color:#e6db74">"a"</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"apps"</span>))
|
||
</code></pre></div><h4 id="universal-argument">Universal argument</h4>
|
||
<p>Change the universal argument to <code>M-u</code>. I use <code>C-u</code> to scroll up, as I’m used to from vim.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-def
|
||
:keymaps <span style="color:#e6db74">'universal-argument-map</span>
|
||
<span style="color:#e6db74">"M-u"</span> <span style="color:#e6db74">'universal-argument-more</span>)
|
||
(general-def
|
||
:keymaps <span style="color:#e6db74">'override</span>
|
||
:states <span style="color:#f92672">'</span>(normal motion emacs <span style="color:#a6e22e">insert</span> visual)
|
||
<span style="color:#e6db74">"M-u"</span> <span style="color:#e6db74">'universal-argument</span>)
|
||
</code></pre></div><h4 id="profiler">Profiler</h4>
|
||
<p>The built-in profiler is a magnificent tool to troubleshoot performance issues.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"P"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"profiler"</span>)
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'profiler-start</span>
|
||
<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'profiler-stop</span>
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'profiler-report</span>)
|
||
</code></pre></div><h4 id="buffer-switching">Buffer switching</h4>
|
||
<p>Some keybindings I used in vim to switch buffers and can’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">(general-define-key
|
||
:keymaps <span style="color:#e6db74">'override</span>
|
||
<span style="color:#e6db74">"C-<right>"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
<span style="color:#e6db74">"C-<left>"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
<span style="color:#e6db74">"C-<up>"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
<span style="color:#e6db74">"C-<down>"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
<span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
<span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
<span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
<span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
<span style="color:#e6db74">"C-x h"</span> <span style="color:#e6db74">'previous-buffer</span>
|
||
<span style="color:#e6db74">"C-x l"</span> <span style="color:#e6db74">'next-buffer</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'evil-window-map</span>
|
||
<span style="color:#e6db74">"x"</span> <span style="color:#e6db74">'kill-buffer-and-window</span>
|
||
<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'kill-current-buffer</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">(winner-mode <span style="color:#ae81ff">1</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'evil-window-map</span>
|
||
<span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'winner-undo</span>
|
||
<span style="color:#e6db74">"U"</span> <span style="color:#e6db74">'winner-redo</span>)
|
||
</code></pre></div><h4 id="buffer-management">Buffer management</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"b"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"buffers"</span>)
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#f92672">'</span>((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||
:which-key <span style="color:#e6db74">"*scratch*"</span>)
|
||
<span style="color:#e6db74">"m"</span> <span style="color:#f92672">'</span>((lambda () (interactive) (persp-switch-to-buffer <span style="color:#e6db74">"*Messages*"</span>))
|
||
:which-key <span style="color:#e6db74">"*Messages*"</span>)
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'next-buffer</span>
|
||
<span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'previous-buffer</span>
|
||
<span style="color:#e6db74">"k"</span> <span style="color:#e6db74">'kill-buffer</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'revert-buffer</span>
|
||
<span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'ibuffer</span>)
|
||
</code></pre></div><h4 id="xref">xref</h4>
|
||
<p>Some keybindings for xref and go to definition.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-nmap
|
||
<span style="color:#e6db74">"gD"</span> <span style="color:#e6db74">'xref-find-definitions-other-window</span>
|
||
<span style="color:#e6db74">"gr"</span> <span style="color:#e6db74">'xref-find-references</span>
|
||
<span style="color:#e6db74">"gd"</span> <span style="color:#e6db74">'evil-goto-definition</span>)
|
||
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"fx"</span> <span style="color:#e6db74">'xref-find-apropos</span>)
|
||
</code></pre></div><h4 id="folding">Folding</h4>
|
||
<p>There are multiple ways to fold text in Emacs.</p>
|
||
<p>The most versatile is the built-in <code>hs-minor-mode</code>, which seems to work out of the box for Lisps, C-like languages and Python. <code>outline-minor-mode</code> works for org-mode, LaTeX and the like. There is a 3rd-party solution <a href="https://github.com/elp-revive/origami.el">origami.el</a>, but I don’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">(general-nmap :keymaps <span style="color:#f92672">'</span>(hs-minor-mode-map outline-minor-mode-map)
|
||
<span style="color:#e6db74">"ze"</span> <span style="color:#e6db74">'hs-hide-level</span>
|
||
<span style="color:#e6db74">"TAB"</span> <span style="color:#e6db74">'evil-toggle-fold</span>)
|
||
</code></pre></div><h4 id="zoom">Zoom</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/zoom-in ()
|
||
<span style="color:#e6db74">"Increase font size by 10 points"</span>
|
||
(interactive)
|
||
(set-face-attribute <span style="color:#e6db74">'default</span> <span style="color:#66d9ef">nil</span>
|
||
:height
|
||
(<span style="color:#a6e22e">+</span> (face-attribute <span style="color:#e6db74">'default</span> :height) <span style="color:#ae81ff">10</span>)))
|
||
|
||
(defun my/zoom-out ()
|
||
<span style="color:#e6db74">"Decrease font size by 10 points"</span>
|
||
(interactive)
|
||
(set-face-attribute <span style="color:#e6db74">'default</span> <span style="color:#66d9ef">nil</span>
|
||
:height
|
||
(<span style="color:#a6e22e">-</span> (face-attribute <span style="color:#e6db74">'default</span> :height) <span style="color:#ae81ff">10</span>)))
|
||
|
||
<span style="color:#75715e">;; change font size, interactively</span>
|
||
(global-set-key (kbd <span style="color:#e6db74">"C-+"</span>) <span style="color:#e6db74">'my/zoom-in</span>)
|
||
(global-set-key (kbd <span style="color:#e6db74">"C-="</span>) <span style="color:#e6db74">'my/zoom-out</span>)
|
||
</code></pre></div><h3 id="i3-integration">i3 integration</h3>
|
||
<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="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>
|
||
command<span style="color:#f92672">=</span><span style="color:#e6db74">"(my/emacs-i3-integration \"</span>$@<span style="color:#e6db74">\")"</span>
|
||
emacsclient -e <span style="color:#e6db74">"</span>$command<span style="color:#e6db74">"</span>
|
||
<span style="color:#66d9ef">else</span>
|
||
i3-msg $@
|
||
<span style="color:#66d9ef">fi</span>
|
||
</code></pre></div><p>This script is being run from the <a href="/configs/desktop/">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">(add-hook <span style="color:#e6db74">'after-init-hook</span> <span style="color:#a6e22e">#'</span>server-start)
|
||
</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">(defmacro i3-msg (<span style="color:#66d9ef">&rest</span> args)
|
||
<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))
|
||
</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">(defun my/emacs-i3-windmove (dir)
|
||
(let ((other-window (windmove-find-other-window dir)))
|
||
(if (or (<span style="color:#a6e22e">null</span> other-window) (<span style="color:#a6e22e">window-minibuffer-p</span> other-window))
|
||
(i3-msg <span style="color:#e6db74">"focus"</span> (<span style="color:#a6e22e">symbol-name</span> dir))
|
||
(windmove-do-window-select dir))))
|
||
</code></pre></div><p>For the <code>move</code> I want the following behavior:</p>
|
||
<ul>
|
||
<li>if there is space in the required directon, 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">(defun my/emacs-i3-direction-exists-p (dir)
|
||
(cl-some (lambda (dir)
|
||
(let ((win (windmove-find-other-window dir)))
|
||
(and win (not (<span style="color:#a6e22e">window-minibuffer-p</span> win)))))
|
||
(pcase dir
|
||
(<span style="color:#e6db74">'width</span> <span style="color:#f92672">'</span>(left right))
|
||
(<span style="color:#e6db74">'height</span> <span style="color:#f92672">'</span>(up down)))))
|
||
</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">(defun my/emacs-i3-move-window (dir)
|
||
(let ((other-window (windmove-find-other-window dir))
|
||
(other-direction (my/emacs-i3-direction-exists-p
|
||
(pcase dir
|
||
(<span style="color:#e6db74">'up</span> <span style="color:#e6db74">'width</span>)
|
||
(<span style="color:#e6db74">'down</span> <span style="color:#e6db74">'width</span>)
|
||
(<span style="color:#e6db74">'left</span> <span style="color:#e6db74">'height</span>)
|
||
(<span style="color:#e6db74">'right</span> <span style="color:#e6db74">'height</span>)))))
|
||
(cond
|
||
((and other-window (not (<span style="color:#a6e22e">window-minibuffer-p</span> other-window)))
|
||
(window-swap-states (<span style="color:#a6e22e">selected-window</span>) other-window))
|
||
(other-direction
|
||
(evil-move-window dir))
|
||
(<span style="color:#66d9ef">t</span> (i3-msg <span style="color:#e6db74">"move"</span> (<span style="color:#a6e22e">symbol-name</span> dir))))))
|
||
</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">(defun my/emacs-i3-resize-window (dir kind value)
|
||
(if (or (one-window-p)
|
||
(not (my/emacs-i3-direction-exists-p dir)))
|
||
(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 style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s px or %s ppt"</span> value value))
|
||
(setq value (<span style="color:#a6e22e">/</span> value <span style="color:#ae81ff">2</span>))
|
||
(pcase kind
|
||
(<span style="color:#e6db74">'shrink</span>
|
||
(pcase dir
|
||
(<span style="color:#e6db74">'width</span>
|
||
(evil-window-decrease-width value))
|
||
(<span style="color:#e6db74">'height</span>
|
||
(evil-window-decrease-height value))))
|
||
(<span style="color:#e6db74">'grow</span>
|
||
(pcase dir
|
||
(<span style="color:#e6db74">'width</span>
|
||
(evil-window-increase-width value))
|
||
(<span style="color:#e6db74">'height</span>
|
||
(evil-window-increase-height value)))))))
|
||
</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">(use-package transpose-frame
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (transpose-frame))
|
||
</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">(defun my/emacs-i3-integration (command)
|
||
(pcase command
|
||
((rx bos <span style="color:#e6db74">"focus"</span>)
|
||
(my/emacs-i3-windmove
|
||
(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</span>))))
|
||
((rx bos <span style="color:#e6db74">"move"</span>)
|
||
(my/emacs-i3-move-window
|
||
(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</span>))))
|
||
((rx bos <span style="color:#e6db74">"resize"</span>)
|
||
(my/emacs-i3-resize-window
|
||
(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">2</span>))
|
||
(<span style="color:#a6e22e">intern</span> (<span style="color:#a6e22e">elt</span> (split-string command) <span style="color:#ae81ff">1</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 style="color:#e6db74">"layout toggle split"</span> (transpose-frame))
|
||
(<span style="color:#e6db74">"split h"</span> (evil-window-split))
|
||
(<span style="color:#e6db74">"split v"</span> (evil-window-vsplit))
|
||
(<span style="color:#e6db74">"kill"</span> (evil-quit))
|
||
(<span style="color:#a6e22e">-</span> (i3-msg command))))
|
||
</code></pre></div><h3 id="editing-helpers">Editing helpers</h3>
|
||
<h4 id="visual-fill-column-mode">Visual fill column mode</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package visual-fill-column
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'visual-fill-column-mode-hook</span>
|
||
(lambda () (setq visual-fill-column-center-text <span style="color:#66d9ef">t</span>))))
|
||
</code></pre></div><h4 id="smartparens">smartparens</h4>
|
||
<p>A minor mode to deal with pairs. Its functionality overlaps with evil-surround, but smartparens provides the most comfortable way to do stuff like automatically insert pairs.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/Fuco1/smartparens">smartparens repo</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package smartparens
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="aggressive-indent">Aggressive Indent</h4>
|
||
<p>A package to keep the code intended.</p>
|
||
<p>Doesn’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">(use-package aggressive-indent
|
||
:commands (aggressive-indent-mode)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="delete-trailing-whitespace">Delete trailing whitespace</h4>
|
||
<p>Delete trailing whitespace on save, unless in particular modes where trailing whitespace is important, like Markdown.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/trailing-whitespace-modes <span style="color:#f92672">'</span>(markdown-mode))
|
||
|
||
(require <span style="color:#e6db74">'cl-extra</span>)
|
||
|
||
(add-hook <span style="color:#e6db74">'before-save-hook</span>
|
||
(lambda ()
|
||
(unless (cl-some <span style="color:#a6e22e">#'</span>derived-mode-p my/trailing-whitespace-modes)
|
||
(delete-trailing-whitespace))))
|
||
</code></pre></div><h4 id="expand-region">Expand region</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package expand-region
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (er/expand-region)
|
||
:init
|
||
(general-nmap <span style="color:#e6db74">"+"</span> <span style="color:#e6db74">'er/expand-region</span>))
|
||
</code></pre></div><h3 id="various-settings">Various settings</h3>
|
||
<h4 id="tabs">Tabs</h4>
|
||
<p>Some default settings to manage tabs.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq tab-always-indent <span style="color:#66d9ef">nil</span>)
|
||
|
||
(setq-default default-tab-width <span style="color:#ae81ff">4</span>)
|
||
(setq-default tab-width <span style="color:#ae81ff">4</span>)
|
||
(setq-default evil-indent-convert-tabs <span style="color:#66d9ef">nil</span>)
|
||
(setq-default indent-tabs-mode <span style="color:#66d9ef">nil</span>)
|
||
(setq-default tab-width <span style="color:#ae81ff">4</span>)
|
||
(setq-default evil-shift-round <span style="color:#66d9ef">nil</span>)
|
||
</code></pre></div><h4 id="scrolling-config">Scrolling config</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq scroll-conservatively scroll-margin)
|
||
(setq scroll-step <span style="color:#ae81ff">1</span>)
|
||
(setq scroll-preserve-screen-position <span style="color:#66d9ef">t</span>)
|
||
(setq scroll-error-top-bottom <span style="color:#66d9ef">t</span>)
|
||
(setq mouse-wheel-progressive-speed <span style="color:#66d9ef">nil</span>)
|
||
(setq mouse-wheel-inhibit-click-time <span style="color:#66d9ef">nil</span>)
|
||
</code></pre></div><h4 id="clipboard">Clipboard</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq select-enable-clipboard <span style="color:#66d9ef">t</span>)
|
||
(setq mouse-yank-at-point <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="backups">Backups</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq backup-inhibited <span style="color:#66d9ef">t</span>)
|
||
(setq auto-save-default <span style="color:#66d9ef">nil</span>)
|
||
</code></pre></div><h3 id="undo-tree">Undo Tree</h3>
|
||
<p>Replaces Emacs build-in sequential undo system with a tree-based one. Probably one of the greatest features of Emacs as a text editor.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://www.emacswiki.org/emacs/UndoTree">UndoTree on EmacsWiki</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package undo-tree
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(global-undo-tree-mode)
|
||
(setq undo-tree-visualizer-diff <span style="color:#66d9ef">t</span>)
|
||
(setq undo-tree-visualizer-timestamps <span style="color:#66d9ef">t</span>)
|
||
|
||
(my-leader-def <span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'undo-tree-visualize</span>)
|
||
(<span style="color:#a6e22e">fset</span> <span style="color:#e6db74">'undo-auto-amalgamate</span> <span style="color:#e6db74">'ignore</span>)
|
||
(setq undo-limit <span style="color:#ae81ff">6710886400</span>)
|
||
(setq undo-strong-limit <span style="color:#ae81ff">100663296</span>)
|
||
(setq undo-outer-limit <span style="color:#ae81ff">1006632960</span>))
|
||
</code></pre></div><h3 id="help">Help</h3>
|
||
<p><a href="https://github.com/Wilfred/helpful">helpful</a> package improves the <code>*help*</code> buffer.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package helpful
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (helpful-callable
|
||
helpful-variable
|
||
helpful-key
|
||
helpful-macro
|
||
helpful-function
|
||
helpful-command))
|
||
|
||
</code></pre></div><p>As I use <code>C-h</code> to switch buffers, I moved the help to <code>SPC-h</code> with the code below. Of course, I didn’t type it all by hand.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"h"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"help"</span>)
|
||
<span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'view-order-manuals</span>
|
||
<span style="color:#e6db74">"."</span> <span style="color:#e6db74">'display-local-help</span>
|
||
<span style="color:#e6db74">"?"</span> <span style="color:#e6db74">'help-for-help</span>
|
||
<span style="color:#e6db74">"C"</span> <span style="color:#e6db74">'describe-coding-system</span>
|
||
<span style="color:#e6db74">"F"</span> <span style="color:#e6db74">'Info-goto-emacs-command-node</span>
|
||
<span style="color:#e6db74">"I"</span> <span style="color:#e6db74">'describe-input-method</span>
|
||
<span style="color:#e6db74">"K"</span> <span style="color:#e6db74">'Info-goto-emacs-key-command-node</span>
|
||
<span style="color:#e6db74">"L"</span> <span style="color:#e6db74">'describe-language-environment</span>
|
||
<span style="color:#e6db74">"P"</span> <span style="color:#e6db74">'describe-package</span>
|
||
<span style="color:#e6db74">"S"</span> <span style="color:#e6db74">'info-lookup-symbol</span>
|
||
<span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'helm-apropos</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'describe-bindings</span>
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'describe-key-briefly</span>
|
||
<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'apropos-documentation</span>
|
||
<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'view-echo-area-messages</span>
|
||
<span style="color:#e6db74">"f"</span> <span style="color:#e6db74">'helpful-function</span>
|
||
<span style="color:#e6db74">"g"</span> <span style="color:#e6db74">'describe-gnu-project</span>
|
||
<span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'view-hello-file</span>
|
||
<span style="color:#e6db74">"i"</span> <span style="color:#e6db74">'info</span>
|
||
<span style="color:#e6db74">"k"</span> <span style="color:#e6db74">'helpful-key</span>
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'view-lossage</span>
|
||
<span style="color:#e6db74">"m"</span> <span style="color:#e6db74">'describe-mode</span>
|
||
<span style="color:#e6db74">"n"</span> <span style="color:#e6db74">'view-emacs-news</span>
|
||
<span style="color:#e6db74">"o"</span> <span style="color:#e6db74">'describe-symbol</span>
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'finder-by-keyword</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'help-quit</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'info-emacs-manual</span>
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'describe-syntax</span>
|
||
<span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'help-with-tutorial</span>
|
||
<span style="color:#e6db74">"v"</span> <span style="color:#e6db74">'helpful-variable</span>
|
||
<span style="color:#e6db74">"w"</span> <span style="color:#e6db74">'where-is</span>
|
||
<span style="color:#e6db74">"<f1>"</span> <span style="color:#e6db74">'help-for-help</span>)
|
||
</code></pre></div><h3 id="ivy-counsel-swiper">Ivy, counsel, swiper</h3>
|
||
<p>Minibuffer completion tools for Emacs.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://oremacs.com/swiper/">repo</a></li>
|
||
<li><a href="https://oremacs.com/swiper/">User Manual</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(setq ivy-use-virtual-buffers <span style="color:#66d9ef">t</span>)
|
||
(ivy-mode))
|
||
|
||
(use-package counsel
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after ivy
|
||
:config
|
||
(counsel-mode))
|
||
|
||
(use-package swiper
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="ivy-rich">ivy-rich</h4>
|
||
<p><a href="https://github.com/Yevgnen/ivy-rich">ivy-rich</a> provides a more informative interface for ivy.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy-rich
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after ivy
|
||
:config
|
||
(ivy-rich-mode <span style="color:#ae81ff">1</span>)
|
||
(<span style="color:#a6e22e">setcdr</span> (<span style="color:#a6e22e">assq</span> <span style="color:#66d9ef">t</span> ivy-format-functions-alist) <span style="color:#a6e22e">#'</span>ivy-format-function-line))
|
||
</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">(use-package ivy-prescient
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after counsel
|
||
:config
|
||
(ivy-prescient-mode <span style="color:#ae81ff">+1</span>)
|
||
(setq ivy-prescient-retain-classic-highlighting <span style="color:#66d9ef">t</span>)
|
||
(prescient-persist-mode <span style="color:#ae81ff">1</span>)
|
||
(setq ivy-prescient-sort-commands
|
||
<span style="color:#f92672">'</span>(:not swiper
|
||
swiper-isearch
|
||
ivy-switch-buffer
|
||
<span style="color:#75715e">;; ivy-resume</span>
|
||
<span style="color:#75715e">;; ivy--restore-session</span>
|
||
lsp-ivy-workspace-symbol
|
||
dap-switch-stack-frame
|
||
my/dap-switch-stack-frame
|
||
dap-switch-session
|
||
dap-switch-thread
|
||
counsel-grep
|
||
<span style="color:#75715e">;; counsel-find-file</span>
|
||
counsel-git-grep
|
||
counsel-rg
|
||
counsel-ag
|
||
counsel-ack
|
||
counsel-fzf
|
||
counsel-pt
|
||
counsel-imenu
|
||
counsel-yank-pop
|
||
counsel-recentf
|
||
counsel-buffer-or-recentf
|
||
proced-filter-interactive
|
||
proced-sort-interactive))
|
||
<span style="color:#75715e">;; Do not use prescient in find-file</span>
|
||
(ivy--alist-set <span style="color:#e6db74">'ivy-sort-functions-alist</span> <span style="color:#a6e22e">#'</span>read-file-name-internal <span style="color:#a6e22e">#'</span>ivy-sort-file-function-default))
|
||
</code></pre></div><h4 id="keybindings">Keybindings</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"f"</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 style="color:#75715e">;; "b" 'counsel-switch-buffer</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'conda-env-activate</span>
|
||
<span style="color:#e6db74">"f"</span> <span style="color:#e6db74">'project-find-file</span>
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'counsel-yank-pop</span>
|
||
<span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'counsel-rg</span>
|
||
<span style="color:#e6db74">"A"</span> <span style="color:#e6db74">'counsel-ag</span>)
|
||
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span> normal)
|
||
<span style="color:#e6db74">"C-y"</span> <span style="color:#e6db74">'counsel-yank-pop</span>)
|
||
|
||
(my-leader-def <span style="color:#e6db74">"SPC"</span> <span style="color:#e6db74">'ivy-resume</span>)
|
||
(my-leader-def <span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'swiper-isearch</span>
|
||
<span style="color:#e6db74">"S"</span> <span style="color:#e6db74">'swiper-all</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(ivy-minibuffer-map swiper-map)
|
||
<span style="color:#e6db74">"M-j"</span> <span style="color:#e6db74">'ivy-next-line</span>
|
||
<span style="color:#e6db74">"M-k"</span> <span style="color:#e6db74">'ivy-previous-line</span>
|
||
<span style="color:#e6db74">"<C-return>"</span> <span style="color:#e6db74">'ivy-call</span>
|
||
<span style="color:#e6db74">"M-RET"</span> <span style="color:#e6db74">'ivy-immediate-done</span>
|
||
[escape] <span style="color:#e6db74">'minibuffer-keyboard-quit</span>)
|
||
</code></pre></div><h3 id="treemacs">Treemacs</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Note</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>TODO</td>
|
||
<td>Enable modeline only for particular treemacs instances</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><a href="https://github.com/Alexander-Miller/treemacs">Treemacs</a> calls itself a tree layout file explorer, but looks more like a project and workspace management system.</p>
|
||
<p>Integrates with evil, magit, projectile and perspective. The latter is particularly great - each perspective can have its own treemacs workspace!</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package treemacs
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (treemacs treemacs-switch-workspace treemacs-edit-workspace)
|
||
:config
|
||
(setq treemacs-follow-mode <span style="color:#66d9ef">nil</span>)
|
||
(setq treemacs-follow-after-init <span style="color:#66d9ef">nil</span>)
|
||
(setq treemacs-space-between-root-nodes <span style="color:#66d9ef">nil</span>)
|
||
(treemacs-git-mode <span style="color:#e6db74">'extended</span>)
|
||
(add-to-list <span style="color:#e6db74">'treemacs-pre-file-insert-predicates</span> <span style="color:#a6e22e">#'</span>treemacs-is-file-git-ignored?)
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'treemacs-mode-map</span>
|
||
[mouse-1] <span style="color:#a6e22e">#'</span>treemacs-single-click-expand-action
|
||
<span style="color:#e6db74">"M-l"</span> <span style="color:#a6e22e">#'</span>treemacs-root-down
|
||
<span style="color:#e6db74">"M-h"</span> <span style="color:#a6e22e">#'</span>treemacs-root-up))
|
||
|
||
(use-package treemacs-evil
|
||
:after (treemacs evil)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package treemacs-magit
|
||
:after (treemacs magit)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package treemacs-perspective
|
||
:after (treemacs perspective)
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(treemacs-set-scope-type <span style="color:#e6db74">'Perspectives</span>))
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(normal override global)
|
||
<span style="color:#e6db74">"C-n"</span> <span style="color:#e6db74">'treemacs</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(treemacs-mode-map) [mouse-1] <span style="color:#a6e22e">#'</span>treemacs-single-click-expand-action)
|
||
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"t"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"treemacs"</span>)
|
||
<span style="color:#e6db74">"w"</span> <span style="color:#e6db74">'treemacs-switch-workspace</span>
|
||
<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'treemacs-edit-workspaces</span>)
|
||
</code></pre></div><h4 id="helper-functions">Helper functions</h4>
|
||
<p>Function to open dired and vterm at given nodes.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/treemacs-open-dired ()
|
||
<span style="color:#e6db74">"Open dired at given treemacs node"</span>
|
||
(interactive)
|
||
(let (path (treemacs--prop-at-point :path))
|
||
(dired path)))
|
||
|
||
(defun my/treemacs-open-vterm ()
|
||
<span style="color:#e6db74">"Open vterm at given treemacs node"</span>
|
||
(interactive)
|
||
(let ((default-directory (<span style="color:#a6e22e">file-name-directory</span> (treemacs--prop-at-point :path))))
|
||
(vterm)))
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'treemacs</span>
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'treemacs-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(treemacs)
|
||
<span style="color:#e6db74">"gd"</span> <span style="color:#e6db74">'my/treemacs-open-dired</span>
|
||
<span style="color:#e6db74">"gt"</span> <span style="color:#e6db74">'my/treemacs-open-vterm</span>
|
||
<span style="color:#e6db74">"`"</span> <span style="color:#e6db74">'my/treemacs-open-vterm</span>))
|
||
</code></pre></div><h4 id="custom-icons">Custom icons</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (treemacs-define-custom-icon (concat " " (all-the-icons-fileicon "typescript")) "spec.ts")</span>
|
||
<span style="color:#75715e">;; (setq treemacs-file-extension-regex (rx "." (or "spec.ts" (+ (not "."))) eos))</span>
|
||
</code></pre></div><h3 id="projectile">Projectile</h3>
|
||
<p><a href="https://github.com/bbatsov/projectile">Projectile</a> gives a bunch of useful functions for managing projects, like finding files within a project, fuzzy-find, replace, etc.</p>
|
||
<p><code>defadvice</code> is meant to speed projectile up with TRAMP a bit.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package projectile
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(projectile-mode <span style="color:#ae81ff">+1</span>)
|
||
(setq projectile-project-search-path <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/Code"</span> <span style="color:#e6db74">"~/Documents"</span>))
|
||
(defadvice projectile-project-root (around ignore-remote first activate)
|
||
(unless (file-remote-p default-directory) ad-do-it)))
|
||
|
||
(use-package counsel-projectile
|
||
:after (counsel projectile)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package treemacs-projectile
|
||
:after (treemacs projectile)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#f92672">'</span>(:keymap projectile-command-map :which-key <span style="color:#e6db74">"projectile"</span>))
|
||
|
||
(general-nmap <span style="color:#e6db74">"C-p"</span> <span style="color:#e6db74">'counsel-projectile-find-file</span>)
|
||
</code></pre></div><h3 id="company">Company</h3>
|
||
<p>A completion framework for Emacs.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="http://company-mode.github.io/">company homepage</a></li>
|
||
<li><a href="https://github.com/sebastiencs/company-box">company-box homepage</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package company
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(global-company-mode)
|
||
(setq company-idle-delay (if my/lowpower <span style="color:#ae81ff">0.5</span> <span style="color:#ae81ff">0.125</span>))
|
||
(setq company-dabbrev-downcase <span style="color:#66d9ef">nil</span>)
|
||
(setq company-show-numbers <span style="color:#66d9ef">t</span>))
|
||
|
||
(general-imap <span style="color:#e6db74">"C-SPC"</span> <span style="color:#e6db74">'company-complete</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">(use-package company-box
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:disabled
|
||
:if (and (display-graphic-p) (not my/lowpower))
|
||
:after (company)
|
||
:hook (company-mode <span style="color:#f92672">.</span> company-box-mode))
|
||
</code></pre></div><h3 id="git-and-magit">Git & Magit</h3>
|
||
<p><a href="https://magit.vc/">Magic</a> is a git interface for Emacs. The closest non-Emacs alternative (sans actual clones) I know is <a href="https://github.com/jesseduffield/lazygit">lazygit</a>, which I used before Emacs.</p>
|
||
<p><a href="https://github.com/emacsorphanage/git-gutter">git-gutter</a> is a package which shows git changes for each line (added/changed/deleted lines).</p>
|
||
<p><a href="https://github.com/emacsmirror/git-timemachine">git-timemachine</a> allows to visit previous versions of a file.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package magit
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (magit-status magit-file-dispatch)
|
||
:config
|
||
(setq magit-blame-styles
|
||
<span style="color:#f92672">'</span>((margin
|
||
(margin-format <span style="color:#f92672">.</span> (<span style="color:#e6db74">"%a %A %s"</span>))
|
||
(margin-width <span style="color:#f92672">.</span> <span style="color:#ae81ff">42</span>)
|
||
(margin-face <span style="color:#f92672">.</span> magit-blame-margin)
|
||
(margin-body-face <span style="color:#f92672">.</span> (magit-blame-dimmed)))
|
||
(headings
|
||
(heading-format <span style="color:#f92672">.</span> <span style="color:#e6db74">"%-20a %C %s\n"</span>))
|
||
(highlight
|
||
(highlight-face <span style="color:#f92672">.</span> magit-blame-highlight))
|
||
(lines
|
||
(show-lines <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(show-message <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))))
|
||
|
||
(use-package git-gutter
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/slow-ssh)
|
||
:config
|
||
(global-git-gutter-mode <span style="color:#ae81ff">+1</span>))
|
||
|
||
(use-package git-timemachine
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (git-timemachine))
|
||
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"m"</span> <span style="color:#e6db74">'magit</span>
|
||
<span style="color:#e6db74">"M"</span> <span style="color:#e6db74">'magit-file-dispatch</span>)
|
||
</code></pre></div><h3 id="editorconfig">Editorconfig</h3>
|
||
<p>Editorconfig support for Emacs.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://editorconfig.org/">Editorconfig reference</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package editorconfig
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(unless my/slow-ssh (editorconfig-mode <span style="color:#ae81ff">1</span>))
|
||
(add-to-list <span style="color:#e6db74">'editorconfig-indentation-alist</span>
|
||
<span style="color:#f92672">'</span>(emmet-mode emmet-indentation)))
|
||
</code></pre></div><h3 id="snippets">Snippets</h3>
|
||
<p>A snippet system for Emacs and a collection of pre-built snippets.</p>
|
||
<p><code>yasnippet-snippets</code> has to be loaded before <code>yasnippet</code> for user snippets to override the pre-built ones.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="http://joaotavora.github.io/yasnippet/">yasnippet documentation</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yasnippet-snippets
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package yasnippet
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(setq yas-snippet-dirs
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">expand-file-name</span> user-emacs-directory) <span style="color:#e6db74">"snippets"</span>)
|
||
yasnippet-snippets-dir))
|
||
(setq yas-triggers-in-field <span style="color:#66d9ef">t</span>)
|
||
(yas-global-mode <span style="color:#ae81ff">1</span>))
|
||
|
||
(general-imap <span style="color:#e6db74">"M-TAB"</span> <span style="color:#e6db74">'company-yasnippet</span>)
|
||
</code></pre></div><h3 id="time-trackers">Time trackers</h3>
|
||
<p>A bunch of time trackers I use.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://wakatime.com">WakaTime</a></li>
|
||
<li><a href="https://activitywatch.net/">ActivityWatch</a></li>
|
||
</ul>
|
||
<h4 id="wakatime">WakaTime</h4>
|
||
<p>Before I figure out how to package this for Guix:</p>
|
||
<ul>
|
||
<li>Clone <a href="https://github.com/wakatime/wakatime-cli">the repo</a></li>
|
||
<li>Run <code>go build</code></li>
|
||
<li>Copy the binary to the <code>~/bin</code> folder</li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package wakatime-mode
|
||
:straight (:host github :repo <span style="color:#e6db74">"SqrtMinusOne/wakatime-mode"</span>)
|
||
:if (not (or my/is-termux my/remote-server))
|
||
:config
|
||
(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>))
|
||
(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 style="color:#75715e">;; (setq wakatime-cli-path (executable-find "wakatime"))</span>
|
||
(global-wakatime-mode))
|
||
</code></pre></div><h4 id="activitywatch">ActivityWatch</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package request
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package activity-watch-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not (or my/is-termux my/remote-server))
|
||
:config
|
||
(global-activity-watch-mode))
|
||
</code></pre></div><h2 id="ui">UI</h2>
|
||
<h3 id="general-ui-and-gui-settings">General UI & GUI Settings</h3>
|
||
<p>Disable GUI elements</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(unless my/is-termux
|
||
(tool-bar-mode <span style="color:#ae81ff">-1</span>)
|
||
(menu-bar-mode <span style="color:#ae81ff">-1</span>)
|
||
(scroll-bar-mode <span style="color:#ae81ff">-1</span>))
|
||
</code></pre></div><p>Transparency. Not setting it now, as I’m using <a href="/configs/desktop/">picom</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (set-frame-parameter (selected-frame) 'alpha '(90 . 90))</span>
|
||
<span style="color:#75715e">;; (add-to-list 'default-frame-alist '(alpha . (90 . 90)))</span>
|
||
</code></pre></div><p>Prettify symbols. Also not setting it, ligatures seem to be enough for me.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (global-prettify-symbols-mode)</span>
|
||
</code></pre></div><p>No start screen</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq inhibit-startup-screen <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><p>Visual bell</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq visible-bell <span style="color:#ae81ff">0</span>)
|
||
</code></pre></div><p>y or n instead of yes or no</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defalias <span style="color:#e6db74">'yes-or-no-p</span> <span style="color:#e6db74">'y-or-n-p</span>)
|
||
</code></pre></div><p>Hide mouse cursor while typing</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq make-pointer-invisible <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><p>Line numbers. There seems to be a catch with the relative number setting:</p>
|
||
<ul>
|
||
<li><code>visual</code> doesn’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">(global-display-line-numbers-mode <span style="color:#ae81ff">1</span>)
|
||
(line-number-mode <span style="color:#66d9ef">nil</span>)
|
||
(setq display-line-numbers-type <span style="color:#e6db74">'visual</span>)
|
||
(column-number-mode)
|
||
</code></pre></div><p>Show pairs</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(show-paren-mode <span style="color:#ae81ff">1</span>)
|
||
</code></pre></div><p>Word wrapping. These settings aren’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">(setq word-wrap <span style="color:#ae81ff">1</span>)
|
||
(global-visual-line-mode <span style="color:#ae81ff">1</span>)
|
||
</code></pre></div><p>Highlight current line</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(global-hl-line-mode <span style="color:#ae81ff">1</span>)
|
||
</code></pre></div><h3 id="theme-and-global-stuff">Theme & global stuff</h3>
|
||
<p>Dim inactive buffers.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package auto-dim-other-buffers
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (display-graphic-p)
|
||
:config
|
||
(auto-dim-other-buffers-mode <span style="color:#66d9ef">t</span>))
|
||
</code></pre></div><p>My colorscheme of choice.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package doom-themes
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/is-termux)
|
||
:config
|
||
(setq doom-themes-enable-bold <span style="color:#66d9ef">t</span>
|
||
doom-themes-enable-italic <span style="color:#66d9ef">t</span>)
|
||
(if my/remote-server
|
||
(load-theme <span style="color:#e6db74">'doom-gruvbox</span> <span style="color:#66d9ef">t</span>)
|
||
(load-theme <span style="color:#e6db74">'doom-palenight</span> <span style="color:#66d9ef">t</span>))
|
||
(doom-themes-visual-bell-config)
|
||
(setq doom-themes-treemacs-theme <span style="color:#e6db74">"doom-colors"</span>)
|
||
(doom-themes-treemacs-config))
|
||
</code></pre></div><h4 id="custom-theme">Custom theme</h4>
|
||
<p>A custom theme, dependent on Doom. I set all my custom variables there.</p>
|
||
<p>A custom theme is necessary because if one calls <code>custom-set-faces</code> and <code>custom-set-variables</code> in code, whenever a variable is changed and saved in a customize buffer, data from all calls of these functions is saved as well.</p>
|
||
<p>Also, a hook allows me to change doom-theme more or less at will, although I do that only to switch to a light theme once in a blue moon.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(unless my/is-termux
|
||
(deftheme my-theme-1)
|
||
|
||
(defun my/update-my-theme (<span style="color:#66d9ef">&rest</span> _)
|
||
(custom-theme-set-faces
|
||
<span style="color:#e6db74">'my-theme-1</span>
|
||
<span style="color:#f92672">`</span>(tab-bar-tab ((<span style="color:#66d9ef">t</span> (
|
||
:background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'bg</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)
|
||
:underline <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)))))
|
||
<span style="color:#f92672">`</span>(org-block ((<span style="color:#66d9ef">t</span> (:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>)))))
|
||
<span style="color:#f92672">`</span>(org-block-begin-line ((<span style="color:#66d9ef">t</span> (
|
||
:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'grey</span>)))))
|
||
<span style="color:#f92672">`</span>(auto-dim-other-buffers-face ((<span style="color:#66d9ef">t</span> (:background <span style="color:#f92672">,</span>(color-darken-name (doom-color <span style="color:#e6db74">'bg</span>) <span style="color:#ae81ff">3</span>)))))
|
||
<span style="color:#f92672">`</span>(aweshell-alert-buffer-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'red</span>) :weight bold))))
|
||
<span style="color:#f92672">`</span>(aweshell-alert-command-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>) :weight bold))))
|
||
<span style="color:#f92672">`</span>(epe-pipeline-delimiter-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'green</span>)))))
|
||
<span style="color:#f92672">`</span>(epe-pipeline-host-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'blue</span>)))))
|
||
<span style="color:#f92672">`</span>(epe-pipeline-time-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)))))
|
||
<span style="color:#f92672">`</span>(epe-pipeline-user-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'red</span>)))))
|
||
<span style="color:#f92672">`</span>(elfeed-search-tag-face ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)))))
|
||
<span style="color:#f92672">`</span>(notmuch-wash-cited-text ((<span style="color:#66d9ef">t</span> (:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-emacs ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'bg</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'fg</span>))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-insert ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'green</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'base0</span>))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-motion ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'magenta</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'base0</span>))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-normal ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'blue</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'base0</span>))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-replace ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'base0</span>))))
|
||
<span style="color:#f92672">`</span>(spaceline-evil-visual ((<span style="color:#66d9ef">t</span> :background <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'grey</span>)
|
||
:foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'base0</span>)))))
|
||
(custom-theme-set-variables
|
||
<span style="color:#e6db74">'my-theme-1</span>
|
||
<span style="color:#f92672">`</span>(aweshell-invalid-command-color <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'red</span>))
|
||
<span style="color:#f92672">`</span>(aweshell-valid-command-color <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'green</span>)))
|
||
(enable-theme <span style="color:#e6db74">'my-theme-1</span>))
|
||
|
||
(advice-add <span style="color:#e6db74">'load-theme</span> :after <span style="color:#a6e22e">#'</span>my/update-my-theme)
|
||
(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'doom-color</span>)
|
||
(my/update-my-theme)))
|
||
</code></pre></div><h4 id="font">Font</h4>
|
||
<p>To install a font, download the font and unpack it into the <code>.local/share/fonts</code> directory. Create one if it doesn’t exist.</p>
|
||
<p>As I use nerd fonts elsewhere, I use one in Emacs as well.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://nerdfonts.com">nerd fonts homepage</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(set-frame-font <span style="color:#e6db74">"JetBrainsMono Nerd Font 10"</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><p>To make the icons work (e.g. in the Doom Modeline), run <code>M-x all-the-icons-install-fonts</code>. The package definition is somewhere later in the config.</p>
|
||
<h3 id="custom-frame-title">Custom frame title</h3>
|
||
<p>Title format, which looks something like <code>emacs:project@hostname</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq-default frame-title-format
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">""</span>
|
||
<span style="color:#e6db74">"emacs"</span>
|
||
(:eval
|
||
(let ((project-name (projectile-project-name)))
|
||
(if (not (string= <span style="color:#e6db74">"-"</span> project-name))
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">":%s@%s"</span> project-name (<span style="color:#a6e22e">system-name</span>))
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"@%s"</span> (<span style="color:#a6e22e">system-name</span>)))))))
|
||
</code></pre></div><h3 id="perspective-dot-el">perspective.el</h3>
|
||
<p><a href="https://github.com/nex3/perspective-el">perspective.el</a> is a package which provides gives Emacs capacities to group buffers into “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">(use-package perspective
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:init
|
||
<span style="color:#75715e">;; (setq persp-show-modestring 'header)</span>
|
||
(setq persp-sort <span style="color:#e6db74">'created</span>)
|
||
:config
|
||
(persp-mode)
|
||
(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>))
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'override</span>
|
||
:states <span style="color:#f92672">'</span>(normal emacs)
|
||
<span style="color:#e6db74">"gt"</span> <span style="color:#e6db74">'persp-next</span>
|
||
<span style="color:#e6db74">"gT"</span> <span style="color:#e6db74">'persp-prev</span>
|
||
<span style="color:#e6db74">"gn"</span> <span style="color:#e6db74">'persp-switch</span>
|
||
<span style="color:#e6db74">"gN"</span> <span style="color:#e6db74">'persp-kill</span>)
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'perspective-map</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
<span style="color:#e6db74">"x"</span> <span style="color:#e6db74">'persp-ivy-switch-buffer</span>
|
||
<span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'persp-ibuffer</span>))
|
||
</code></pre></div><h4 id="some-functions">Some functions</h4>
|
||
<p>Move the current buffer to a perspective and switch to it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/persp-move-window-and-switch ()
|
||
(interactive)
|
||
(let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
|
||
(<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#'</span>persp-switch)
|
||
(persp-set-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
|
||
(switch-to-buffer buffer)))
|
||
</code></pre></div><p>Copy the current buffer to a perspective and switch to it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/persp-copy-window-and-switch ()
|
||
(interactive)
|
||
(let* ((buffer (<span style="color:#a6e22e">current-buffer</span>)))
|
||
(<span style="color:#a6e22e">call-interactively</span> <span style="color:#a6e22e">#'</span>persp-switch)
|
||
(persp-add-buffer (<span style="color:#a6e22e">buffer-name</span> buffer))
|
||
(switch-to-buffer buffer)))
|
||
</code></pre></div><p>Add keybindings to the default map.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'perspective</span>
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'perspective-map</span>
|
||
<span style="color:#e6db74">"m"</span> <span style="color:#a6e22e">#'</span>my/persp-move-window-and-switch
|
||
<span style="color:#e6db74">"f"</span> <span style="color:#a6e22e">#'</span>my/persp-copy-window-and-switch))
|
||
</code></pre></div><h3 id="off--tab-bar"><span class="org-todo done OFF">OFF</span> (OFF) Tab bar</h3>
|
||
<p><del>I rely rather heavily on tab-bar in my workflow. I have a suspicion I’m not using it the intended way, but that works for me.</del></p>
|
||
<p>For now switched to perspective.el, so the following block is not tangled.</p>
|
||
<h4 id="setup">Setup</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-define-key
|
||
:keymaps <span style="color:#e6db74">'override</span>
|
||
:states <span style="color:#f92672">'</span>(normal emacs)
|
||
<span style="color:#e6db74">"gt"</span> <span style="color:#e6db74">'tab-bar-switch-to-next-tab</span>
|
||
<span style="color:#e6db74">"gT"</span> <span style="color:#e6db74">'tab-bar-switch-to-prev-tab</span>
|
||
<span style="color:#e6db74">"gn"</span> <span style="color:#e6db74">'tab-bar-new-tab</span>)
|
||
|
||
(setq tab-bar-show <span style="color:#ae81ff">1</span>)
|
||
(setq tab-bar-tab-hints <span style="color:#66d9ef">t</span>)
|
||
(setq tab-bar-tab-name-function <span style="color:#e6db74">'tab-bar-tab-name-current-with-count</span>)
|
||
|
||
<span style="color:#75715e">;; Tabs</span>
|
||
(general-nmap <span style="color:#e6db74">"gn"</span> <span style="color:#e6db74">'tab-new</span>)
|
||
(general-nmap <span style="color:#e6db74">"gN"</span> <span style="color:#e6db74">'tab-close</span>)
|
||
</code></pre></div><h4 id="my-title">My title</h4>
|
||
<p>Prepend tab name with the shortened projectile project title</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/project-title-separators <span style="color:#e6db74">"[-_ ]"</span>)
|
||
|
||
(setq my/project-names-override-alist
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">".password-store"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"pass"</span>)))
|
||
|
||
(defun my/shorten-project-name-elem (elem crop)
|
||
(if (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"^\\[.*\\]$"</span> elem)
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"["</span>
|
||
(my/shorten-project-name-elem (<span style="color:#a6e22e">substring</span> elem <span style="color:#ae81ff">1</span> (<span style="color:#a6e22e">-</span> (<span style="color:#a6e22e">length</span> elem) <span style="color:#ae81ff">1</span>)) crop)
|
||
<span style="color:#e6db74">"]"</span>)
|
||
(let* ((prefix (<span style="color:#a6e22e">car</span> (s-match my/project-title-separators elem)))
|
||
(rest
|
||
(<span style="color:#a6e22e">substring</span>
|
||
(if prefix
|
||
(<span style="color:#a6e22e">substring</span> elem (<span style="color:#a6e22e">length</span> prefix))
|
||
elem)
|
||
<span style="color:#ae81ff">0</span> (if crop <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">nil</span>))))
|
||
(<span style="color:#a6e22e">concat</span> prefix rest))))
|
||
|
||
(defun my/shorten-project-name (project-name)
|
||
(or
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> project-name my/project-names-override-alist))
|
||
(let ((elems (s-slice-at my/project-title-separators project-name)))
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">apply</span>
|
||
<span style="color:#a6e22e">#'concat</span>
|
||
(cl-mapcar (lambda (elem) (my/shorten-project-name-elem elem <span style="color:#66d9ef">t</span>)) (butlast elems)))
|
||
(my/shorten-project-name-elem (<span style="color:#a6e22e">car</span> (last elems)) <span style="color:#66d9ef">nil</span>)))))
|
||
|
||
(defun my/tab-bar-name-function ()
|
||
(let ((project-name (projectile-project-name)))
|
||
(if (string= <span style="color:#e6db74">"-"</span> project-name)
|
||
(tab-bar-tab-name-current-with-count)
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"["</span> (my/shorten-project-name project-name) <span style="color:#e6db74">"] "</span>
|
||
(replace-regexp-in-string <span style="color:#e6db74">"<.*>"</span> <span style="color:#e6db74">""</span> (tab-bar-tab-name-current-with-count))))))
|
||
|
||
(setq tab-bar-tab-name-function <span style="color:#a6e22e">#'</span>my/tab-bar-name-function)
|
||
</code></pre></div><h3 id="doom-modeline">Doom Modeline</h3>
|
||
<p>A modeline from Doom Emacs.</p>
|
||
<p>A big advantage of this package is that it just works out of the box and does not require much customization. For now I opted out of it in favour of spaceline because I want to have a more powerline-ish look.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/seagle0128/doom-modeline">Doom Modeline</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package doom-modeline
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
<span style="color:#75715e">;; :if (not (display-graphic-p))</span>
|
||
:init
|
||
(setq doom-modeline-env-enable-python <span style="color:#66d9ef">nil</span>)
|
||
(setq doom-modeline-env-enable-go <span style="color:#66d9ef">nil</span>)
|
||
(setq doom-modeline-buffer-encoding <span style="color:#e6db74">'nondefault</span>)
|
||
(setq doom-modeline-hud <span style="color:#66d9ef">t</span>)
|
||
:config
|
||
(doom-modeline-mode <span style="color:#ae81ff">1</span>)
|
||
(setq doom-modeline-minor-modes <span style="color:#66d9ef">nil</span>)
|
||
(setq doom-modeline-buffer-state-icon <span style="color:#66d9ef">nil</span>))
|
||
</code></pre></div><h3 id="off--spaceline"><span class="org-todo done OFF">OFF</span> (OFF) Spaceline</h3>
|
||
<p>A modeline from Spacemacs. It provides a different look than Doom modeline, but also needs to be tuned more.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package spaceline
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:disabled
|
||
:config
|
||
<<spaceline-conf>>)
|
||
</code></pre></div><h4 id="perspectives">Perspectives</h4>
|
||
<p>Definining a bunch of custom powerline segments. First, a list of perspectives.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/format-perspective-list ()
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"[%s]"</span>
|
||
(let ((curr (persp-current-name)))
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (name)
|
||
(if (<span style="color:#a6e22e">string-equal</span> name curr)
|
||
(<span style="color:#a6e22e">propertize</span>
|
||
name
|
||
<span style="color:#e6db74">'face</span>
|
||
<span style="color:#e6db74">'persp-selected-face</span>)
|
||
name))
|
||
(persp-names)
|
||
<span style="color:#e6db74">"|"</span>))))
|
||
|
||
(defvar my/spaceline-persp-list <span style="color:#e6db74">""</span>)
|
||
|
||
(defun my/persp-update-advice (<span style="color:#66d9ef">&rest</span> _)
|
||
(setq my/spaceline-persp-list (my/format-perspective-list)))
|
||
|
||
(advice-add <span style="color:#a6e22e">#'</span>persp-update-modestring :after <span style="color:#a6e22e">#'</span>my/persp-update-advice)
|
||
(add-hook <span style="color:#e6db74">'buffer-list-update-hook</span> <span style="color:#a6e22e">#'</span>my/persp-update-advice)
|
||
(add-hook <span style="color:#e6db74">'find-file-hook</span> <span style="color:#a6e22e">#'</span>my/persp-update-advice)
|
||
|
||
(spaceline-define-segment perspective
|
||
<span style="color:#e6db74">"Perspective.el"</span>
|
||
my/spaceline-persp-list)
|
||
</code></pre></div><h4 id="exwm-workspace">EXWM workspace</h4>
|
||
<p>Current EXWM workspace. The variable is being set in the EXWM config, the segment just displays 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">(defvar my/exwm-mode-line-info-no-props <span style="color:#e6db74">""</span>)
|
||
|
||
(spaceline-define-segment exwm
|
||
my/exwm-mode-line-info-no-props)
|
||
</code></pre></div><h4 id="debug">Debug</h4>
|
||
<p>Indicators for <code>debug-on-error</code> and <code>debug-on-quit</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">(spaceline-define-segment debug-on-error
|
||
(when debug-on-error
|
||
(<span style="color:#a6e22e">propertize</span>
|
||
<span style="color:#e6db74">""</span>
|
||
<span style="color:#e6db74">'face</span> <span style="color:#e6db74">'warning</span>
|
||
<span style="color:#e6db74">'local-map</span> (let ((map (<span style="color:#a6e22e">make-sparse-keymap</span>)))
|
||
(<span style="color:#a6e22e">define-key</span> map
|
||
[mode-line mouse-1]
|
||
<span style="color:#a6e22e">#'</span>toggle-debug-on-error)
|
||
map))))
|
||
|
||
(spaceline-define-segment debug-on-quit
|
||
(when debug-on-quit
|
||
(<span style="color:#a6e22e">propertize</span>
|
||
<span style="color:#e6db74">""</span>
|
||
<span style="color:#e6db74">'face</span> <span style="color:#e6db74">'error</span>
|
||
<span style="color:#e6db74">'local-map</span> (let ((map (<span style="color:#a6e22e">make-sparse-keymap</span>)))
|
||
(<span style="color:#a6e22e">define-key</span> map
|
||
[mode-line mouse-1]
|
||
<span style="color:#a6e22e">#'</span>toggle-debug-on-quit)
|
||
map))))
|
||
</code></pre></div><h4 id="my-theme">My theme</h4>
|
||
<p>And a custom spaceline config with segments I 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-emacs-lisp" data-lang="emacs-lisp">(require <span style="color:#e6db74">'spaceline-config</span>)
|
||
|
||
(spaceline-compile
|
||
<span style="color:#e6db74">"my"</span>
|
||
<span style="color:#f92672">'</span>((evil-state :priority <span style="color:#ae81ff">100</span> :face (spaceline-highlight-face-evil-state))
|
||
(buffer-modified :priority <span style="color:#ae81ff">50</span>)
|
||
(version-control :priority <span style="color:#ae81ff">25</span> :when active)
|
||
(buffer-id :priority <span style="color:#ae81ff">90</span>))
|
||
<span style="color:#f92672">'</span>(<span style="color:#75715e">;; (global)</span>
|
||
(exwm :when active)
|
||
(perspective :when active)
|
||
(flycheck-error :when active)
|
||
(flycheck-warning :when active)
|
||
(debug-on-error :when active)
|
||
(debug-on-quit :when active)
|
||
(major-mode :when active :priority <span style="color:#ae81ff">90</span>)
|
||
(selection-info :priority <span style="color:#ae81ff">95</span>)
|
||
(line-column :when active :priority <span style="color:#ae81ff">99</span>)
|
||
(hud :when active :priority <span style="color:#ae81ff">99</span>)))
|
||
|
||
(spaceline-ml-my)
|
||
|
||
(setq-default mode-line-format <span style="color:#f92672">'</span>(<span style="color:#e6db74">"%e"</span> (:eval (spaceline-ml-my))))
|
||
(setq mode-line-format <span style="color:#f92672">'</span>(<span style="color:#e6db74">"%e"</span> (:eval (spaceline-ml-my))))
|
||
</code></pre></div><h3 id="font-stuff">Font stuff</h3>
|
||
<h4 id="ligatures">Ligatures</h4>
|
||
<p>Ligature setup for the JetBrainsMono font.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ligature
|
||
:straight (:host github :repo <span style="color:#e6db74">"mickeynp/ligature.el"</span>)
|
||
:if (display-graphic-p)
|
||
:config
|
||
(ligature-set-ligatures
|
||
<span style="color:#f92672">'</span>(
|
||
typescript-mode
|
||
js2-mode
|
||
vue-mode
|
||
svelte-mode
|
||
scss-mode
|
||
php-mode
|
||
python-mode
|
||
js-mode
|
||
markdown-mode
|
||
clojure-mode
|
||
go-mode
|
||
sh-mode
|
||
haskell-mode
|
||
web-mode)
|
||
<span style="color:#f92672">'</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 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 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 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 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 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 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 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 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 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 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 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 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 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>))
|
||
(global-ligature-mode <span style="color:#66d9ef">t</span>))
|
||
</code></pre></div><h4 id="icons">Icons</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package all-the-icons
|
||
:if (display-graphic-p)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="highlight-todo">Highlight todo</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hl-todo
|
||
:hook (prog-mode <span style="color:#f92672">.</span> hl-todo-mode)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h3 id="text-highlight-improvements">Text highlight improvements</h3>
|
||
<p>Highlight indent guides.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package highlight-indent-guides
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not (or my/lowpower my/remote-server))
|
||
:hook (
|
||
(prog-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
|
||
(vue-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode)
|
||
(LaTeX-mode <span style="color:#f92672">.</span> highlight-indent-guides-mode))
|
||
:config
|
||
(setq highlight-indent-guides-method <span style="color:#e6db74">'bitmap</span>)
|
||
(setq highlight-indent-guides-bitmap-function <span style="color:#e6db74">'highlight-indent-guides--bitmap-line</span>))
|
||
</code></pre></div><p>Rainbow parentheses.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package rainbow-delimiters
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/lowpower)
|
||
:hook ((prog-mode <span style="color:#f92672">.</span> rainbow-delimiters-mode))
|
||
<span style="color:#75715e">;; :commands (rainbow-delimiters-mode)</span>
|
||
<span style="color:#75715e">;; :init</span>
|
||
<span style="color:#75715e">;; (add-hook 'prog-mode-hook</span>
|
||
<span style="color:#75715e">;; (lambda ()</span>
|
||
<span style="color:#75715e">;; (unless (org-in-src-block-p)</span>
|
||
<span style="color:#75715e">;; (rainbow-delimiters-mode))))</span>
|
||
)
|
||
</code></pre></div><p>Highlight colors</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package rainbow-mode
|
||
:commands (rainbow-mode)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h2 id="dired">Dired</h2>
|
||
<p>Dired is a built-in file manager. I use it as my primary file manager, hence the top level of config.</p>
|
||
<h3 id="basic-config-and-keybindings">Basic config & keybindings</h3>
|
||
<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">(use-package dired
|
||
:ensure <span style="color:#66d9ef">nil</span>
|
||
:custom ((dired-listing-switches <span style="color:#e6db74">"-alh --group-directories-first"</span>))
|
||
:commands (dired)
|
||
:config
|
||
(setq dired-dwim-target <span style="color:#66d9ef">t</span>)
|
||
(setq wdired-allow-to-change-permissions <span style="color:#66d9ef">t</span>)
|
||
(setq wdired-create-parent-directories <span style="color:#66d9ef">t</span>)
|
||
(setq dired-recursive-copies <span style="color:#e6db74">'always</span>)
|
||
(setq dired-recursive-deletes <span style="color:#e6db74">'always</span>)
|
||
(setq dired-kill-when-opening-new-dired-buffer <span style="color:#66d9ef">t</span>)
|
||
(add-hook <span style="color:#e6db74">'dired-mode-hook</span>
|
||
(lambda ()
|
||
(setq truncate-lines <span style="color:#66d9ef">t</span>)
|
||
(visual-line-mode <span style="color:#66d9ef">nil</span>)))
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'dired-mode-map</span>
|
||
<span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'dired-up-directory</span>
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'dired-find-file</span>
|
||
<span style="color:#e6db74">"="</span> <span style="color:#e6db74">'dired-narrow</span>
|
||
<span style="color:#e6db74">"-"</span> <span style="color:#e6db74">'dired-create-empty-file</span>
|
||
<span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'vterm</span>
|
||
<span style="color:#e6db74">"<left>"</span> <span style="color:#e6db74">'dired-up-directory</span>
|
||
<span style="color:#e6db74">"<right>"</span> <span style="color:#e6db74">'dired-find-file</span>
|
||
<span style="color:#e6db74">"M-<return>"</span> <span style="color:#e6db74">'dired-open-xdg</span>))
|
||
|
||
(defun my/dired-home ()
|
||
<span style="color:#e6db74">"Open dired at $HOME"</span>
|
||
(interactive)
|
||
(dired (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~"</span>)))
|
||
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"ad"</span> <span style="color:#a6e22e">#'</span>dired
|
||
<span style="color:#e6db74">"aD"</span> <span style="color:#a6e22e">#'</span>my/dired-home)
|
||
</code></pre></div><h3 id="addons">Addons</h3>
|
||
<p>I used to use <a href="https://www.emacswiki.org/emacs/DiredPlus">dired+</a>, which provides a lot of extensions for dired functionality, but it also creates some new problems, so I opt out of it. Fortunately, the one feature I want from this package - adding more colors to dired buffers - is available as a separate package.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package diredfl
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after dired
|
||
:config
|
||
(diredfl-global-mode <span style="color:#ae81ff">1</span>))
|
||
</code></pre></div><p><del>Reuse the current dired buffer instead of spamming new ones.</del> Looks like not neccesary with Emacs 28.1</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-single
|
||
:after dired
|
||
:disabled
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><p>Display icons for files.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Note</th>
|
||
<th>Type</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>ACHTUNG</strong></td>
|
||
<td>This plugin is slow as hell with TRAMP or in <code>gnu/store</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package all-the-icons-dired
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not (or my/lowpower my/slow-ssh (not (display-graphic-p))))
|
||
:hook (dired-mode <span style="color:#f92672">.</span> (lambda ()
|
||
(unless (string-match-p <span style="color:#e6db74">"/gnu/store"</span> default-directory)
|
||
(all-the-icons-dired-mode))))
|
||
:config
|
||
(advice-add <span style="color:#e6db74">'dired-add-entry</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice)
|
||
(advice-add <span style="color:#e6db74">'dired-remove-entry</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice)
|
||
(advice-add <span style="color:#e6db74">'dired-kill-subdir</span> :around <span style="color:#a6e22e">#'</span>all-the-icons-dired--refresh-advice))
|
||
</code></pre></div><p>Provides stuff like <code>dired-open-xdg</code></p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-open
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (dired-open-xdg))
|
||
</code></pre></div><p>vifm-like filter</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dired-narrow
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (dired-narrow)
|
||
:config
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'dired-narrow-map</span>
|
||
[escape] <span style="color:#e6db74">'keyboard-quit</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">(use-package dired-git-info
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after dired
|
||
:if (not my/slow-ssh)
|
||
:config
|
||
(general-define-key
|
||
:keymap <span style="color:#e6db74">'dired-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(normal emacs)
|
||
<span style="color:#e6db74">")"</span> <span style="color:#e6db74">'dired-git-info-mode</span>))
|
||
</code></pre></div><h3 id="subdirectories">Subdirectories</h3>
|
||
<p>Subdirectories are one of the interesting features of Dired. It allows displaying multiple folders on the same window.</p>
|
||
<p>I add my own keybindings and some extra functionality.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dired-open-this-subdir ()
|
||
(interactive)
|
||
(dired (dired-current-directory)))
|
||
|
||
(defun my/dired-kill-all-subdirs ()
|
||
(interactive)
|
||
(let ((dir dired-directory))
|
||
(<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
|
||
(dired dir)))
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'dired</span>
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'dired-mode-map</span>
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#66d9ef">nil</span>
|
||
<span style="color:#e6db74">"ss"</span> <span style="color:#e6db74">'dired-maybe-insert-subdir</span>
|
||
<span style="color:#e6db74">"sl"</span> <span style="color:#e6db74">'dired-maybe-insert-subdir</span>
|
||
<span style="color:#e6db74">"sq"</span> <span style="color:#e6db74">'dired-kill-subdir</span>
|
||
<span style="color:#e6db74">"sk"</span> <span style="color:#e6db74">'dired-prev-subdir</span>
|
||
<span style="color:#e6db74">"sj"</span> <span style="color:#e6db74">'dired-next-subdir</span>
|
||
<span style="color:#e6db74">"sS"</span> <span style="color:#e6db74">'my/dired-open-this-subdir</span>
|
||
<span style="color:#e6db74">"sQ"</span> <span style="color:#e6db74">'my/dired-kill-all-subdirs</span>
|
||
(kbd <span style="color:#e6db74">"TAB"</span>) <span style="color:#e6db74">'dired-hide-subdir</span>))
|
||
</code></pre></div><h3 id="tramp">TRAMP</h3>
|
||
<p>TRAMP is a package that provides remote editing capacities. It is particularly useful for remote server management.</p>
|
||
<p>One of the reasons why TRAMP may be slow is that some plugins do too many requests to the filesystem. To debug these issues, set the following variable to 6:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq tramp-verbose <span style="color:#ae81ff">1</span>)
|
||
</code></pre></div><p>To check if a file is remote, you can use <code>file-remote-p</code>. E.g. <code>(file-remote-p default-directory)</code> for a current buffer. The problem with this approach is that it’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">(setq remote-file-name-inhibit-cache <span style="color:#66d9ef">nil</span>)
|
||
(setq vc-ignore-dir-regexp
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"\\(%s\\)\\|\\(%s\\)"</span>
|
||
vc-ignore-dir-regexp
|
||
tramp-file-name-regexp))
|
||
</code></pre></div><p>Set the default shell to <code>bin/bash</code> for TRAMP or on a remote server.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(when (or my/remote-server my/slow-ssh)
|
||
(setq explicit-shell-file-name <span style="color:#e6db74">"/bin/bash"</span>))
|
||
</code></pre></div><p>Also, here is a hack to make TRAMP find <code>ls</code> on Guix:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'tramp</span>
|
||
(setq tramp-remote-path
|
||
(<span style="color:#a6e22e">append</span> tramp-remote-path
|
||
<span style="color:#f92672">'</span>(tramp-own-remote-path))))
|
||
</code></pre></div><h3 id="bookmarks">Bookmarks</h3>
|
||
<p>A simple bookmark list for Dired, mainly to use with TRAMP. I may look into a proper bookmarking system later.</p>
|
||
<p>Bookmarks are listed in the <a href=".emacs.d/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">(setq my/dired-bookmarks
|
||
'(("sudo" . "/sudo::/")))
|
||
</code></pre></div><p>The file itself is encrypted with yadm.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/dired-bookmark-open ()
|
||
(interactive)
|
||
(let ((bookmarks
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%-30s %s"</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
|
||
my/dired-bookmarks)))
|
||
(dired
|
||
(<span style="color:#a6e22e">cdr</span>
|
||
(<span style="color:#a6e22e">assoc</span>
|
||
(<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Dired: "</span> bookmarks <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"^"</span>)
|
||
bookmarks)))))
|
||
</code></pre></div><h2 id="shells">Shells</h2>
|
||
<h3 id="vterm">vterm</h3>
|
||
<p>My terminal emulator of choice.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/akermu/emacs-libvterm">emacs-libvterm repo</a></li>
|
||
</ul>
|
||
<h4 id="configuration">Configuration</h4>
|
||
<p>I use the package from the Guix repository to avoid building libvterm.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package vterm
|
||
<span style="color:#75715e">;; :straight t</span>
|
||
:commands (vterm vterm-other-window)
|
||
:config
|
||
(setq vterm-kill-buffer-on-exit <span style="color:#66d9ef">t</span>)
|
||
|
||
(add-hook <span style="color:#e6db74">'vterm-mode-hook</span>
|
||
(lambda ()
|
||
(setq-local global-display-line-numbers-mode <span style="color:#66d9ef">nil</span>)
|
||
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
|
||
|
||
|
||
(advice-add <span style="color:#e6db74">'evil-collection-vterm-insert</span>
|
||
:before (lambda (<span style="color:#66d9ef">&rest</span> args)
|
||
(ignore-errors
|
||
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'</span>vterm-reset-cursor-point args))))
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
<span style="color:#e6db74">"M-q"</span> <span style="color:#e6db74">'vterm-send-escape</span>
|
||
|
||
<span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
<span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
<span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
<span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
|
||
<span style="color:#e6db74">"C-<right>"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
<span style="color:#e6db74">"C-<left>"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
<span style="color:#e6db74">"C-<up>"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
<span style="color:#e6db74">"C-<down>"</span> <span style="color:#e6db74">'evil-window-down</span>
|
||
|
||
<span style="color:#e6db74">"M-<left>"</span> <span style="color:#e6db74">'vterm-send-left</span>
|
||
<span style="color:#e6db74">"M-<right>"</span> <span style="color:#e6db74">'vterm-send-right</span>
|
||
<span style="color:#e6db74">"M-<up>"</span> <span style="color:#e6db74">'vterm-send-up</span>
|
||
<span style="color:#e6db74">"M-<down>"</span> <span style="color:#e6db74">'vterm-send-down</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(normal <span style="color:#a6e22e">insert</span>)
|
||
<span style="color:#e6db74">"<home>"</span> <span style="color:#e6db74">'vterm-beginning-of-line</span>
|
||
<span style="color:#e6db74">"<end>"</span> <span style="color:#e6db74">'vterm-end-of-line</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(<span style="color:#a6e22e">insert</span>)
|
||
<span style="color:#e6db74">"C-r"</span> <span style="color:#e6db74">'vterm-send-C-r</span>
|
||
<span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'vterm-send-C-k</span>
|
||
<span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'vterm-send-C-j</span>
|
||
<span style="color:#e6db74">"M-l"</span> <span style="color:#e6db74">'vterm-send-right</span>
|
||
<span style="color:#e6db74">"M-h"</span> <span style="color:#e6db74">'vterm-send-left</span>
|
||
<span style="color:#e6db74">"M-k"</span> <span style="color:#e6db74">'vterm-send-up</span>
|
||
<span style="color:#e6db74">"M-j"</span> <span style="color:#e6db74">'vterm-send-down</span>))
|
||
</code></pre></div><h4 id="subterminal">Subterminal</h4>
|
||
<p>Open a terminal in the lower third of the frame with the <code>`</code> key.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-to-list <span style="color:#e6db74">'display-buffer-alist</span>
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span><span style="color:#e6db74">"vterm-subterminal.*"</span>
|
||
(display-buffer-reuse-window
|
||
display-buffer-in-side-window)
|
||
(side <span style="color:#f92672">.</span> bottom)
|
||
(reusable-frames <span style="color:#f92672">.</span> visible)
|
||
(window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>)))
|
||
|
||
(defun my/toggle-vterm-subteminal ()
|
||
<span style="color:#e6db74">"Toogle subteminal."</span>
|
||
(interactive)
|
||
(let
|
||
((vterm-window
|
||
(seq-find
|
||
(lambda (window)
|
||
(<span style="color:#a6e22e">string-match</span>
|
||
<span style="color:#e6db74">"vterm-subterminal.*"</span>
|
||
(<span style="color:#a6e22e">buffer-name</span> (<span style="color:#a6e22e">window-buffer</span> window))))
|
||
(<span style="color:#a6e22e">window-list</span>))))
|
||
(if vterm-window
|
||
(if (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">get-buffer-window</span> (<span style="color:#a6e22e">current-buffer</span>)) vterm-window)
|
||
(<span style="color:#a6e22e">kill-buffer</span> (<span style="color:#a6e22e">current-buffer</span>))
|
||
(<span style="color:#a6e22e">select-window</span> vterm-window))
|
||
(vterm-other-window <span style="color:#e6db74">"vterm-subterminal"</span>))))
|
||
|
||
(unless my/slow-ssh
|
||
(general-nmap <span style="color:#e6db74">"`"</span> <span style="color:#e6db74">'my/toggle-vterm-subteminal</span>)
|
||
(general-nmap <span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'vterm</span>))
|
||
</code></pre></div><h4 id="dired-integration">Dired integration</h4>
|
||
<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">(defun my/vterm-get-pwd ()
|
||
(if vterm--process
|
||
(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)))
|
||
default-directory))
|
||
</code></pre></div><p>Now we can open dired for vterm pwd:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/vterm-dired-other-window ()
|
||
<span style="color:#e6db74">"Open dired in vterm pwd in other window"</span>
|
||
(interactive)
|
||
(dired-other-window (my/vterm-get-pwd)))
|
||
|
||
(defun my/vterm-dired-replace ()
|
||
<span style="color:#e6db74">"Replace vterm with dired"</span>
|
||
(interactive)
|
||
(let ((pwd (my/vterm-get-pwd)))
|
||
(<span style="color:#a6e22e">kill-process</span> vterm--process)
|
||
(dired pwd)))
|
||
</code></pre></div><p>The second function is particularly handy because that way I can alternate between vterm and dired.</p>
|
||
<p>Keybindings:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'vterm</span>
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'vterm-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
<span style="color:#e6db74">"gd"</span> <span style="color:#a6e22e">#'</span>my/vterm-dired-other-window
|
||
<span style="color:#e6db74">"gD"</span> <span style="color:#a6e22e">#'</span>my/vterm-dired-replace))
|
||
</code></pre></div><h4 id="with-editor-integration">With-editor integration</h4>
|
||
<p>A package used by Magit to use the current Emacs instance as the <code>$EDITOR</code>.</p>
|
||
<p>That is, with the help of <a href="/configs/console/">this function</a>, I can just write <code>e <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">(use-package with-editor
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (vterm)
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'vterm-mode-hook</span> <span style="color:#e6db74">'with-editor-export-editor</span>))
|
||
</code></pre></div><h3 id="eshell">Eshell</h3>
|
||
<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">(defun my/configure-eshell ()
|
||
(add-hook <span style="color:#e6db74">'eshell-pre-command-hook</span> <span style="color:#e6db74">'eshell-save-some-history</span>)
|
||
(add-to-list <span style="color:#e6db74">'eshell-output-filter-functions</span> <span style="color:#e6db74">'eshell-truncate-buffer</span>)
|
||
(setq eshell-history-size <span style="color:#ae81ff">10000</span>)
|
||
(setq eshell-hist-ingnoredups <span style="color:#66d9ef">t</span>)
|
||
(setq eshell-buffer-maximum-lines <span style="color:#ae81ff">10000</span>)
|
||
|
||
(evil-define-key <span style="color:#f92672">'</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>)
|
||
(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>)
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'eshell-mode-map</span>
|
||
(kbd <span style="color:#e6db74">"C-h"</span>) <span style="color:#e6db74">'evil-window-left</span>
|
||
(kbd <span style="color:#e6db74">"C-l"</span>) <span style="color:#e6db74">'evil-window-right</span>
|
||
(kbd <span style="color:#e6db74">"C-k"</span>) <span style="color:#e6db74">'evil-window-up</span>
|
||
(kbd <span style="color:#e6db74">"C-j"</span>) <span style="color:#e6db74">'evil-window-down</span>))
|
||
|
||
(use-package eshell
|
||
:ensure <span style="color:#66d9ef">nil</span>
|
||
:after evil-collection
|
||
:commands (eshell)
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'eshell-first-time-mode-hook</span> <span style="color:#e6db74">'my/configure-eshell</span> <span style="color:#ae81ff">90</span>)
|
||
(when my/slow-ssh
|
||
(add-hook <span style="color:#e6db74">'eshell-mode-hook</span>
|
||
(lambda ()
|
||
(setq-local company-idle-delay <span style="color:#ae81ff">1000</span>))))
|
||
(setq eshell-banner-message <span style="color:#e6db74">""</span>))
|
||
|
||
(use-package aweshell
|
||
:straight (:repo <span style="color:#e6db74">"manateelazycat/aweshell"</span> :host github)
|
||
:after eshell
|
||
:config
|
||
(setq eshell-highlight-prompt <span style="color:#66d9ef">nil</span>)
|
||
(setq eshell-prompt-function <span style="color:#e6db74">'epe-theme-pipeline</span>))
|
||
|
||
(use-package eshell-info-banner
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:if (not my/slow-ssh)
|
||
:straight (eshell-info-banner :type git
|
||
:host github
|
||
:repo <span style="color:#e6db74">"phundrak/eshell-info-banner.el"</span>)
|
||
:hook (eshell-banner-load <span style="color:#f92672">.</span> eshell-info-banner-update-banner))
|
||
|
||
(when my/slow-ssh
|
||
(general-nmap <span style="color:#e6db74">"`"</span> <span style="color:#e6db74">'aweshell-dedicated-toggle</span>)
|
||
(general-nmap <span style="color:#e6db74">"~"</span> <span style="color:#e6db74">'eshell</span>))
|
||
</code></pre></div><h2 id="org-mode">Org Mode</h2>
|
||
<p>The best feature of Emacs. Just after every other best feature of Emacs, probably.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://orgmode.org/">Org Mode homepage</a></li>
|
||
<li><a href="https://orgmode.org/manual/">Manual</a></li>
|
||
</ul>
|
||
<h3 id="installation-and-basic-settings">Installation & basic settings</h3>
|
||
<p>Use the built-in org mode.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/remote-server)
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:init
|
||
(setq org-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Documents/org-mode"</span>))
|
||
:config
|
||
(setq org-startup-indented <span style="color:#66d9ef">t</span>)
|
||
(setq org-return-follows-link <span style="color:#66d9ef">t</span>)
|
||
(setq org-src-tab-acts-natively <span style="color:#66d9ef">nil</span>)
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
(add-hook <span style="color:#e6db74">'org-agenda-mode-hook</span>
|
||
(lambda ()
|
||
(visual-line-mode <span style="color:#ae81ff">-1</span>)
|
||
(toggle-truncate-lines <span style="color:#ae81ff">1</span>)
|
||
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)))
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
(lambda ()
|
||
(rainbow-delimiters-mode <span style="color:#ae81ff">-1</span>)))
|
||
(require <span style="color:#e6db74">'org-tempo</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>))
|
||
(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>))
|
||
(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>))
|
||
<<org-crypt-setup>>
|
||
(unless my/is-termux
|
||
<<org-lang-setup>>)
|
||
<<org-ui-setup>>
|
||
<<org-keys-setup>>
|
||
<<org-productivity-setup>>)
|
||
</code></pre></div><h4 id="encryption">Encryption</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(require <span style="color:#e6db74">'org-crypt</span>)
|
||
(org-crypt-use-before-save-magic)
|
||
(setq org-tags-exclude-from-inheritance (quote (<span style="color:#e6db74">"crypt"</span>)))
|
||
(setq org-crypt-key <span style="color:#e6db74">"C1EC867E478472439CC82410DE004F32AFA00205"</span>)
|
||
</code></pre></div><h4 id="org-contrib">org-contrib</h4>
|
||
<p><code>org-contrib</code> is a package with various additions to Org. I use the following:</p>
|
||
<ul>
|
||
<li><code>ox-extra</code> - extensions for org export</li>
|
||
<li><code>ol-notmuch</code> - integration with notmuch</li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-contrib
|
||
:straight (org-contrib
|
||
:type git
|
||
:host <span style="color:#66d9ef">nil</span>
|
||
:repo <span style="color:#e6db74">"https://git.sr.ht/~bzg/org-contrib"</span>
|
||
:build <span style="color:#66d9ef">t</span>)
|
||
:after (org)
|
||
:config
|
||
(require <span style="color:#e6db74">'ox-extra</span>)
|
||
(require <span style="color:#e6db74">'ol-notmuch</span>)
|
||
(ox-extras-activate <span style="color:#f92672">'</span>(latex-header-blocks ignore-headlines)))
|
||
</code></pre></div><h3 id="integration-with-evil">Integration with evil</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package evil-org
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:hook (org-mode <span style="color:#f92672">.</span> evil-org-mode)
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'evil-org-mode-hook</span>
|
||
(lambda ()
|
||
(evil-org-set-key-theme <span style="color:#f92672">'</span>(navigation <span style="color:#a6e22e">insert</span> textobjects additional calendar todo))))
|
||
(add-to-list <span style="color:#e6db74">'evil-emacs-state-modes</span> <span style="color:#e6db74">'org-agenda-mode</span>)
|
||
(require <span style="color:#e6db74">'evil-org-agenda</span>)
|
||
(evil-org-agenda-set-keys))
|
||
</code></pre></div><h3 id="literate-programing">Literate programing</h3>
|
||
<h4 id="python-and-jupyter">Python & Jupyter</h4>
|
||
<p>Use jupyter kernels for Org Mode.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/nnicandro/emacs-jupyter">emacs-jupyter repo</a></li>
|
||
<li><a href="https://github.com/jkitchin/scimax/blob/master/scimax.org">SCIMAX manual</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package jupyter
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/is-termux)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ar"</span> <span style="color:#e6db74">'jupyter-run-repl</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">(defun my/jupyter-refresh-kernelspecs ()
|
||
<span style="color:#e6db74">"Refresh Jupyter kernelspecs"</span>
|
||
(interactive)
|
||
(jupyter-available-kernelspecs <span style="color:#66d9ef">t</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">(defun my/jupyter-refesh-langs ()
|
||
<span style="color:#e6db74">"Refresh Jupyter languages"</span>
|
||
(interactive)
|
||
(org-babel-jupyter-aliases-from-kernelspecs <span style="color:#66d9ef">t</span>))
|
||
</code></pre></div><h4 id="hy">Hy</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ob-hy
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="view-html-in-browser">View HTML in browser</h4>
|
||
<p>Open HTML in the <code>begin_export</code> block with xdg-open.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-view-html-tmp-dir <span style="color:#e6db74">"/tmp/org-html-preview/"</span>)
|
||
|
||
(use-package f
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(defun my/org-view-html ()
|
||
(interactive)
|
||
(let ((elem (org-element-at-point))
|
||
(temp-file-path (<span style="color:#a6e22e">concat</span> my/org-view-html-tmp-dir (<span style="color:#a6e22e">number-to-string</span> (<span style="color:#a6e22e">random</span> (<span style="color:#a6e22e">expt</span> <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">32</span>))) <span style="color:#e6db74">".html"</span>)))
|
||
(cond
|
||
((not (<span style="color:#a6e22e">eq</span> <span style="color:#e6db74">'export-block</span> (<span style="color:#a6e22e">car</span> elem)))
|
||
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Not in an export block!"</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 style="color:#a6e22e">message</span> <span style="color:#e6db74">"Export block is not HTML!"</span>))
|
||
(<span style="color:#66d9ef">t</span> (progn
|
||
(f-mkdir my/org-view-html-tmp-dir)
|
||
(f-write (<span style="color:#a6e22e">plist-get</span> (<span style="color:#a6e22e">car</span> (<span style="color:#a6e22e">cdr</span> elem)) :value) <span style="color:#e6db74">'utf-8</span> temp-file-path)
|
||
(<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))))))
|
||
</code></pre></div><h4 id="plantuml">PlantUML</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-plantuml-executable-path <span style="color:#e6db74">"/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml"</span>)
|
||
(setq org-plantuml-exec-mode <span style="color:#e6db74">'plantuml</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))
|
||
</code></pre></div><h4 id="setup">Setup</h4>
|
||
<p>Enable languages</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(org-babel-do-load-languages
|
||
<span style="color:#e6db74">'org-babel-load-languages</span>
|
||
<span style="color:#f92672">'</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(python <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(sql <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
<span style="color:#75715e">;; (typescript .t)</span>
|
||
(hy <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(plantuml <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(octave <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(jupyter <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
|
||
|
||
(add-hook <span style="color:#e6db74">'org-babel-after-execute-hook</span> <span style="color:#e6db74">'org-redisplay-inline-images</span>)
|
||
</code></pre></div><p>Use Jupyter block instead of built-in Python.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(org-babel-jupyter-override-src-block <span style="color:#e6db74">"python"</span>)
|
||
(org-babel-jupyter-override-src-block <span style="color:#e6db74">"hy"</span>)
|
||
</code></pre></div><p>Turn of some minor modes in source blocks.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'org-src-mode-hook</span>
|
||
(lambda ()
|
||
<span style="color:#75715e">;; (hs-minor-mode -1)</span>
|
||
<span style="color:#75715e">;; (electric-indent-local-mode -1)</span>
|
||
<span style="color:#75715e">;; (rainbow-delimiters-mode -1)</span>
|
||
(highlight-indent-guides-mode <span style="color:#ae81ff">-1</span>)))
|
||
</code></pre></div><p>Async code blocks evaluations. Jupyter blocks have a built-in async, so they are set as ignored.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ob-async
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (org)
|
||
:config
|
||
(setq ob-async-no-async-languages-alist <span style="color:#f92672">'</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>)))
|
||
</code></pre></div><h4 id="managing-jupyter-kernels">Managing Jupyter kernels</h4>
|
||
<p>Functions for managing local Jupyter kernels.</p>
|
||
<p><code>my/insert-jupyter-kernel</code> inserts a path to an active Jupyter kernel to the buffer. Useful to quickly write a header like:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">#+PROPERTY: header-args:python :session <path-to-kernel>
|
||
</code></pre></div><p><code>my/jupyter-connect-repl</code> opens a <code>emacs-jupyter</code> REPL, connected to an active kernel. <code>my/jupyter-qtconsole</code> runs a standalone Jupyter QtConsole.</p>
|
||
<p>Requirements: <code>ss</code></p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/jupyter-runtime-folder (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/.local/share/jupyter/runtime"</span>))
|
||
|
||
(defun my/get-open-ports ()
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
<span style="color:#a6e22e">#'string-to-number</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>)))
|
||
|
||
(defun my/list-jupyter-kernel-files ()
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (file) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">car</span> file) (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assq</span> <span style="color:#e6db74">'shell_port</span> (json-read-file (<span style="color:#a6e22e">car</span> file))))))
|
||
(<span style="color:#a6e22e">sort</span>
|
||
(<span style="color:#a6e22e">directory-files-and-attributes</span> my/jupyter-runtime-folder <span style="color:#66d9ef">t</span> <span style="color:#e6db74">".*kernel.*json$"</span>)
|
||
(lambda (x y) (not (<span style="color:#a6e22e">time-less-p</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">6</span> x) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">6</span> y)))))))
|
||
|
||
(defun my/select-jupyter-kernel ()
|
||
(let ((ports (my/get-open-ports))
|
||
(files (my/list-jupyter-kernel-files)))
|
||
(<span style="color:#a6e22e">completing-read</span>
|
||
<span style="color:#e6db74">"Jupyter kernels: "</span>
|
||
(seq-filter
|
||
(lambda (file)
|
||
(<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports))
|
||
files))))
|
||
|
||
(defun my/insert-jupyter-kernel ()
|
||
<span style="color:#e6db74">"Insert a path to an active Jupyter kernel into the buffer"</span>
|
||
(interactive)
|
||
(<span style="color:#a6e22e">insert</span> (my/select-jupyter-kernel)))
|
||
|
||
(defun my/jupyter-connect-repl ()
|
||
<span style="color:#e6db74">"Open an emacs-jupyter REPL, connected to a Jupyter kernel"</span>
|
||
(interactive)
|
||
(jupyter-connect-repl (my/select-jupyter-kernel) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>))
|
||
|
||
(defun my/jupyter-qtconsole ()
|
||
<span style="color:#e6db74">"Open Jupyter QtConsole, connected to a Jupyter kernel"</span>
|
||
(interactive)
|
||
(<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 style="color:#a6e22e">file-name-nondirectory</span> (my/select-jupyter-kernel))))
|
||
</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">(defun my/jupyter-cleanup-kernels ()
|
||
(interactive)
|
||
(let* ((ports (my/get-open-ports))
|
||
(files (my/list-jupyter-kernel-files))
|
||
(to-delete (seq-filter
|
||
(lambda (file)
|
||
(not (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">cdr</span> file) ports)))
|
||
files)))
|
||
(when (and (length> to-delete <span style="color:#ae81ff">0</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))))
|
||
(dolist (file to-delete)
|
||
(<span style="color:#a6e22e">delete-file</span> (<span style="color:#a6e22e">car</span> file))))))
|
||
</code></pre></div><h4 id="do-not-wrap-the-output-in-emacs-jupyter">Do not wrap the output in emacs-jupyter</h4>
|
||
<p>Emacs-jupyter has its own insertion mechanisms, which always prepends output statements with <code>:</code>. That is not desirable in cases where a kernel supports only plain output, e.g. calysto_hy kernel.</p>
|
||
<p>So there we have a minor mode that overrides this behavior.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jupyter-org-scalar (value)
|
||
(cond
|
||
((<span style="color:#a6e22e">stringp</span> value) value)
|
||
(<span style="color:#66d9ef">t</span> (jupyter-org-scalar value))))
|
||
|
||
(define-minor-mode my/emacs-jupyter-raw-output
|
||
<span style="color:#e6db74">"Make emacs-jupyter do raw output"</span>)
|
||
|
||
(defun my/jupyter-org-scalar-around (fun value)
|
||
(if my/emacs-jupyter-raw-output
|
||
(my/jupyter-org-scalar value)
|
||
(<span style="color:#a6e22e">funcall</span> fun value)))
|
||
|
||
(advice-add <span style="color:#e6db74">'jupyter-org-scalar</span> :around <span style="color:#a6e22e">#'</span>my/jupyter-org-scalar-around)
|
||
</code></pre></div><h4 id="wrap-source-code-output">Wrap source code output</h4>
|
||
<p>A function to remove :RESULTS: drawer from the results. Once again, necessary because emacs-jupyter doesn’t seem to respect :results raw.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-strip-results (data)
|
||
(replace-regexp-in-string <span style="color:#e6db74">":\\(RESULTS\\|END\\):\n"</span> <span style="color:#e6db74">""</span> data))
|
||
</code></pre></div><p>And an all-in-one function to:</p>
|
||
<ul>
|
||
<li>prepend <code>#+NAME:</code> and <code>#+CAPTION:</code> to the source block output. Useful if the output is an image.</li>
|
||
<li>strip :RESULTS: drawer from the output, if necessary</li>
|
||
<li>wrap results in the <code>src</code> block</li>
|
||
</ul>
|
||
<p>As for now, looks sufficient to format source code outputs to get a tolerable LaTeX.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-caption-wrap (data <span style="color:#66d9ef">&optional</span> name caption attrs strip-drawer src-wrap)
|
||
(let* ((data-s (if (and strip-drawer (not (string-empty-p strip-drawer)))
|
||
(my/org-strip-results data)
|
||
data))
|
||
(drawer-start (if (string-match-p <span style="color:#e6db74">"^:RESULTS:.*"</span> data-s) <span style="color:#ae81ff">10</span> <span style="color:#ae81ff">0</span>)))
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">substring</span> data-s <span style="color:#ae81ff">0</span> drawer-start)
|
||
(and name (not (string-empty-p name)) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+NAME:"</span> name <span style="color:#e6db74">"\n"</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>))
|
||
(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>))
|
||
(if (and src-wrap (not (string-empty-p src-wrap)))
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"#+begin_src "</span> src-wrap <span style="color:#e6db74">"\n"</span>
|
||
(<span style="color:#a6e22e">substring</span> data-s drawer-start)
|
||
(when (not (string-match-p <span style="color:#e6db74">".*\n"</span> data-s)) <span style="color:#e6db74">"\n"</span>)
|
||
<span style="color:#e6db74">"#+end_src"</span>)
|
||
(<span style="color:#a6e22e">substring</span> data-s drawer-start)))))
|
||
</code></pre></div><p>To use, add the following snippet to the org file:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">#+NAME: out_wrap
|
||
#+begin_src emacs-lisp :var data="" caption="" name="" attrs="" strip-drawer="" src-wrap="" :tangle no :exports none
|
||
(my/org-caption-wrap data name caption attrs strip-drawer src-wrap)
|
||
#+end_src
|
||
</code></pre></div><p>Example usage:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">:post out_wrap(name="fig:chart", caption="График", data=*this*)
|
||
</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">#+PROPERTY: PRJ-DIR ..
|
||
</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">(defun my/org-prj-dir (path)
|
||
(<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>)))
|
||
</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">:tangle (my/org-prj-dir "sqrt_data/api/__init__.py")
|
||
</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%5Fmode%5Fworkflow%5Fpreview/">Jetro Kuan. Org-mode Workflow</a></li>
|
||
<li><a href="https://www.alexeyshmalko.com/how-i-note/">Alexey Shmalko: How I note</a></li>
|
||
<li><a href="https://rgoswami.me/posts/org-note-workflow/">Rohit Goswami: An Orgmode Note Workflow</a></li>
|
||
</ul>
|
||
<p>Used files</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-agenda-files <span style="color:#f92672">'</span>(<span style="color:#e6db74">"inbox.org"</span> <span style="color:#e6db74">"projects.org"</span> <span style="color:#e6db74">"work.org"</span> <span style="color:#e6db74">"sem-11.org"</span> <span style="color:#e6db74">"life.org"</span>))
|
||
<span style="color:#75715e">;; (setq org-default-notes-file (concat org-directory "/notes.org"))</span>
|
||
</code></pre></div><p>Hotkeys</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"o"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-mode"</span>)
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'org-capture</span>
|
||
<span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'org-agenda</span>)
|
||
</code></pre></div><p>Refile targets</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-refile-targets
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"projects.org"</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)
|
||
(<span style="color:#e6db74">"work.org"</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)
|
||
(<span style="color:#e6db74">"sem-11.org"</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">3</span>)
|
||
(<span style="color:#e6db74">"life.org"</span> :maxlevel <span style="color:#f92672">.</span> <span style="color:#ae81ff">2</span>)))
|
||
(setq org-refile-use-outline-path <span style="color:#e6db74">'file</span>)
|
||
(setq org-outline-path-complete-in-steps <span style="color:#66d9ef">nil</span>)
|
||
</code></pre></div><h4 id="capture-templates-and-various-settings">Capture templates & 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">(defun my/generate-inbox-note-name ()
|
||
(<span style="color:#a6e22e">format</span>
|
||
<span style="color:#e6db74">"%s/inbox-notes/%s.org"</span>
|
||
org-directory
|
||
(<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y%m%d%H%M%S"</span>)))
|
||
|
||
(setq org-capture-templates
|
||
<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 style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %?\n"</span>
|
||
<span style="color:#e6db74">"/Entered on/ %U"</span>))
|
||
(<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">"email"</span> entry (file <span style="color:#e6db74">"inbox.org"</span>)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %:from %:subject \n"</span>
|
||
<span style="color:#e6db74">"/Entered on/ %U\n"</span>
|
||
<span style="color:#e6db74">"/Received on/ %:date-timestamp-inactive\n"</span>
|
||
<span style="color:#e6db74">"%a\n"</span>))
|
||
(<span style="color:#e6db74">"f"</span> <span style="color:#e6db74">"elfeed"</span> entry (file <span style="color:#e6db74">"inbox.org"</span>)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* TODO %:elfeed-entry-title\n"</span>
|
||
<span style="color:#e6db74">"/Entered on/ %U\n"</span>
|
||
<span style="color:#e6db74">"%a\n"</span>))
|
||
(<span style="color:#e6db74">"n"</span> <span style="color:#e6db74">"note"</span> entry (file my/generate-inbox-note-name)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"* %?\n"</span>
|
||
<span style="color:#e6db74">"/Entered on/ %U"</span>))))
|
||
</code></pre></div><p>Effort estimation</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-to-list <span style="color:#e6db74">'org-global-properties</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>))
|
||
</code></pre></div><p>Log DONE time</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq org-log-done <span style="color:#e6db74">'time</span>)
|
||
</code></pre></div><h4 id="trello-sync">Trello sync</h4>
|
||
<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">(setq org-trello-files
|
||
(thread-last (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello"</span>)
|
||
(<span style="color:#a6e22e">directory-files</span>)
|
||
(seq-filter
|
||
(lambda (f) (string-match-p (rx <span style="color:#e6db74">".org"</span> eos) f)))
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (f) (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/trello/"</span> f)))))
|
||
</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">(use-package org-trello
|
||
:straight (:build (:not native-compile))
|
||
:commands (org-trello-mode)
|
||
:init
|
||
(setq org-trello-current-prefix-keybinding <span style="color:#e6db74">"C-c o"</span>)
|
||
(setq org-trello-add-tags <span style="color:#66d9ef">nil</span>)
|
||
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
(lambda ()
|
||
(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>))
|
||
(org-trello-mode))))
|
||
:config
|
||
(<span style="color:#a6e22e">eval</span>
|
||
<span style="color:#f92672">`</span>(my-leader-def
|
||
:infix <span style="color:#e6db74">"o t"</span>
|
||
:keymaps <span style="color:#f92672">'</span>(org-trello-mode-map)
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"trello"</span>)
|
||
<span style="color:#f92672">,@</span>(mapcan
|
||
(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))))
|
||
org-trello-interactive-command-binding-couples))))
|
||
</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">(use-package org-ql
|
||
:straight (:fetcher github
|
||
:repo <span style="color:#e6db74">"alphapapa/org-ql"</span>
|
||
:files (:defaults (:exclude <span style="color:#e6db74">"helm-org-ql.el"</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">(defun my/org-scheduled-get-time ()
|
||
(let ((scheduled (org-get-scheduled-time (<span style="color:#a6e22e">point</span>))))
|
||
(if scheduled
|
||
(<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y-%m-%d"</span> scheduled)
|
||
<span style="color:#e6db74">""</span>)))
|
||
|
||
(setq org-agenda-custom-commands
|
||
<span style="color:#f92672">`</span>((<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">"My outline"</span>
|
||
((agenda <span style="color:#e6db74">""</span>)
|
||
(todo <span style="color:#e6db74">"NEXT"</span>
|
||
((org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c [%e] "</span>)
|
||
(org-agenda-overriding-header <span style="color:#e6db74">"Next tasks"</span>)))
|
||
(org-ql-block
|
||
<span style="color:#f92672">`</span>(and
|
||
(regexp <span style="color:#f92672">,</span>(rx <span style="color:#e6db74">":orgtrello_users:"</span> (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">"sqrtminusone"</span>))
|
||
(todo)
|
||
(deadline))
|
||
((org-agenda-files <span style="color:#e6db74">',org-trello-files</span>)
|
||
(org-ql-block-header <span style="color:#e6db74">"Trello assigned"</span>)))
|
||
(tags-todo <span style="color:#e6db74">"inbox"</span>
|
||
((org-agenda-overriding-header <span style="color:#e6db74">"Inbox"</span>)
|
||
(org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c"</span>)
|
||
(org-agenda-hide-tags-regexp <span style="color:#e6db74">"."</span>)))
|
||
(tags-todo <span style="color:#e6db74">"+waitlist+SCHEDULED<=\"<+14d>\""</span>
|
||
((org-agenda-overriding-header <span style="color:#e6db74">"Waitlist"</span>)
|
||
(org-agenda-hide-tags-regexp <span style="color:#e6db74">"waitlist"</span>)
|
||
(org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c %-12(my/org-scheduled-get-time)"</span>)))))
|
||
(<span style="color:#e6db74">"tp"</span> <span style="color:#e6db74">"Personal tasks"</span>
|
||
((tags-todo <span style="color:#e6db74">"personal"</span>
|
||
((org-agenda-prefix-format <span style="color:#e6db74">" %i %-12:c [%e] "</span>)))))))
|
||
</code></pre></div><h4 id="review-workflow">Review workflow</h4>
|
||
<p>My take on a review workflow. As a baseline, I want to have a template that lists the important changes since the last review and other basic information. I’m doing reviews regularly, but the time intervals still may vary, hence this flexibility.</p>
|
||
<h5 id="data-from-git-and-org-roam">Data from git & org-roam</h5>
|
||
<p>First, as I have <a href="/configs/console/">autocommit</a> set up in my org directory, here is a handy function to get an alist of changed files of a form <code>(status . path)</code>. In principle, the <code>rev</code> parameter can be a commit, tag, etc but here I’m interested in a form like <code>@{2021-08-30}</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/git-diff-status
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"A"</span> <span style="color:#f92672">.</span> added)
|
||
(<span style="color:#e6db74">"C"</span> <span style="color:#f92672">.</span> copied)
|
||
(<span style="color:#e6db74">"D"</span> <span style="color:#f92672">.</span> deleted)
|
||
(<span style="color:#e6db74">"M"</span> <span style="color:#f92672">.</span> modified)
|
||
(<span style="color:#e6db74">"R"</span> <span style="color:#f92672">.</span> renamed)
|
||
(<span style="color:#e6db74">"T"</span> <span style="color:#f92672">.</span> type-changed)
|
||
(<span style="color:#e6db74">"U"</span> <span style="color:#f92672">.</span> unmerged)))
|
||
|
||
(defun my/get-files-status (rev)
|
||
(let ((files (shell-command-to-string (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"git diff --name-status "</span> rev))))
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (file)
|
||
(let ((elems (split-string file <span style="color:#e6db74">"\t"</span>)))
|
||
(<span style="color:#a6e22e">cons</span>
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> (<span style="color:#a6e22e">car</span> elems) my/git-diff-status))
|
||
(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elems))))
|
||
(split-string files <span style="color:#e6db74">"\n"</span> <span style="color:#66d9ef">t</span>))))
|
||
</code></pre></div><p>I’ll use it to get a list of added and changed Roam files since the last review. Date should have be in a format <code>YYYY-MM-DD</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-changed-files-since-date (date)
|
||
(let ((default-directory org-directory))
|
||
(my/get-files-status (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"@{%s}"</span> date))))
|
||
</code></pre></div><p>Now we are ready to format this list to insert it into the capture template.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-roam (rev)
|
||
(let* ((changes (my/org-changed-files-since-date rev))
|
||
(new-roam
|
||
(seq-filter
|
||
(lambda (elem)
|
||
(and (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">car</span> elem) <span style="color:#e6db74">'added</span>)
|
||
(string-match-p (rx bos <span style="color:#e6db74">"roam"</span>) (<span style="color:#a6e22e">cdr</span> elem))))
|
||
changes))
|
||
(changed-roam
|
||
(seq-filter
|
||
(lambda (elem)
|
||
(and (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">car</span> elem) <span style="color:#e6db74">'modified</span>)
|
||
(string-match-p (rx bos <span style="color:#e6db74">"roam"</span>) (<span style="color:#a6e22e">cdr</span> elem))))
|
||
changes)))
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(unless (seq-empty-p new-roam)
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"** New Roam entries \n"</span>
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (entry)
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"- [[file:%s][%s]]"</span> (<span style="color:#a6e22e">cdr</span> entry) (<span style="color:#a6e22e">cdr</span> entry)))
|
||
new-roam
|
||
<span style="color:#e6db74">"\n"</span>)
|
||
<span style="color:#e6db74">"\n"</span>))
|
||
(unless (seq-empty-p changed-roam)
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"** Changed Roam entries \n"</span>
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (entry)
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"- [[file:%s][%s]]"</span> (<span style="color:#a6e22e">cdr</span> entry) (<span style="color:#a6e22e">cdr</span> entry)))
|
||
changed-roam
|
||
<span style="color:#e6db74">"\n"</span>))))))
|
||
</code></pre></div><h5 id="data-from-org-journal">Data from org-journal</h5>
|
||
<p>Second, I want to have a list of new jounal entries since the last review.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-journal-entries-since-date (rev-date)
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (date)
|
||
(let ((time (<span style="color:#a6e22e">encode-time</span> (parse-time-string date))))
|
||
<span style="color:#f92672">`</span>((file <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(org-journal--get-entry-path time))
|
||
(header <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">format-time-string</span> org-journal-date-format time)))))
|
||
(seq-filter
|
||
(lambda (date) (<span style="color:#a6e22e">string-lessp</span> rev-date date))
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (date)
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%04d-%02d-%02dT00:00:00+0300"</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> date) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> date) (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> date)))
|
||
(org-journal--list-dates)))))
|
||
</code></pre></div><p>Format the results:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-journal (rev-date)
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (item)
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"- [[file:%s::*%s][%s]]"</span>
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'file</span> item))
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'header</span> item))
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'header</span> item))))
|
||
(my/org-journal-entries-since-date rev-date)
|
||
<span style="color:#e6db74">"\n"</span>))
|
||
</code></pre></div><h5 id="data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</h5>
|
||
<p>Third, I want to list some changes in my agenda. This section will change depending on what I’m currently working on.</p>
|
||
<p>So, here is a list of queries results of which I want to see in the review template. The format is <code>(name date-field order-by-field query)</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-ql-review-queries
|
||
<span style="color:#f92672">`</span>((<span style="color:#e6db74">"Waitlist"</span> scheduled scheduled
|
||
(and
|
||
(done)
|
||
(tags-inherited <span style="color:#e6db74">"waitlist"</span>)))
|
||
(<span style="color:#e6db74">"Personal tasks done"</span> closed <span style="color:#f92672">,</span><span style="color:#66d9ef">nil</span>
|
||
(and
|
||
(tags-inherited <span style="color:#e6db74">"personal"</span>)
|
||
(todo <span style="color:#e6db74">"DONE"</span>)))
|
||
(<span style="color:#e6db74">"Attended meetings"</span> closed scheduled
|
||
(and
|
||
(tags-inherited <span style="color:#e6db74">"meeting"</span>)
|
||
(todo <span style="color:#e6db74">"PASSED"</span>)))
|
||
(<span style="color:#e6db74">"Done project tasks"</span> closed deadline
|
||
(and
|
||
(todo <span style="color:#e6db74">"DONE"</span>)
|
||
(ancestors
|
||
(heading <span style="color:#e6db74">"Tasks"</span>))))))
|
||
</code></pre></div><p>The query will be executed like this: <code>(and (date-field :from rev-date) query)</code></p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-exec-ql (saved rev-date)
|
||
(let ((query <span style="color:#f92672">`</span>(and
|
||
(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> saved) :from <span style="color:#f92672">,</span>rev-date)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">3</span> saved))))
|
||
(org-ql-query
|
||
:select <span style="color:#a6e22e">#'</span>element
|
||
:from (org-agenda-files)
|
||
:where query
|
||
:order-by (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> saved))))
|
||
</code></pre></div><p>Format one element of query result.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-element (elem)
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(string-pad
|
||
(<span style="color:#a6e22e">plist-get</span> (cadr elem) :raw-value)
|
||
<span style="color:#ae81ff">40</span>)
|
||
(when-let (scheduled (<span style="color:#a6e22e">plist-get</span> (cadr elem) :scheduled))
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">" [SCHEDULED: "</span> (<span style="color:#a6e22e">plist-get</span> (cadr scheduled) :raw-value) <span style="color:#e6db74">"]"</span>))
|
||
(when-let (deadline (<span style="color:#a6e22e">plist-get</span> (cadr elem) :deadline))
|
||
(<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>))))
|
||
</code></pre></div><p>Execute all the saved queries and format an Org list for the capture template.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-review-format-queries (rev-date)
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (results)
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"** "</span> (<span style="color:#a6e22e">car</span> results) <span style="color:#e6db74">"\n"</span>
|
||
(string-join
|
||
(<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 style="color:#e6db74">"\n"</span>)
|
||
<span style="color:#e6db74">"\n"</span>))
|
||
(seq-filter
|
||
(lambda (result)
|
||
(not (seq-empty-p (<span style="color:#a6e22e">cdr</span> result))))
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (saved)
|
||
(<span style="color:#a6e22e">cons</span>
|
||
(<span style="color:#a6e22e">car</span> saved)
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
<span style="color:#a6e22e">#'</span>my/org-review-format-element
|
||
(my/org-review-exec-ql saved rev-date))))
|
||
my/org-ql-review-queries))
|
||
<span style="color:#e6db74">"\n"</span>))
|
||
</code></pre></div><h5 id="capture-template">Capture template</h5>
|
||
<p>Now, we have to put all this together and define a capture template for the review.</p>
|
||
<p>I’ll use a separate directory for the review files, just like for org-journal and org-roam. The filename will have a format <code>YYYY-MM-DD.org</code>, which will also free me from the effort of storing the last review date somewhere.</p>
|
||
<p>If somehow there are no files in the folder, fallback to the current date minus one week.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-review-directory <span style="color:#e6db74">"review"</span>)
|
||
|
||
(defun my/org-review-get-filename ()
|
||
(<span style="color:#a6e22e">concat</span> my/org-review-directory <span style="color:#e6db74">"/"</span> (<span style="color:#a6e22e">format-time-string</span> <span style="color:#e6db74">"%Y-%m-%d.org"</span> (<span style="color:#a6e22e">current-time</span>))))
|
||
|
||
(defun my/get-last-review-date ()
|
||
(<span style="color:#a6e22e">substring</span>
|
||
(or
|
||
(-max-by
|
||
<span style="color:#e6db74">'string-greaterp</span>
|
||
(-filter
|
||
(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 style="color:#a6e22e">directory-files</span> (f-join org-directory my/org-review-directory))))
|
||
(<span style="color:#a6e22e">format-time-string</span>
|
||
<span style="color:#e6db74">"%Y-%m-%d"</span>
|
||
(<span style="color:#a6e22e">time-subtract</span>
|
||
(<span style="color:#a6e22e">current-time</span>)
|
||
(seconds-to-time (<span style="color:#a6e22e">*</span> <span style="color:#ae81ff">60</span> <span style="color:#ae81ff">60</span> <span style="color:#ae81ff">24</span> <span style="color:#ae81ff">7</span>)))))
|
||
<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">10</span>))
|
||
</code></pre></div><p>A template looks like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-review-capture-template
|
||
<span style="color:#f92672">`</span>(<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">"Review"</span> plain (file <span style="color:#f92672">,</span>(my/org-review-get-filename))
|
||
<span style="color:#f92672">,</span>(string-join
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"#+TITLE: Review %t"</span>
|
||
<span style="color:#e6db74">""</span>
|
||
<span style="color:#e6db74">"Last review date: %(org-timestamp-translate (org-timestamp-from-string (format \"<%s>\" (my/get-last-review-date))))"</span>
|
||
<span style="color:#e6db74">""</span>
|
||
<span style="color:#e6db74">"* Roam"</span>
|
||
<span style="color:#e6db74">"%(my/org-review-format-roam (my/get-last-review-date))"</span>
|
||
<span style="color:#e6db74">"* Journal"</span>
|
||
<span style="color:#e6db74">"New journal entries:"</span>
|
||
<span style="color:#e6db74">"%(my/org-review-format-journal (my/get-last-review-date))"</span>
|
||
<span style="color:#e6db74">"* Agenda"</span>
|
||
<span style="color:#e6db74">"%(my/org-review-format-queries (my/get-last-review-date))"</span>
|
||
<span style="color:#e6db74">"* Thoughts :crypt:"</span>
|
||
<span style="color:#e6db74">"%?"</span>)
|
||
<span style="color:#e6db74">"\n"</span>)))
|
||
|
||
(add-to-list <span style="color:#e6db74">'org-capture-templates</span> my/org-review-capture-template <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="org-journal">Org Journal</h4>
|
||
<p><a href="https://github.com/bastibe/org-journal">org-journal</a> is a plugin for maintaining a journal in org mode. I want to have its entries separate from my knowledge base.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-journal
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/remote-server)
|
||
:after org
|
||
:config
|
||
(setq org-journal-dir (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/journal"</span>))
|
||
(setq org-journal-file-type <span style="color:#e6db74">'weekly</span>)
|
||
(setq org-journal-file-format <span style="color:#e6db74">"%Y-%m-%d.org"</span>)
|
||
(setq org-journal-date-format <span style="color:#e6db74">"%A, %Y-%m-%d"</span>)
|
||
(setq org-journal-enable-encryption <span style="color:#66d9ef">t</span>))
|
||
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"oj"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-journal"</span>)
|
||
<span style="color:#e6db74">"j"</span> <span style="color:#e6db74">'org-journal-new-entry</span>
|
||
<span style="color:#e6db74">"o"</span> <span style="color:#e6db74">'org-journal-open-current-journal-file</span>
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'org-journal-search</span>)
|
||
</code></pre></div><p>Also, I want to store some information in the journal as properties of the record. So below is a function which does just that.</p>
|
||
<p>As of now, it stores Emacs version, hostname, location and current EMMS track if there is one.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-journal-header ()
|
||
(org-set-property <span style="color:#e6db74">"Emacs"</span> emacs-version)
|
||
(org-set-property <span style="color:#e6db74">"Hostname"</span> <span style="color:#a6e22e">system-name</span>)
|
||
(when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/location</span>)
|
||
(org-set-property <span style="color:#e6db74">"Location"</span> my/location))
|
||
(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'emms-playlist-current-selected-track</span>)
|
||
(let ((track (emms-playlist-current-selected-track)))
|
||
(when track
|
||
(let ((album (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-album</span> track)))
|
||
(artist (or (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-albumartist</span> track))
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-album</span> track))))
|
||
(title (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'info-title</span> track)))
|
||
(<span style="color:#a6e22e">string</span> <span style="color:#e6db74">""</span>))
|
||
(when artist
|
||
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> <span style="color:#e6db74">"["</span> artist <span style="color:#e6db74">"] "</span>)))
|
||
(when album
|
||
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> album <span style="color:#e6db74">" - "</span>)))
|
||
(when title
|
||
(setq <span style="color:#a6e22e">string</span> (<span style="color:#a6e22e">concat</span> <span style="color:#a6e22e">string</span> title)))
|
||
(when (<span style="color:#a6e22e">></span> (<span style="color:#a6e22e">length</span> <span style="color:#a6e22e">string</span>) <span style="color:#ae81ff">0</span>)
|
||
(org-set-property <span style="color:#e6db74">"EMMS_Track"</span> <span style="color:#a6e22e">string</span>)))))))
|
||
|
||
(add-hook <span style="color:#e6db74">'org-journal-after-entry-create-hook</span>
|
||
<span style="color:#a6e22e">#'</span>my/set-journal-header)
|
||
</code></pre></div><h4 id="org-roam">Org Roam</h4>
|
||
<p><a href="https://github.com/org-roam/org-roam">org-roam</a> is a plain-text knowledge database.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>emacs-emacsql-sqlite3</td>
|
||
</tr>
|
||
<tr>
|
||
<td>graphviz</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/org-roam/org-roam/wiki/Hitchhiker%27s-Rough-Guide-to-Org-roam-V2">Hitchhiker’s Rough Guide to Org roam V2</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package emacsql-sqlite
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:straight (:type built-in))
|
||
|
||
(use-package org-roam
|
||
:straight (:host github :repo <span style="color:#e6db74">"org-roam/org-roam"</span>
|
||
:files (:defaults <span style="color:#e6db74">"extensions/*.el"</span>))
|
||
:if (not my/remote-server)
|
||
:after org
|
||
:init
|
||
(setq org-roam-directory (<span style="color:#a6e22e">concat</span> org-directory <span style="color:#e6db74">"/roam"</span>))
|
||
(setq org-roam-file-extensions <span style="color:#f92672">'</span>(<span style="color:#e6db74">"org"</span>))
|
||
(setq org-roam-v2-ack <span style="color:#66d9ef">t</span>)
|
||
(setq orb-insert-interface <span style="color:#e6db74">'ivy-bibtex</span>)
|
||
:config
|
||
(org-roam-setup)
|
||
(setq org-roam-capture-templates
|
||
<span style="color:#f92672">`</span>((<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">"default"</span> plain <span style="color:#e6db74">"%?"</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>)
|
||
:unnarrowed <span style="color:#66d9ef">t</span>)))
|
||
(require <span style="color:#e6db74">'org-roam-protocol</span>)
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-roam-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
<span style="color:#e6db74">"TAB"</span> <span style="color:#a6e22e">#'</span>magit-section-toggle
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#a6e22e">#'</span>quit-window
|
||
<span style="color:#e6db74">"k"</span> <span style="color:#a6e22e">#'</span>magit-section-backward
|
||
<span style="color:#e6db74">"j"</span> <span style="color:#a6e22e">#'</span>magit-section-forward
|
||
<span style="color:#e6db74">"gr"</span> <span style="color:#a6e22e">#'</span>revert-buffer
|
||
<span style="color:#e6db74">"RET"</span> <span style="color:#a6e22e">#'</span>org-roam-buffer-visit-thing))
|
||
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"or"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-roam"</span>)
|
||
<span style="color:#e6db74">"i"</span> <span style="color:#e6db74">'org-roam-node-insert</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'org-roam-node-find</span>
|
||
<span style="color:#e6db74">"g"</span> <span style="color:#e6db74">'org-roam-graph</span>
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'org-roam-capture</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'org-roam-buffer-toggle</span>)
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'org</span>
|
||
(my-leader-def
|
||
:keymap <span style="color:#e6db74">'org-mode-map</span>
|
||
:infix <span style="color:#e6db74">"or"</span>
|
||
<span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'org-roam-tag-add</span>
|
||
<span style="color:#e6db74">"T"</span> <span style="color:#e6db74">'org-toam-tag-remove</span>)
|
||
(general-define-key
|
||
:keymap <span style="color:#e6db74">'org-mode-map</span>
|
||
<span style="color:#e6db74">"C-c i"</span> <span style="color:#e6db74">'org-id-get-create</span>
|
||
<span style="color:#e6db74">"C-c l o"</span> <span style="color:#e6db74">'org-roam-node-insert</span>))
|
||
</code></pre></div><h5 id="org-roam-ui">org-roam-ui</h5>
|
||
<p>A browser frontend to visualize a Roam directory in a form of a graph.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-roam-ui
|
||
:straight (:host github :repo <span style="color:#e6db74">"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>))
|
||
:after org-roam
|
||
<span style="color:#75715e">;; :hook (org-roam . org-roam-ui-mode)</span>
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"oru"</span> <span style="color:#a6e22e">#'</span>org-roam-ui-mode))
|
||
</code></pre></div><h5 id="org-roam-protocol">org-roam-protocol</h5>
|
||
<p>Open links such as <code>org-protocol://</code> from browser. Run <code>M-x server-start</code> for org-protocol to work.</p>
|
||
<pre><code class="language-conf" data-lang="conf">[Desktop Entry]
|
||
Name=Org-Protocol
|
||
Exec=emacsclient %u
|
||
Icon=emacs-icon
|
||
Type=Application
|
||
Terminal=false
|
||
MimeType=x-scheme-handler/org-protocol
|
||
</code></pre><p>Don’t forget to run the following after setup:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
|
||
</code></pre></div><h4 id="org-ref">org-ref</h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>TODO</td>
|
||
<td>Figure out how not to load Helm</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><a href="https://github.com/jkitchin/org-ref">org-ref</a> is a package that provides support for various citations & 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">(use-package org-ref
|
||
:straight (:files (:defaults (:exclude <span style="color:#e6db74">"*helm*"</span>)))
|
||
:if (not my/remote-server)
|
||
:init
|
||
(setq org-ref-completion-library <span style="color:#e6db74">'org-ref-ivy-cite</span>)
|
||
(setq bibtex-dialect <span style="color:#e6db74">'biblatex</span>)
|
||
(setq org-ref-default-bibliography <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/Documents/org-mode/bibliography.bib"</span>))
|
||
(setq reftex-default-bibliography org-ref-default-bibliography)
|
||
(setq bibtex-completion-bibliography org-ref-default-bibliography)
|
||
:after (org)
|
||
:config
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
:infix <span style="color:#e6db74">"C-c l"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"org-ref"</span>)
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'org-ref-ivy-insert-cite-link</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'org-ref-ivy-insert-ref-link</span>
|
||
<span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'org-ref-cite-hydra/body</span>)
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'bibtex-mode-map</span>
|
||
<span style="color:#e6db74">"M-RET"</span> <span style="color:#e6db74">'org-ref-bibtex-hydra/body</span>)
|
||
<span style="color:#75715e">;; (add-to-list 'orhc-candidate-formats</span>
|
||
<span style="color:#75715e">;; '("online" . " |${=key=}| ${title} ${url}"))</span>
|
||
)
|
||
</code></pre></div><h4 id="org-roam-bibtex">org-roam-bibtex</h4>
|
||
<p>Integration with bibtex and org-ref.</p>
|
||
<p>There are some problems with org roam v2, so I disabled it as of now. I will probably use another way of managing bibliography notes anyway.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-roam-bibtex
|
||
:straight (:host github :repo <span style="color:#e6db74">"org-roam/org-roam-bibtex"</span>)
|
||
:after (org-roam org-ref)
|
||
:disabled
|
||
:config
|
||
(org-roam-bibtex-mode))
|
||
</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">(defun my/export-org-tables-to-csv ()
|
||
(interactive)
|
||
(org-table-map-tables
|
||
(lambda ()
|
||
(when-let
|
||
(name
|
||
(<span style="color:#a6e22e">plist-get</span> (cadr (org-element-at-point)) :name))
|
||
(org-table-export
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">file-name-directory</span>
|
||
(<span style="color:#a6e22e">buffer-file-name</span>))
|
||
name <span style="color:#e6db74">".csv"</span>)
|
||
<span style="color:#e6db74">"orgtbl-to-csv"</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">(use-package org-latex-impatient
|
||
:straight (:repo <span style="color:#e6db74">"yangsheng6810/org-latex-impatient"</span>
|
||
:branch <span style="color:#e6db74">"master"</span>
|
||
:host github)
|
||
:hook (org-mode <span style="color:#f92672">.</span> org-latex-impatient-mode)
|
||
:disabled
|
||
:init
|
||
(setq org-latex-impatient-tex2svg-bin
|
||
<span style="color:#e6db74">"/home/pavel/Programs/miniconda3/lib/node_modules/mathjax-node-cli/bin/tex2svg"</span>)
|
||
(setq org-latex-impatient-scale <span style="color:#ae81ff">1.75</span>)
|
||
(setq org-latex-impatient-delay <span style="color:#ae81ff">1</span>)
|
||
(setq org-latex-impatient-border-color <span style="color:#e6db74">"#ffffff"</span>))
|
||
</code></pre></div><h4 id="latex-fragments">LaTeX fragments</h4>
|
||
<p>A function to enable LaTeX native highlighting. Not setting this as default, because it loads LaTeX stuff.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/enable-org-latex ()
|
||
(interactive)
|
||
(customize-set-variable <span style="color:#e6db74">'org-highlight-latex-and-related</span> <span style="color:#f92672">'</span>(native))
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span> (lambda () (yas-activate-extra-mode <span style="color:#e6db74">'LaTeX-mode</span>)))
|
||
(sp-local-pair <span style="color:#e6db74">'org-mode</span> <span style="color:#e6db74">"$"</span> <span style="color:#e6db74">"$"</span>)
|
||
(sp--remove-local-pair <span style="color:#e6db74">"'"</span>))
|
||
</code></pre></div><p>Call the function before opening an org file or reopen a buffer after calling the function.</p>
|
||
<p>Scale latex fragments preview.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-latex-scale <span style="color:#ae81ff">1.75</span>)
|
||
(setq org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
|
||
</code></pre></div><p>Also, LaTeX fragments preview tends to break whenever the are custom <code>#+LATEX_HEADER</code> entries. To circumvent this, I add a custom header and modify the <code>org-preview-latex-process-alist</code> variable</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-preview-header <span style="color:#e6db74">"\\documentclass{article}
|
||
</span><span style="color:#e6db74">\\usepackage[usenames]{color}
|
||
</span><span style="color:#e6db74">\\usepackage{graphicx}
|
||
</span><span style="color:#e6db74">\\usepackage{grffile}
|
||
</span><span style="color:#e6db74">\\usepackage{longtable}
|
||
</span><span style="color:#e6db74">\\usepackage{wrapfig}
|
||
</span><span style="color:#e6db74">\\usepackage{rotating}
|
||
</span><span style="color:#e6db74">\\usepackage[normalem]{ulem}
|
||
</span><span style="color:#e6db74">\\usepackage{amsmath}
|
||
</span><span style="color:#e6db74">\\usepackage{textcomp}
|
||
</span><span style="color:#e6db74">\\usepackage{amssymb}
|
||
</span><span style="color:#e6db74">\\usepackage{capt-of}
|
||
</span><span style="color:#e6db74">\\usepackage{hyperref}
|
||
</span><span style="color:#e6db74">\\pagestyle{empty}"</span>)
|
||
|
||
(setq org-preview-latex-process-alist
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (item)
|
||
(<span style="color:#a6e22e">cons</span>
|
||
(<span style="color:#a6e22e">car</span> item)
|
||
(<span style="color:#a6e22e">plist-put</span> (<span style="color:#a6e22e">cdr</span> item) :latex-header my/latex-preview-header)))
|
||
org-preview-latex-process-alist))
|
||
</code></pre></div><h4 id="better-headers">Better headers</h4>
|
||
<p><a href="https://github.com/integral-dw/org-superstar-mode">org-superstar-mode</a> is 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">(use-package org-superstar
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:disabled
|
||
:hook (org-mode <span style="color:#f92672">.</span> org-superstar-mode))
|
||
</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">(use-package org-bars
|
||
:straight (:repo <span style="color:#e6db74">"tonyaldon/org-bars"</span> :host github)
|
||
:if (display-graphic-p)
|
||
:hook (org-mode <span style="color:#f92672">.</span> org-bars-mode))
|
||
</code></pre></div><p>Remove the elipsis at the end of folded headlines. The elipsis seems unnecesary 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">(defun my/org-no-ellipsis-in-headlines ()
|
||
(remove-from-invisibility-spec <span style="color:#f92672">'</span>(outline <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>))
|
||
(add-to-invisibility-spec <span style="color:#e6db74">'outline</span>))
|
||
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span> <span style="color:#a6e22e">#'</span>my/org-no-ellipsis-in-headlines)
|
||
</code></pre></div><h4 id="org-agenda-icons">Org Agenda Icons</h4>
|
||
<p>Categories are broad labels to group agenda items.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(if (not my/lowpower)
|
||
(setq org-agenda-category-icon-alist
|
||
<span style="color:#f92672">`</span>((<span style="color:#e6db74">"inbox"</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">"inbox"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
|
||
(<span style="color:#e6db74">"work"</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">"cog"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
|
||
(<span style="color:#e6db74">"education"</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-material <span style="color:#e6db74">"build"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
|
||
(<span style="color:#e6db74">"personal"</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">"music"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
|
||
(<span style="color:#e6db74">"misc"</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-material <span style="color:#e6db74">"archive"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center)
|
||
<span style="color:#75715e">;; ("lesson" ,(list (all-the-icons-faicon "book")) nil nil :ascent center)</span>
|
||
<span style="color:#75715e">;; ("meeting" ,(list (all-the-icons-material "chat")) nil nil :ascent center)</span>
|
||
<span style="color:#75715e">;; ("event" ,(list (all-the-icons-octicon "clock")) nil nil :ascent center)</span>
|
||
(<span style="color:#e6db74">"."</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">list</span> (all-the-icons-faicon <span style="color:#e6db74">"circle-o"</span>)) <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> :ascent center))))
|
||
</code></pre></div><h3 id="export">Export</h3>
|
||
<h4 id="general-settings">General settings</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (setq org-export-backends '(md html latex beamer org))</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">(use-package ox-hugo
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after ox)
|
||
</code></pre></div><h4 id="jupyter-notebook">Jupyter Notebook</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ox-ipynb
|
||
:straight (:host github :repo <span style="color:#e6db74">"jkitchin/ox-ipynb"</span>)
|
||
:after ox)
|
||
</code></pre></div><h4 id="html-export">Html export</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package htmlize
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after ox
|
||
:config
|
||
(setq org-html-htmlize-output-type <span style="color:#e6db74">'css</span>))
|
||
</code></pre></div><h4 id="latex">LaTeX</h4>
|
||
<p>Add a custom LaTeX template without default packages. Packages are indented to be imported with function from <a href="#import-dot-sty">Import *.sty</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/setup-org-latex ()
|
||
(setq org-latex-prefer-user-labels <span style="color:#66d9ef">t</span>)
|
||
(setq org-latex-compiler <span style="color:#e6db74">"xelatex"</span>) <span style="color:#75715e">;; Probably not necessary</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>
|
||
(setq org-latex-listings <span style="color:#e6db74">'minted</span>) <span style="color:#75715e">;; Use minted to highlight source code</span>
|
||
(setq org-latex-minted-options <span style="color:#75715e">;; Some minted options I like</span>
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"breaklines"</span> <span style="color:#e6db74">"true"</span>)
|
||
(<span style="color:#e6db74">"tabsize"</span> <span style="color:#e6db74">"4"</span>)
|
||
(<span style="color:#e6db74">"autogobble"</span>)
|
||
(<span style="color:#e6db74">"linenos"</span>)
|
||
(<span style="color:#e6db74">"numbersep"</span> <span style="color:#e6db74">"0.5cm"</span>)
|
||
(<span style="color:#e6db74">"xleftmargin"</span> <span style="color:#e6db74">"1cm"</span>)
|
||
(<span style="color:#e6db74">"frame"</span> <span style="color:#e6db74">"single"</span>)))
|
||
<span style="color:#75715e">;; Use extarticle without the default packages</span>
|
||
(add-to-list <span style="color:#e6db74">'org-latex-classes</span>
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"org-plain-extarticle"</span>
|
||
<span style="color:#e6db74">"\\documentclass{extarticle}
|
||
</span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
|
||
</span><span style="color:#e6db74">[PACKAGES]
|
||
</span><span style="color:#e6db74">[EXTRA]"</span>
|
||
(<span style="color:#e6db74">"\\section{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\subsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\subsubsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\paragraph{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\paragraph*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\subparagraph{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subparagraph*{%s}"</span>)))
|
||
<span style="color:#75715e">;; Use beamer without the default packages</span>
|
||
(add-to-list <span style="color:#e6db74">'org-latex-classes</span>
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"org-latex-beamer"</span>
|
||
<span style="color:#e6db74">"\\documentclass{beamer}
|
||
</span><span style="color:#e6db74">[NO-DEFAULT-PACKAGES]
|
||
</span><span style="color:#e6db74">[PACKAGES]
|
||
</span><span style="color:#e6db74">[EXTRA]"</span>
|
||
(<span style="color:#e6db74">"beamer"</span> <span style="color:#e6db74">"\\documentclass[presentation]{beamer}"</span>
|
||
(<span style="color:#e6db74">"\\section{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\subsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection*{%s}"</span>)
|
||
(<span style="color:#e6db74">"\\subsubsection{%s}"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection*{%s}"</span>)))))
|
||
|
||
<span style="color:#75715e">;; Make sure to eval the function when org-latex-classes list already exists</span>
|
||
(with-eval-after-load <span style="color:#e6db74">'ox-latex</span>
|
||
(my/setup-org-latex))
|
||
</code></pre></div><h3 id="keybindings-and-stuff">Keybindings & stuff</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
<span style="color:#e6db74">"C-c d"</span> <span style="color:#e6db74">'org-decrypt-entry</span>
|
||
<span style="color:#e6db74">"C-c e"</span> <span style="color:#e6db74">'org-encrypt-entry</span>
|
||
<span style="color:#e6db74">"M-p"</span> <span style="color:#e6db74">'org-latex-preview</span>
|
||
<span style="color:#e6db74">"M-o"</span> <span style="color:#e6db74">'org-redisplay-inline-images</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
:states <span style="color:#f92672">'</span>(normal emacs)
|
||
<span style="color:#e6db74">"L"</span> <span style="color:#e6db74">'org-shiftright</span>
|
||
<span style="color:#e6db74">"H"</span> <span style="color:#e6db74">'org-shiftleft</span>
|
||
<span style="color:#e6db74">"S-<next>"</span> <span style="color:#e6db74">'org-next-visible-heading</span>
|
||
<span style="color:#e6db74">"S-<prior>"</span> <span style="color:#e6db74">'org-previous-visible-heading</span>
|
||
<span style="color:#e6db74">"M-0"</span> <span style="color:#e6db74">'org-next-visible-heading</span>
|
||
<span style="color:#e6db74">"M-9"</span> <span style="color:#e6db74">'org-previous-visible-heading</span>
|
||
<span style="color:#e6db74">"M-]"</span> <span style="color:#e6db74">'org-babel-next-src-block</span>
|
||
<span style="color:#e6db74">"M-["</span> <span style="color:#e6db74">'org-babel-previous-src-block</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-agenda-mode-map</span>
|
||
<span style="color:#e6db74">"M-]"</span> <span style="color:#e6db74">'org-agenda-later</span>
|
||
<span style="color:#e6db74">"M-["</span> <span style="color:#e6db74">'org-agenda-earlier</span>)
|
||
|
||
<span style="color:#75715e">;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)</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 style="color:#75715e">;; (my-leader-def "aa" 'org-agenda)</span>
|
||
</code></pre></div><h4 id="copy-a-link">Copy a link</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/org-link-copy (<span style="color:#66d9ef">&optional</span> arg)
|
||
<span style="color:#e6db74">"Extract URL from org-mode link and add it to kill ring."</span>
|
||
(interactive <span style="color:#e6db74">"P"</span>)
|
||
(let* ((link (org-element-lineage (org-element-context) <span style="color:#f92672">'</span>(link) <span style="color:#66d9ef">t</span>))
|
||
(type (org-element-property :type link))
|
||
(url (org-element-property :path link))
|
||
(url (<span style="color:#a6e22e">concat</span> type <span style="color:#e6db74">":"</span> url)))
|
||
(kill-new url)
|
||
(<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Copied URL: "</span> url))))
|
||
|
||
(general-nmap :keymaps <span style="color:#e6db74">'org-mode-map</span>
|
||
<span style="color:#e6db74">"C-x C-l"</span> <span style="color:#e6db74">'my/org-link-copy</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">(defun my/org-file-open ()
|
||
(interactive)
|
||
(let* ((default-directory org-directory)
|
||
(project-files
|
||
(seq-filter
|
||
(lambda (f)
|
||
(and
|
||
(string-match-p (rx (<span style="color:#a6e22e">*</span> nonl) <span style="color:#e6db74">".org"</span> eos) f)
|
||
(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))))
|
||
(projectile-current-project-files))))
|
||
(find-file
|
||
(<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)))))
|
||
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"o o"</span> <span style="color:#e6db74">'my/org-file-open</span>)
|
||
</code></pre></div><h3 id="presentations">Presentations</h3>
|
||
<p>Doing presentations with <a href="https://github.com/rlister/org-present">org-present</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hide-mode-line
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (org-present))
|
||
|
||
(defun my/present-next-with-latex ()
|
||
(interactive)
|
||
(org-present-next)
|
||
(org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>)))
|
||
|
||
(defun my/present-prev-with-latex ()
|
||
(interactive)
|
||
(org-present-prev)
|
||
(org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>)))
|
||
|
||
(use-package org-present
|
||
:straight (:host github :repo <span style="color:#e6db74">"rlister/org-present"</span>)
|
||
:if (not my/remote-server)
|
||
:commands (org-present)
|
||
:config
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'org-present-mode-keymap</span>
|
||
<span style="color:#e6db74">"<next>"</span> <span style="color:#e6db74">'my/present-next-with-latex</span>
|
||
<span style="color:#e6db74">"<prior>"</span> <span style="color:#e6db74">'my/present-prev-with-latex</span>)
|
||
(add-hook <span style="color:#e6db74">'org-present-mode-hook</span>
|
||
(lambda ()
|
||
(blink-cursor-mode <span style="color:#ae81ff">0</span>)
|
||
(org-present-big)
|
||
<span style="color:#75715e">;; (org-display-inline-images)</span>
|
||
(org-present-hide-cursor)
|
||
(org-present-read-only)
|
||
(display-line-numbers-mode <span style="color:#ae81ff">0</span>)
|
||
(hide-mode-line-mode <span style="color:#ae81ff">+1</span>)
|
||
(setq-local org-format-latex-options
|
||
(<span style="color:#a6e22e">plist-put</span> org-format-latex-options
|
||
:scale (<span style="color:#a6e22e">*</span> org-present-text-scale my/org-latex-scale <span style="color:#ae81ff">0.5</span>)))
|
||
(org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">16</span>))))
|
||
(add-hook <span style="color:#e6db74">'org-present-mode-quit-hook</span>
|
||
(lambda ()
|
||
(blink-cursor-mode <span style="color:#ae81ff">1</span>)
|
||
(org-present-small)
|
||
<span style="color:#75715e">;; (org-remove-inline-images)</span>
|
||
(org-present-show-cursor)
|
||
(org-present-read-write)
|
||
(display-line-numbers-mode <span style="color:#ae81ff">1</span>)
|
||
(hide-mode-line-mode <span style="color:#ae81ff">0</span>)
|
||
(setq-local org-format-latex-options (<span style="color:#a6e22e">plist-put</span> org-format-latex-options :scale my/org-latex-scale))
|
||
(org-latex-preview <span style="color:#f92672">'</span>(<span style="color:#ae81ff">64</span>)))))
|
||
</code></pre></div><h3 id="tools">Tools</h3>
|
||
<p>Various small packages.</p>
|
||
<h4 id="toc">TOC</h4>
|
||
<p>Make a TOC inside the org file.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/alphapapa/org-make-toc">alphapapa/org-make-toc</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-make-toc
|
||
:after (org)
|
||
:if (not my/remote-server)
|
||
:commands
|
||
(org-make-toc
|
||
org-make-toc-insert
|
||
org-make-toc-set
|
||
org-make-toc-at-point)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="screenshots">Screenshots</h4>
|
||
<p>A nice package to make screenshots and insert them to the Org document.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package org-attach-screenshot
|
||
:commands (org-attach-screenshot)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h3 id="system-configuration">System configuration</h3>
|
||
<p>Functions used across my literate config files.</p>
|
||
<h4 id="tables-for-guix-dependencies">Tables for Guix Dependencies</h4>
|
||
<p>A function to extract Guix dependencies from the org file.</p>
|
||
<ul>
|
||
<li>If column name matches <code>[G|g]uix.*dep</code>, its contents will be added to the result.</li>
|
||
<li>If <code>CATEGORY</code> is passed, a column with name <code>[C|c]ategory</code> will be used to filter results. That way one file can be used to produce multiple manifests.</li>
|
||
<li>If <code>CATEGORY</code> is not passed, entries with non-empty category will be filtered out</li>
|
||
<li>If there is a <code>[D|d]isabled</code> column, entries that have a non-empty value in this column will be filtered out.</li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/extract-guix-dependencies (<span style="color:#66d9ef">&optional</span> category)
|
||
(let ((dependencies <span style="color:#f92672">'</span>()))
|
||
(org-table-map-tables
|
||
(lambda ()
|
||
(let* ((table
|
||
(seq-filter
|
||
(lambda (q) (not (<span style="color:#a6e22e">eq</span> q <span style="color:#e6db74">'hline</span>)))
|
||
(org-table-to-lisp)))
|
||
(dep-name-index
|
||
(cl-position
|
||
<span style="color:#66d9ef">nil</span>
|
||
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'substring-no-properties</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> table))
|
||
:test (lambda (_ elem)
|
||
(string-match-p <span style="color:#e6db74">"[G|g]uix.*dep"</span> elem))))
|
||
(category-name-index
|
||
(cl-position
|
||
<span style="color:#66d9ef">nil</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))
|
||
:test (lambda (_ elem)
|
||
(string-match-p <span style="color:#e6db74">".*[C|c]ategory.*"</span> elem))))
|
||
(disabled-name-index
|
||
(cl-position
|
||
<span style="color:#66d9ef">nil</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))
|
||
:test (lambda (_ elem)
|
||
(string-match-p <span style="color:#e6db74">".*[D|d]isabled.*"</span> elem)))))
|
||
(when dep-name-index
|
||
(dolist (elem (<span style="color:#a6e22e">cdr</span> table))
|
||
(when
|
||
(and
|
||
<span style="color:#75715e">;; Category</span>
|
||
(or
|
||
<span style="color:#75715e">;; Category not set and not present in the table</span>
|
||
(and
|
||
(or (not category) (string-empty-p category))
|
||
(not category-name-index))
|
||
<span style="color:#75715e">;; Category is set and present in the table</span>
|
||
(and
|
||
category-name-index
|
||
(not (string-empty-p category))
|
||
(string-match-p category (<span style="color:#a6e22e">nth</span> category-name-index elem))))
|
||
<span style="color:#75715e">;; Not disabled</span>
|
||
(or
|
||
(not disabled-name-index)
|
||
(string-empty-p (<span style="color:#a6e22e">nth</span> disabled-name-index elem))))
|
||
(add-to-list
|
||
<span style="color:#e6db74">'dependencies</span>
|
||
(<span style="color:#a6e22e">substring-no-properties</span> (<span style="color:#a6e22e">nth</span> dep-name-index elem)))))))))
|
||
dependencies))
|
||
</code></pre></div><p>Now, join the dependencies list to make it compatible with Scheme:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/format-guix-dependencies (<span style="color:#66d9ef">&optional</span> category)
|
||
(<span style="color:#a6e22e">mapconcat</span>
|
||
(lambda (e) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"\""</span> e <span style="color:#e6db74">"\""</span>))
|
||
(my/extract-guix-dependencies category)
|
||
<span style="color:#e6db74">"\n"</span>))
|
||
</code></pre></div><h4 id="noweb-evaluations">Noweb evaluations</h4>
|
||
<p>Turn off eval confirmations for configuration files.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/org-config-files
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"/home/pavel/Emacs.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Desktop.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Console.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Guix.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Mail.org"</span>))
|
||
|
||
(add-hook <span style="color:#e6db74">'org-mode-hook</span>
|
||
(lambda ()
|
||
(when (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">buffer-file-name</span>) my/org-config-files)
|
||
(setq-local org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>))))
|
||
</code></pre></div><h4 id="yadm-hook">yadm hook</h4>
|
||
<p>A script to run tangle from CLI.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(require <span style="color:#e6db74">'org</span>)
|
||
|
||
(org-babel-do-load-languages
|
||
<span style="color:#e6db74">'org-babel-load-languages</span>
|
||
<span style="color:#f92672">'</span>((emacs-lisp <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)
|
||
(shell <span style="color:#f92672">.</span> <span style="color:#66d9ef">t</span>)))
|
||
|
||
<span style="color:#75715e">;; Do not ask to confirm evaluations</span>
|
||
(setq org-confirm-babel-evaluate <span style="color:#66d9ef">nil</span>)
|
||
|
||
<<guix-tables>>
|
||
|
||
<span style="color:#75715e">;; A few dummy modes to avoid being prompted for comment systax</span>
|
||
(define-derived-mode fish-mode prog-mode <span style="color:#e6db74">"Fish"</span>
|
||
(setq-local comment-start <span style="color:#e6db74">"# "</span>)
|
||
(setq-local comment-start-skip <span style="color:#e6db74">"#+[\t ]*"</span>))
|
||
|
||
(define-derived-mode yaml-mode text-mode <span style="color:#e6db74">"YAML"</span>
|
||
(setq-local comment-start <span style="color:#e6db74">"# "</span>)
|
||
(setq-local comment-start-skip <span style="color:#e6db74">"#+ *"</span>))
|
||
|
||
(<span style="color:#a6e22e">mapcar</span> <span style="color:#a6e22e">#'</span>org-babel-tangle-file
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"/home/pavel/Emacs.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Desktop.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Console.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Guix.org"</span>
|
||
<span style="color:#e6db74">"/home/pavel/Mail.org"</span>))
|
||
</code></pre></div><p>To launch from CLI, run:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">emacs -Q --batch -l run-tangle.el
|
||
</code></pre></div><p>I have added this line to yadm’s <code>post_alt</code> hook, so tangle is run after <code>yadm alt</code></p>
|
||
<h2 id="programming">Programming</h2>
|
||
<h3 id="general-setup">General setup</h3>
|
||
<h4 id="lsp">LSP</h4>
|
||
<p>LSP-mode provides an IDE-like experience for Emacs - real-time diagnostic, code actions, intelligent autocompletion, etc.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://emacs-lsp.github.io/lsp-mode/">lsp-mode homepage</a></li>
|
||
</ul>
|
||
<h5 id="setup">Setup</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lsp-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not (or my/slow-ssh my/is-termux my/remote-server))
|
||
:hook (
|
||
(typescript-mode <span style="color:#f92672">.</span> lsp)
|
||
(js-mode <span style="color:#f92672">.</span> lsp)
|
||
(vue-mode <span style="color:#f92672">.</span> lsp)
|
||
(go-mode <span style="color:#f92672">.</span> lsp)
|
||
(svelte-mode <span style="color:#f92672">.</span> lsp)
|
||
<span style="color:#75715e">;; (python-mode . lsp)</span>
|
||
(json-mode <span style="color:#f92672">.</span> lsp)
|
||
(haskell-mode <span style="color:#f92672">.</span> lsp)
|
||
(haskell-literate-mode <span style="color:#f92672">.</span> lsp)
|
||
(java-mode <span style="color:#f92672">.</span> lsp)
|
||
<span style="color:#75715e">;; (csharp-mode . lsp)</span>
|
||
)
|
||
:commands lsp
|
||
:init
|
||
(setq lsp-keymap-prefix <span style="color:#66d9ef">nil</span>)
|
||
:config
|
||
(setq lsp-idle-delay <span style="color:#ae81ff">1</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>))
|
||
(setq lsp-eslint-run <span style="color:#e6db74">"onSave"</span>)
|
||
(setq lsp-signature-render-documentation <span style="color:#66d9ef">nil</span>)
|
||
<span style="color:#75715e">;; (lsp-headerline-breadcrumb-mode nil)</span>
|
||
(setq lsp-headerline-breadcrumb-enable <span style="color:#66d9ef">nil</span>)
|
||
(add-to-list <span style="color:#e6db74">'lsp-language-id-configuration</span> <span style="color:#f92672">'</span>(svelte-mode <span style="color:#f92672">.</span> <span style="color:#e6db74">"svelte"</span>)))
|
||
|
||
(use-package lsp-ui
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands lsp-ui-mode
|
||
:config
|
||
(setq lsp-ui-doc-delay <span style="color:#ae81ff">2</span>)
|
||
(setq lsp-ui-sideline-show-hover <span style="color:#66d9ef">nil</span>))
|
||
</code></pre></div><h5 id="integrations">Integrations</h5>
|
||
<p>The only integration left now is treemacs.</p>
|
||
<p>Origami should’ve leveraged LSP folding, but it was too unstable at the moment I tried it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="color:#75715e">;; (use-package helm-lsp</span>
|
||
<span style="color:#75715e">;; :straight t</span>
|
||
<span style="color:#75715e">;; :commands helm-lsp-workspace-symbol)</span>
|
||
|
||
<span style="color:#75715e">;; (use-package origami</span>
|
||
<span style="color:#75715e">;; :straight t</span>
|
||
<span style="color:#75715e">;; :hook (prog-mode . origami-mode))</span>
|
||
|
||
<span style="color:#75715e">;; (use-package lsp-origami</span>
|
||
<span style="color:#75715e">;; :straight t</span>
|
||
<span style="color:#75715e">;; :config</span>
|
||
<span style="color:#75715e">;; (add-hook 'lsp-after-open-hook #'lsp-origami-try-enable))</span>
|
||
|
||
(use-package lsp-treemacs
|
||
:after (lsp)
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands lsp-treemacs-errors-list)
|
||
</code></pre></div><h5 id="keybindings">Keybindings</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:infix <span style="color:#e6db74">"l"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"lsp"</span>)
|
||
<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'lsp-ui-peek-find-definitions</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'lsp-rename</span>
|
||
<span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'lsp-ui-peek-find-references</span>
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'lsp-ui-find-workspace-symbol</span>
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'lsp-execute-code-action</span>
|
||
<span style="color:#e6db74">"e"</span> <span style="color:#e6db74">'list-flycheck-errors</span>)
|
||
</code></pre></div><h4 id="flycheck">Flycheck</h4>
|
||
<p>A syntax checking extension for Emacs. Integrates with LSP-mode, but can also use various standalone checkers.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://www.flycheck.org/en/latest/">Flycheck homepage</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package flycheck
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(global-flycheck-mode)
|
||
(setq flycheck-check-syntax-automatically <span style="color:#f92672">'</span>(save idle-buffer-switch mode-enabled))
|
||
<span style="color:#75715e">;; (add-hook 'evil-insert-state-exit-hook</span>
|
||
<span style="color:#75715e">;; (lambda ()</span>
|
||
<span style="color:#75715e">;; (if flycheck-checker</span>
|
||
<span style="color:#75715e">;; (flycheck-buffer))</span>
|
||
<span style="color:#75715e">;; ))</span>
|
||
(advice-add <span style="color:#e6db74">'flycheck-eslint-config-exists-p</span> :override (lambda() <span style="color:#66d9ef">t</span>))
|
||
(add-to-list <span style="color:#e6db74">'display-buffer-alist</span>
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx bos <span style="color:#e6db74">"*Flycheck errors*"</span> eos)
|
||
(display-buffer-reuse-window
|
||
display-buffer-in-side-window)
|
||
(side <span style="color:#f92672">.</span> bottom)
|
||
(reusable-frames <span style="color:#f92672">.</span> visible)
|
||
(window-height <span style="color:#f92672">.</span> <span style="color:#ae81ff">0.33</span>))))
|
||
</code></pre></div><h4 id="tree-sitter">Tree Sitter</h4>
|
||
<p>An incremental code parsing system, constructing a syntax tree at runtime.</p>
|
||
<p>Right now it doesn’t do much except provide a better syntax highlighting than regexes, but this integration is a rather recent development. There are already some major modes built on top of this thing.</p>
|
||
<p>Also, it seems to break if ran from mmm-mode, so there is a small workaround.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://tree-sitter.github.io/tree-sitter/">Tree-sitter library</a></li>
|
||
<li><a href="https://ubolonton.github.io/emacs-tree-sitter/">Emacs Tree-sitter</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/tree-sitter-if-not-mmm ()
|
||
(when (not (and (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'mmm-temp-buffer-name</span>)
|
||
(<span style="color:#a6e22e">string-equal</span> mmm-temp-buffer-name (<span style="color:#a6e22e">buffer-name</span>))))
|
||
(tree-sitter-mode)
|
||
(tree-sitter-hl-mode)))
|
||
|
||
(use-package tree-sitter
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/remote-server)
|
||
:hook ((typescript-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
|
||
(js-mode <span style="color:#f92672">.</span> my/tree-sitter-if-not-mmm)
|
||
(python-mode <span style="color:#f92672">.</span> tree-sitter-mode)
|
||
(python-mode <span style="color:#f92672">.</span> tree-sitter-hl-mode)
|
||
(csharp-mode <span style="color:#f92672">.</span> tree-sitter-mode)))
|
||
|
||
(use-package tree-sitter-langs
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after tree-sitter)
|
||
</code></pre></div><h4 id="dap">DAP</h4>
|
||
<p>An Emacs client for Debugger Adapter Protocol.</p>
|
||
<p>As of 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">(use-package dap-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (dap-debug)
|
||
:init
|
||
(setq lsp-enable-dap-auto-configure <span style="color:#66d9ef">nil</span>)
|
||
:config
|
||
|
||
(setq dap-ui-variable-length <span style="color:#ae81ff">100</span>)
|
||
(setq dap-auto-show-output <span style="color:#66d9ef">nil</span>)
|
||
(require <span style="color:#e6db74">'dap-node</span>)
|
||
(dap-node-setup)
|
||
|
||
(require <span style="color:#e6db74">'dap-chrome</span>)
|
||
(dap-chrome-setup)
|
||
|
||
(require <span style="color:#e6db74">'dap-python</span>)
|
||
|
||
(dap-mode <span style="color:#ae81ff">1</span>)
|
||
(dap-ui-mode <span style="color:#ae81ff">1</span>)
|
||
(dap-tooltip-mode <span style="color:#ae81ff">1</span>)
|
||
(tooltip-mode <span style="color:#ae81ff">1</span>))
|
||
</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 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">(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
(defmacro my/define-dap-ui-window-toggler (name)
|
||
<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 style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Toggle DAP "</span> name <span style="color:#e6db74">"buffer"</span>)
|
||
(interactive)
|
||
(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>))))
|
||
(quit-window <span style="color:#66d9ef">nil</span> window)
|
||
(<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))))))
|
||
|
||
(my/define-dap-ui-window-toggler <span style="color:#e6db74">"locals"</span>)
|
||
(my/define-dap-ui-window-toggler <span style="color:#e6db74">"expressions"</span>)
|
||
(my/define-dap-ui-window-toggler <span style="color:#e6db74">"sessions"</span>)
|
||
(my/define-dap-ui-window-toggler <span style="color:#e6db74">"breakpoints"</span>)
|
||
(my/define-dap-ui-window-toggler <span style="color:#e6db74">"repl"</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">(defhydra my/dap-hydra (:color pink :hint <span style="color:#66d9ef">nil</span> :foreign-keys run)
|
||
<span style="color:#e6db74">"
|
||
</span><span style="color:#e6db74">^Stepping^ ^UI^ ^Switch^ ^Breakpoints^ ^Debug^ ^Expressions
|
||
</span><span style="color:#e6db74">^^^^^^^^------------------------------------------------------------------------------------------------------------------------------------------
|
||
</span><span style="color:#e6db74">_n_: Next _uc_: Controls _ss_: Session _bb_: Toggle _dd_: Debug _ee_: Eval
|
||
</span><span style="color:#e6db74">_i_: Step in _ue_: Expressions _st_: Thread _bd_: Delete _dr_: Debug recent _er_: Eval region
|
||
</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 style="color:#e6db74">_c_: Continue _ur_: REPL _su_: Up stack frame _bc_: Set condition _de_: Edit debug template _ea_: Add expression
|
||
</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 style="color:#e6db74"> _us_: Sessions _sF_: Stack frame filtered _bl_: Set log message _eu_: Refresh expressions
|
||
</span><span style="color:#e6db74"> _ub_: Breakpoints "</span>
|
||
|
||
(<span style="color:#e6db74">"n"</span> dap-next)
|
||
(<span style="color:#e6db74">"i"</span> dap-step-in)
|
||
(<span style="color:#e6db74">"o"</span> dap-step-out)
|
||
(<span style="color:#e6db74">"c"</span> dap-continue)
|
||
(<span style="color:#e6db74">"r"</span> dap-restart-frame)
|
||
(<span style="color:#e6db74">"uc"</span> dap-ui-controls-mode)
|
||
(<span style="color:#e6db74">"ue"</span> my/dap-ui-toggle-expressions)
|
||
(<span style="color:#e6db74">"ul"</span> my/dap-ui-toggle-locals)
|
||
(<span style="color:#e6db74">"ur"</span> my/dap-ui-toggle-repl)
|
||
(<span style="color:#e6db74">"uo"</span> dap-ui-go-to-output-buffer)
|
||
(<span style="color:#e6db74">"us"</span> my/dap-ui-toggle-sessions)
|
||
(<span style="color:#e6db74">"ub"</span> my/dap-ui-toggle-breakpoints)
|
||
(<span style="color:#e6db74">"ss"</span> dap-switch-session)
|
||
(<span style="color:#e6db74">"st"</span> dap-switch-thread)
|
||
(<span style="color:#e6db74">"sf"</span> dap-switch-stack-frame)
|
||
(<span style="color:#e6db74">"sF"</span> my/dap-switch-stack-frame)
|
||
(<span style="color:#e6db74">"su"</span> dap-up-stack-frame)
|
||
(<span style="color:#e6db74">"sd"</span> dap-down-stack-frame)
|
||
(<span style="color:#e6db74">"bb"</span> dap-breakpoint-toggle)
|
||
(<span style="color:#e6db74">"ba"</span> dap-breakpoint-add)
|
||
(<span style="color:#e6db74">"bd"</span> dap-breakpoint-delete)
|
||
(<span style="color:#e6db74">"bc"</span> dap-breakpoint-condition)
|
||
(<span style="color:#e6db74">"bh"</span> dap-breakpoint-hit-condition)
|
||
(<span style="color:#e6db74">"bl"</span> dap-breakpoint-log-message)
|
||
(<span style="color:#e6db74">"dd"</span> dap-debug)
|
||
(<span style="color:#e6db74">"dr"</span> dap-debug-recent)
|
||
(<span style="color:#e6db74">"dl"</span> dap-debug-last)
|
||
(<span style="color:#e6db74">"de"</span> dap-debug-edit-template)
|
||
(<span style="color:#e6db74">"ee"</span> dap-eval)
|
||
(<span style="color:#e6db74">"ea"</span> dap-ui-expressions-add)
|
||
(<span style="color:#e6db74">"er"</span> dap-eval-region)
|
||
(<span style="color:#e6db74">"es"</span> dap-eval-thing-at-point)
|
||
(<span style="color:#e6db74">"ed"</span> dap-ui-expressions-remove)
|
||
(<span style="color:#e6db74">"eu"</span> dap-ui-expressions-refresh)
|
||
(<span style="color:#e6db74">"q"</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"quit"</span> :color blue)
|
||
(<span style="color:#e6db74">"Q"</span> dap-disconnect :color red))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"d"</span> <span style="color:#a6e22e">#'</span>my/dap-hydra/body)
|
||
</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 an 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">(defvar my/dap-mode-buffer-fixed <span style="color:#66d9ef">nil</span>)
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
(defmacro my/define-dap-tree-buffer-fixer (buffer-var <span style="color:#a6e22e">buffer-name</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> _)
|
||
(with-current-buffer <span style="color:#f92672">,</span>buffer-var
|
||
(unless my/dap-mode-buffer-fixed
|
||
(toggle-truncate-lines <span style="color:#ae81ff">1</span>)
|
||
(doom-modeline-set-modeline <span style="color:#e6db74">'info</span>)
|
||
(setq-local my/dap-mode-buffer-fixed <span style="color:#66d9ef">t</span>)))))
|
||
|
||
(my/define-dap-tree-buffer-fixer dap-ui--locals-buffer <span style="color:#e6db74">"locals"</span>)
|
||
(my/define-dap-tree-buffer-fixer dap-ui--expressions-buffer <span style="color:#e6db74">"expressions"</span>)
|
||
(my/define-dap-tree-buffer-fixer dap-ui--sessions-buffer <span style="color:#e6db74">"sessions"</span>)
|
||
(my/define-dap-tree-buffer-fixer dap-ui--breakpoints-buffer <span style="color:#e6db74">"breakpoints"</span>)
|
||
|
||
(advice-add <span style="color:#e6db74">'dap-ui-locals</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-locals-buffer)
|
||
(advice-add <span style="color:#e6db74">'dap-ui-expressions</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-expressions-buffer)
|
||
(advice-add <span style="color:#e6db74">'dap-ui-sessions</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-sessions-buffer)
|
||
(advice-add <span style="color:#e6db74">'dap-ui-breakpoints</span> :after <span style="color:#a6e22e">#'</span>my/fix-dap-ui-breakpoints-buffer))
|
||
</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">(defun my/clear-bad-window-parameters ()
|
||
<span style="color:#e6db74">"Clear window parameters that interrupt my workflow."</span>
|
||
(interactive)
|
||
(let ((window (<span style="color:#a6e22e">get-buffer-window</span> (<span style="color:#a6e22e">current-buffer</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>)))
|
||
</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">(defun my/dap-yank-value-at-point (node)
|
||
(interactive (<span style="color:#a6e22e">list</span> (treemacs-node-at-point)))
|
||
(kill-new (<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">plist-get</span> (button-get node :item) :value))))
|
||
</code></pre></div><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">(defun my/dap-display-value (node)
|
||
(interactive (<span style="color:#a6e22e">list</span> (treemacs-node-at-point)))
|
||
(let ((value (<span style="color:#a6e22e">plist-get</span> (button-get node :item) :value)))
|
||
(when value
|
||
(let ((buffer (generate-new-buffer <span style="color:#e6db74">"dap-value"</span>)))
|
||
(with-current-buffer buffer
|
||
(<span style="color:#a6e22e">insert</span> value))
|
||
(<span style="color:#a6e22e">select-window</span> (display-buffer buffer))))))
|
||
</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">(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
(setq my/dap-stack-frame-filters
|
||
<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 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 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>)))))
|
||
|
||
(setq my/dap-stack-frame-current-filter (cdar my/dap-stack-frame-filters))
|
||
|
||
(defun my/dap-stack-frame-filter-set ()
|
||
(interactive)
|
||
(setq my/dap-stack-frame-current-filter
|
||
(<span style="color:#a6e22e">cdr</span>
|
||
(<span style="color:#a6e22e">assoc</span>
|
||
(<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Filter: "</span> my/dap-stack-frame-filters)
|
||
my/dap-stack-frame-filters))))
|
||
|
||
(defun my/dap-stack-frame-filter (frame)
|
||
(when-let (path (dap--get-path-for-frame frame))
|
||
(not (<span style="color:#a6e22e">string-match</span> my/dap-stack-frame-current-filter path)))))
|
||
</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">(defun my/dap-switch-stack-frame ()
|
||
<span style="color:#e6db74">"Switch stackframe by selecting another stackframe stackframes from current thread."</span>
|
||
(interactive)
|
||
(when (not (dap--cur-session))
|
||
(<span style="color:#a6e22e">error</span> <span style="color:#e6db74">"There is no active session"</span>))
|
||
|
||
(-if-let (thread-id (dap--debug-session-thread-id (dap--cur-session)))
|
||
(-if-let (stack-frames
|
||
(<span style="color:#a6e22e">gethash</span>
|
||
thread-id
|
||
(dap--debug-session-thread-stack-frames (dap--cur-session))))
|
||
(let* ((index <span style="color:#ae81ff">0</span>)
|
||
(stack-framces-filtered
|
||
(-filter
|
||
<span style="color:#a6e22e">#'</span>my/dap-stack-frame-filter
|
||
stack-frames))
|
||
(new-stack-frame
|
||
(dap--completing-read
|
||
<span style="color:#e6db74">"Select active frame: "</span>
|
||
stack-framces-filtered
|
||
(-lambda ((frame &as &hash <span style="color:#e6db74">"name"</span>))
|
||
(if-let (frame-path (dap--get-path-for-frame frame))
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s: %s (in %s)"</span>
|
||
(cl-incf index) name frame-path)
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%s: %s"</span> (cl-incf index) name)))
|
||
<span style="color:#66d9ef">nil</span>
|
||
<span style="color:#66d9ef">t</span>)))
|
||
(dap--go-to-stack-frame (dap--cur-session) new-stack-frame))
|
||
(->> (dap--cur-session)
|
||
dap--debug-session-name
|
||
(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Current session %s is not stopped"</span>)
|
||
<span style="color:#a6e22e">error</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)))))
|
||
</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">(with-eval-after-load <span style="color:#e6db74">'dap-mode</span>
|
||
(dap-register-debug-template
|
||
<span style="color:#e6db74">"Node::Nest.js"</span>
|
||
(<span style="color:#a6e22e">list</span> :type <span style="color:#e6db74">"node"</span>
|
||
:request <span style="color:#e6db74">"attach"</span>
|
||
:name <span style="color:#e6db74">"Node::Attach"</span>
|
||
:port <span style="color:#ae81ff">9229</span>
|
||
:outFiles [<span style="color:#e6db74">"${workspaceFolder}/dist/**/*.js"</span>]
|
||
:sourceMaps <span style="color:#66d9ef">t</span>
|
||
:program <span style="color:#e6db74">"${workspaceFolder}/src/app.ts"</span>))
|
||
(dap-register-debug-template
|
||
<span style="color:#e6db74">"Node::Babel"</span>
|
||
(<span style="color:#a6e22e">list</span> :type <span style="color:#e6db74">"node"</span>
|
||
:request <span style="color:#e6db74">"attach"</span>
|
||
:name <span style="color:#e6db74">"Node::Attach"</span>
|
||
:port <span style="color:#ae81ff">9229</span>
|
||
:program <span style="color:#e6db74">"${workspaceFolder}/dist/bin/www.js"</span>)))
|
||
|
||
</code></pre></div><h4 id="off--tabnine"><span class="org-todo done OFF">OFF</span> (OFF) TabNine</h4>
|
||
<p>A ML-based autocompletion system.</p>
|
||
<p>More often than not gives really good results, but is slow as hell & consumes a lot of RAM. Also, LSP-provided completions were more useful in my experience.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://www.tabnine.com/">TabNine Homepage</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package company-tabnine
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/lowpower)
|
||
:after company
|
||
:config
|
||
(add-to-list <span style="color:#e6db74">'company-backends</span> <span style="color:#a6e22e">#'</span>company-tabnine))
|
||
</code></pre></div><h4 id="off--code-compass"><span class="org-todo done OFF">OFF</span> (OFF) Code Compass</h4>
|
||
<p>A set of code analyzing tools.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/ag91/code-compass">code-compass repo</a></li>
|
||
</ul>
|
||
<h5 id="dependencies">Dependencies</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package async
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
(use-package dash
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
(use-package f
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
(use-package s
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
(use-package simple-httpd
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h5 id="plugin">Plugin</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package code-compass
|
||
:straight (
|
||
:repo <span style="color:#e6db74">"ag91/code-compass"</span>
|
||
:files (<span style="color:#e6db74">"code-compass.el"</span>)
|
||
:branch <span style="color:#e6db74">"main"</span>
|
||
))
|
||
</code></pre></div><h4 id="reformatter">Reformatter</h4>
|
||
<p>A general-purpose package to run formattters on files. While the most popular formatters are already packaged for Emacs, those that aren’t can be invoked with this package.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package reformatter
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="general-additional-config">General additional config</h4>
|
||
<p>Make smartparens behave the way I like for C-like languages.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-smartparens-indent (mode)
|
||
(sp-local-pair mode <span style="color:#e6db74">"{"</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>)))
|
||
(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>)))
|
||
(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>))))
|
||
</code></pre></div><p>Override flycheck checker with eslint.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-flycheck-eslint()
|
||
<span style="color:#e6db74">"Override flycheck checker with eslint."</span>
|
||
(setq-local lsp-diagnostic-package :none)
|
||
(setq-local flycheck-checker <span style="color:#e6db74">'javascript-eslint</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">(use-package emmet-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:hook ((vue-html-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
(svelte-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
(web-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
(html-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
(css-mode <span style="color:#f92672">.</span> emmet-mode)
|
||
(scss-mode <span style="color:#f92672">.</span> emmet-mode))
|
||
:config
|
||
<span style="color:#75715e">;; (setq emmet-indent-after-insert nil)</span>
|
||
(setq my/emmet-mmm-submodes <span style="color:#f92672">'</span>(vue-html-mode css-mode))
|
||
(defun my/emmet-or-tab (<span style="color:#66d9ef">&optional</span> arg)
|
||
(interactive)
|
||
(if (and
|
||
(<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'mmm-current-submode</span>)
|
||
mmm-current-submode
|
||
(not (<span style="color:#a6e22e">member</span> mmm-current-submode my/emmet-mmm-submodes)))
|
||
(indent-for-tab-command arg)
|
||
(or (emmet-expand-line arg)
|
||
(emmet-go-to-edit-point <span style="color:#ae81ff">1</span>)
|
||
(indent-for-tab-command arg))))
|
||
(general-imap :keymaps <span style="color:#e6db74">'emmet-mode-keymap</span>
|
||
<span style="color:#e6db74">"TAB"</span> <span style="color:#e6db74">'my/emmet-or-tab</span>
|
||
<span style="color:#e6db74">"<backtab>"</span> <span style="color:#e6db74">'emmet-prev-edit-point</span>))
|
||
</code></pre></div><h4 id="prettier">Prettier</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package prettier
|
||
:commands (prettier-prettify)
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:init
|
||
(my-leader-def
|
||
:keymaps <span style="color:#f92672">'</span>(js-mode-map web-mode-map typescript-mode-map vue-mode-map svelte-mode-map)
|
||
<span style="color:#e6db74">"rr"</span> <span style="color:#a6e22e">#'</span>prettier-prettify))
|
||
</code></pre></div><h4 id="typescript">TypeScript</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package typescript-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.ts\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>rainbow-delimiters-mode)
|
||
(add-hook <span style="color:#e6db74">'typescript-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'typescript-mode</span>))
|
||
</code></pre></div><h4 id="javascript">JavaScript</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'js-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'js-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'js-mode</span>)
|
||
</code></pre></div><h4 id="jest">Jest</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package jest-test-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:hook ((typescript-mode <span style="color:#f92672">.</span> jest-test-mode)
|
||
(js-mode <span style="color:#f92672">.</span> jest-test-mode))
|
||
:config
|
||
(my-leader-def
|
||
:keymaps <span style="color:#e6db74">'jest-test-mode-map</span>
|
||
:infix <span style="color:#e6db74">"t"</span>
|
||
<span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'jest-test-run-at-point</span>
|
||
<span style="color:#e6db74">"r"</span> <span style="color:#e6db74">'jest-test-run</span>
|
||
<span style="color:#e6db74">"a"</span> <span style="color:#e6db74">'jest-test-run-all-tests</span>))
|
||
</code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/jest-test-run-at-point-copy ()
|
||
<span style="color:#e6db74">"Run the top level describe block of the current buffer's point."</span>
|
||
(interactive)
|
||
(let ((filename (jest-test-find-file))
|
||
(example (jest-test-example-at-point)))
|
||
(if (and filename example)
|
||
(jest-test-from-project-directory filename
|
||
(let ((jest-test-options (seq-concatenate <span style="color:#e6db74">'list</span> jest-test-options (<span style="color:#a6e22e">list</span> <span style="color:#e6db74">"-t"</span> example))))
|
||
(kill-new (jest-test-command filename))))
|
||
(<span style="color:#a6e22e">message</span> jest-test-not-found-message))))
|
||
</code></pre></div><h4 id="web-mode">web-mode</h4>
|
||
<p><a href="https://web-mode.org/">web-mode.el</a> is a major mode to edit various web templates.</p>
|
||
<p>Trying this one out instead of vue-mode and svelte-mode, because this one seems to have better support for tree-sitter and generally less problems.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package web-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:init
|
||
(add-to-list <span style="color:#e6db74">'auto-mode-alist</span> <span style="color:#f92672">'</span>(<span style="color:#e6db74">"\\.svelte\\'"</span> <span style="color:#f92672">.</span> web-mode))
|
||
(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))
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'hs-minor-mode</span>)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'web-mode</span>))
|
||
</code></pre></div><p>Hooking this up with lsp.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/web-mode-lsp-extensions
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">".svelte"</span> eos)
|
||
<span style="color:#f92672">,</span>(rx <span style="color:#e6db74">".vue"</span> eos)))
|
||
|
||
(defun my/web-mode-lsp ()
|
||
(when (seq-some
|
||
(lambda (regex) (string-match-p regex (<span style="color:#a6e22e">buffer-name</span>)))
|
||
my/web-mode-lsp-extensions)
|
||
(lsp-deferred)))
|
||
|
||
(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#a6e22e">#'</span>my/web-mode-lsp)
|
||
</code></pre></div><p>Vue settings</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/web-mode-vue-setup ()
|
||
(when (string-match-p (rx <span style="color:#e6db74">".vue"</span> eos) (<span style="color:#a6e22e">buffer-name</span>))
|
||
(setq-local web-mode-script-padding <span style="color:#ae81ff">0</span>)))
|
||
|
||
(add-hook <span style="color:#e6db74">'web-mode-hook</span> <span style="color:#e6db74">'my/web-mode-vue-setup</span>)
|
||
</code></pre></div><h4 id="off--vue-dot-js"><span class="org-todo done OFF">OFF</span> (OFF) Vue.js</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package vue-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:disabled
|
||
:mode <span style="color:#e6db74">"\\.vue\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'vue-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(add-hook <span style="color:#e6db74">'vue-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'vue-mode</span>)
|
||
(add-hook <span style="color:#e6db74">'vue-mode-hook</span> (lambda () (set-face-background <span style="color:#e6db74">'mmm-default-submode-face</span> <span style="color:#66d9ef">nil</span>)))
|
||
<<override-mmm-mode-func>>)
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'editorconfig</span>
|
||
(add-to-list <span style="color:#e6db74">'editorconfig-indentation-alist</span>
|
||
<span style="color:#f92672">'</span>(vue-mode css-indent-offset
|
||
js-indent-level
|
||
sgml-basic-offset
|
||
ssass-tab-width
|
||
typescript-indent-level
|
||
emmet-indentation
|
||
vue-html-extra-indent)))
|
||
</code></pre></div><h5 id="mmm-mode-fix">mmm-mode fix</h5>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/purcell/mmm-mode/issues/112">mmm-mode issue</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun mmm-syntax-propertize-function (start stop)
|
||
(let ((saved-mode mmm-current-submode)
|
||
(saved-ovl mmm-current-overlay))
|
||
(mmm-save-changed-local-variables
|
||
mmm-current-submode mmm-current-overlay)
|
||
(unwind-protect
|
||
(<span style="color:#a6e22e">mapc</span> (lambda (<span style="color:#a6e22e">elt</span>)
|
||
(let* ((mode (<span style="color:#a6e22e">car</span> <span style="color:#a6e22e">elt</span>))
|
||
(func (<span style="color:#a6e22e">get</span> mode <span style="color:#e6db74">'mmm-syntax-propertize-function</span>))
|
||
(beg (cadr <span style="color:#a6e22e">elt</span>)) (end (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> <span style="color:#a6e22e">elt</span>))
|
||
(ovl (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">3</span> <span style="color:#a6e22e">elt</span>))
|
||
syntax-ppss-cache
|
||
syntax-ppss-last)
|
||
(<span style="color:#a6e22e">goto-char</span> beg)
|
||
(mmm-set-current-pair mode ovl)
|
||
(mmm-set-local-variables mode mmm-current-overlay)
|
||
(save-restriction
|
||
(if mmm-current-overlay
|
||
(<span style="color:#a6e22e">narrow-to-region</span> (<span style="color:#a6e22e">overlay-start</span> mmm-current-overlay)
|
||
(<span style="color:#a6e22e">overlay-end</span> mmm-current-overlay))
|
||
(<span style="color:#a6e22e">narrow-to-region</span> beg end))
|
||
(cond
|
||
(func
|
||
(<span style="color:#a6e22e">funcall</span> func beg end))
|
||
(font-lock-syntactic-keywords
|
||
(let ((syntax-propertize-function <span style="color:#66d9ef">nil</span>))
|
||
(font-lock-fontify-syntactic-keywords-region beg end))))
|
||
(<span style="color:#a6e22e">run-hook-with-args</span> <span style="color:#e6db74">'mmm-after-syntax-propertize-functions</span>
|
||
mmm-current-overlay mode beg end))))
|
||
(mmm-regions-in start stop))
|
||
(mmm-set-current-pair saved-mode saved-ovl)
|
||
(mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl))))
|
||
</code></pre></div><h4 id="off--svelte"><span class="org-todo done OFF">OFF</span> (OFF) Svelte</h4>
|
||
<p>Had some problems with this and tree-sitter. Web-mode seems to be doing better.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package svelte-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.svelte\\'"</span>
|
||
:disabled
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'svelte-mode-hook</span> <span style="color:#e6db74">'my/set-flycheck-eslint</span>)
|
||
(add-hook <span style="color:#e6db74">'svelte-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'svelte-mode</span>)
|
||
<span style="color:#75715e">;; I have my own Emmet</span>
|
||
(setq lsp-svelte-plugin-css-completions-emmet <span style="color:#66d9ef">nil</span>)
|
||
(setq lsp-svelte-plugin-html-completions-emmet <span style="color:#66d9ef">nil</span>))
|
||
</code></pre></div><h4 id="scss">SCSS</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'scss-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'scss-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'scss-mode</span>)
|
||
</code></pre></div><h4 id="php">PHP</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package php-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.php\\'"</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">(use-package tex
|
||
:straight auctex
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(setq-default TeX-auto-save <span style="color:#66d9ef">t</span>)
|
||
(setq-default TeX-parse-self <span style="color:#66d9ef">t</span>)
|
||
(TeX-PDF-mode)
|
||
<span style="color:#75715e">;; Use XeLaTeX & stuff</span>
|
||
(setq-default TeX-engine <span style="color:#e6db74">'xetex</span>)
|
||
(setq-default TeX-command-extra-options <span style="color:#e6db74">"-shell-escape"</span>)
|
||
(setq-default TeX-source-correlate-method <span style="color:#e6db74">'synctex</span>)
|
||
(TeX-source-correlate-mode)
|
||
(setq-default TeX-source-correlate-start-server <span style="color:#66d9ef">t</span>)
|
||
(setq-default LaTeX-math-menu-unicode <span style="color:#66d9ef">t</span>)
|
||
|
||
(setq-default font-latex-fontify-sectioning <span style="color:#ae81ff">1.3</span>)
|
||
|
||
<span style="color:#75715e">;; Scale preview for my DPI</span>
|
||
(setq-default preview-scale-function <span style="color:#ae81ff">1.4</span>)
|
||
(when (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'tex--prettify-symbols-alist</span>)
|
||
(assoc-delete-all <span style="color:#e6db74">"--"</span> tex--prettify-symbols-alist)
|
||
(assoc-delete-all <span style="color:#e6db74">"---"</span> tex--prettify-symbols-alist))
|
||
|
||
(add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span>
|
||
(lambda ()
|
||
(TeX-fold-mode <span style="color:#ae81ff">1</span>)
|
||
(outline-minor-mode)))
|
||
|
||
(add-to-list <span style="color:#e6db74">'TeX-view-program-selection</span>
|
||
<span style="color:#f92672">'</span>(output-pdf <span style="color:#e6db74">"Zathura"</span>))
|
||
|
||
<span style="color:#75715e">;; Do not run lsp within templated TeX files</span>
|
||
(add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span>
|
||
(lambda ()
|
||
(unless (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"\.hogan\.tex$"</span> (<span style="color:#a6e22e">buffer-name</span>))
|
||
(lsp))
|
||
(setq-local lsp-diagnostic-package :none)
|
||
(setq-local flycheck-checker <span style="color:#e6db74">'tex-chktex</span>)))
|
||
|
||
(add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>rainbow-delimiters-mode)
|
||
(add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'LaTeX-mode-hook</span> <span style="color:#a6e22e">#'</span>prettify-symbols-mode)
|
||
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'LaTeX-mode</span>)
|
||
(require <span style="color:#e6db74">'smartparens-latex</span>)
|
||
|
||
(general-nmap
|
||
:keymaps <span style="color:#f92672">'</span>(LaTeX-mode-map latex-mode-map)
|
||
<span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'TeX-command-run-all</span>
|
||
<span style="color:#e6db74">"C-c t"</span> <span style="color:#e6db74">'orgtbl-mode</span>)
|
||
|
||
<<init-greek-latex-snippets>>
|
||
<<init-english-latex-snippets>>
|
||
<<init-math-latex-snippets>>
|
||
<<init-section-latex-snippets>>)
|
||
</code></pre></div><h4 id="bibtex">BibTeX</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package ivy-bibtex
|
||
:commands (ivy-bibtex)
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"fB"</span> <span style="color:#e6db74">'ivy-bibtex</span>))
|
||
|
||
(add-hook <span style="color:#e6db74">'bibtex-mode</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
</code></pre></div><h4 id="import-dot-sty">Import *.sty</h4>
|
||
<p>A function to import <code>.sty</code> files to the LaTeX document.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/list-sty ()
|
||
(<span style="color:#a6e22e">reverse</span>
|
||
(<span style="color:#a6e22e">sort</span>
|
||
(seq-filter
|
||
(lambda (file) (if (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">".*\.sty$"</span> file) <span style="color:#ae81ff">1</span> <span style="color:#66d9ef">nil</span>))
|
||
(<span style="color:#a6e22e">directory-files</span>
|
||
(seq-some
|
||
(lambda (dir)
|
||
(if (and
|
||
(f-directory-p dir)
|
||
(seq-some
|
||
(lambda (file) (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">".*\.sty$"</span> file))
|
||
(<span style="color:#a6e22e">directory-files</span> dir))
|
||
) dir <span style="color:#66d9ef">nil</span>))
|
||
(<span style="color:#a6e22e">list</span> <span style="color:#e6db74">"./styles"</span> <span style="color:#e6db74">"../styles/"</span> <span style="color:#e6db74">"."</span> <span style="color:#e6db74">".."</span>)) :full))
|
||
(lambda (f1 f2)
|
||
(let ((f1b (file-name-base f1))
|
||
(f1b (file-name-base f2)))
|
||
(cond
|
||
((string-match-p <span style="color:#e6db74">".*BibTex"</span> f1) <span style="color:#66d9ef">t</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>)
|
||
((string-match-p <span style="color:#e6db74">".*Preamble"</span> f2) <span style="color:#66d9ef">t</span>)
|
||
(<span style="color:#66d9ef">t</span> (<span style="color:#a6e22e">string-lessp</span> f1 f2))))))))
|
||
|
||
(defun my/import-sty ()
|
||
(interactive)
|
||
(<span style="color:#a6e22e">insert</span>
|
||
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'concat</span>
|
||
(cl-mapcar
|
||
(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>))
|
||
(my/list-sty)))))
|
||
|
||
(defun my/import-sty-org ()
|
||
(interactive)
|
||
(<span style="color:#a6e22e">insert</span>
|
||
(<span style="color:#a6e22e">apply</span> <span style="color:#a6e22e">#'concat</span>
|
||
(cl-mapcar
|
||
(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>))
|
||
(my/list-sty)))))
|
||
</code></pre></div><h4 id="snippets">Snippets</h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Note</th>
|
||
<th>Type</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>TODO</td>
|
||
<td>Move yasnippet snippets here? Maybe extract to a separate file?</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h5 id="greek-letters">Greek letters</h5>
|
||
<p>Autogenerate snippets for greek letters. I have a few blocks like this because it’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">(setq my/greek-alphabet
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"a"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\alpha"</span>)
|
||
(<span style="color:#e6db74">"b"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\beta"</span> )
|
||
(<span style="color:#e6db74">"g"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\gamma"</span>)
|
||
(<span style="color:#e6db74">"d"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\delta"</span>)
|
||
(<span style="color:#e6db74">"e"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\epsilon"</span>)
|
||
(<span style="color:#e6db74">"z"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\zeta"</span>)
|
||
(<span style="color:#e6db74">"h"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\eta"</span>)
|
||
(<span style="color:#e6db74">"o"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\theta"</span>)
|
||
(<span style="color:#e6db74">"i"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\iota"</span>)
|
||
(<span style="color:#e6db74">"k"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\kappa"</span>)
|
||
(<span style="color:#e6db74">"l"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\lambda"</span>)
|
||
(<span style="color:#e6db74">"m"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\mu"</span>)
|
||
(<span style="color:#e6db74">"n"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\nu"</span>)
|
||
(<span style="color:#e6db74">"x"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\xi"</span>)
|
||
(<span style="color:#e6db74">"p"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\pi"</span>)
|
||
(<span style="color:#e6db74">"r"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\rho"</span>)
|
||
(<span style="color:#e6db74">"s"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sigma"</span>)
|
||
(<span style="color:#e6db74">"t"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\tau"</span>)
|
||
(<span style="color:#e6db74">"u"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\upsilon"</span>)
|
||
(<span style="color:#e6db74">"f"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\phi"</span>)
|
||
(<span style="color:#e6db74">"c"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\chi"</span>)
|
||
(<span style="color:#e6db74">"v"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\psi"</span>)
|
||
(<span style="color:#e6db74">"g"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\omega"</span>)))
|
||
|
||
(setq my/latex-greek-prefix <span style="color:#e6db74">"'"</span>)
|
||
|
||
<span style="color:#75715e">;; The same for capitalized letters</span>
|
||
(dolist (elem my/greek-alphabet)
|
||
(let ((key (<span style="color:#a6e22e">car</span> elem))
|
||
(value (<span style="color:#a6e22e">cdr</span> elem)))
|
||
(when (<span style="color:#a6e22e">string-equal</span> key (<span style="color:#a6e22e">downcase</span> key))
|
||
(add-to-list <span style="color:#e6db74">'my/greek-alphabet</span>
|
||
(<span style="color:#a6e22e">cons</span>
|
||
(<span style="color:#a6e22e">capitalize</span> (<span style="color:#a6e22e">car</span> elem))
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> <span style="color:#ae81ff">1</span>)
|
||
(<span style="color:#a6e22e">capitalize</span> (<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">2</span>))
|
||
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">2</span>)))))))
|
||
|
||
(yas-define-snippets
|
||
<span style="color:#e6db74">'latex-mode</span>
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (elem)
|
||
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-greek-prefix (<span style="color:#a6e22e">car</span> elem)) (<span style="color:#a6e22e">cdr</span> elem) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Greek letter "</span> (<span style="color:#a6e22e">car</span> elem))))
|
||
my/greek-alphabet))
|
||
</code></pre></div><h5 id="english-letters">English letters</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/english-alphabet
|
||
<span style="color:#f92672">'</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>))
|
||
|
||
(dolist (elem my/english-alphabet)
|
||
(when (<span style="color:#a6e22e">string-equal</span> elem (<span style="color:#a6e22e">downcase</span> elem))
|
||
(add-to-list <span style="color:#e6db74">'my/english-alphabet</span> (<span style="color:#a6e22e">upcase</span> elem))))
|
||
|
||
(setq my/latex-mathbb-prefix <span style="color:#e6db74">"`"</span>)
|
||
|
||
(yas-define-snippets
|
||
<span style="color:#e6db74">'latex-mode</span>
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (elem)
|
||
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-mathbb-prefix elem) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"\\mathbb{"</span> elem <span style="color:#e6db74">"}"</span>) (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Mathbb letter "</span> elem)))
|
||
my/english-alphabet))
|
||
</code></pre></div><h5 id="math-symbols">Math symbols</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-math-symbols
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"x"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\times"</span>)
|
||
(<span style="color:#e6db74">"."</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cdot"</span>)
|
||
(<span style="color:#e6db74">"v"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\forall"</span>)
|
||
(<span style="color:#e6db74">"s"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sum_{$1}^{$2}$0"</span>)
|
||
(<span style="color:#e6db74">"p"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\prod_{$1}^{$2}$0"</span>)
|
||
(<span style="color:#e6db74">"d"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\partial"</span>)
|
||
(<span style="color:#e6db74">"e"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\exists"</span>)
|
||
(<span style="color:#e6db74">"i"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\int_{$1}^{$2}$0"</span>)
|
||
(<span style="color:#e6db74">"c"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cap"</span>)
|
||
(<span style="color:#e6db74">"u"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\cup"</span>)
|
||
(<span style="color:#e6db74">"0"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\emptyset"</span>)
|
||
(<span style="color:#e6db74">"^"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\widehat{$1}$0"</span>)
|
||
(<span style="color:#e6db74">"_"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\overline{$1}$0"</span>)
|
||
(<span style="color:#e6db74">"~"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\sim"</span>)
|
||
(<span style="color:#e6db74">"|"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\mid"</span>)
|
||
(<span style="color:#e6db74">"_|"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\perp"</span>)))
|
||
|
||
(setq my/latex-math-prefix <span style="color:#e6db74">";"</span>)
|
||
|
||
(yas-define-snippets
|
||
<span style="color:#e6db74">'latex-mode</span>
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (elem)
|
||
(let ((key (<span style="color:#a6e22e">car</span> elem))
|
||
(value (<span style="color:#a6e22e">cdr</span> elem)))
|
||
(<span style="color:#a6e22e">list</span> (<span style="color:#a6e22e">concat</span> my/latex-math-prefix key) value (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"Math symbol "</span> value))))
|
||
my/latex-math-symbols))
|
||
</code></pre></div><h5 id="section-snippets">Section snippets</h5>
|
||
<p>Section snippets. The code turned out to be more complicated than just writing the snippets by hand.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/latex-section-snippets
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"ch"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\chapter{$1}"</span>)
|
||
(<span style="color:#e6db74">"sec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\section{$1}"</span>)
|
||
(<span style="color:#e6db74">"ssec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsection{$1}"</span>)
|
||
(<span style="color:#e6db74">"sssec"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\subsubsection{$1}"</span>)
|
||
(<span style="color:#e6db74">"par"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"\\paragraph{$1}}"</span>)))
|
||
|
||
(setq my/latex-section-snippets
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (elem)
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">car</span> elem)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">cdr</span> elem)
|
||
<span style="color:#f92672">,</span>(progn
|
||
(<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"[a-z]+"</span> (<span style="color:#a6e22e">cdr</span> elem))
|
||
(match-string <span style="color:#ae81ff">0</span> (<span style="color:#a6e22e">cdr</span> elem)))))
|
||
my/latex-section-snippets))
|
||
|
||
(dolist (elem my/latex-section-snippets)
|
||
(let* ((key (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">0</span> elem))
|
||
(value (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem))
|
||
(desc (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">2</span> elem))
|
||
(star-index (<span style="color:#a6e22e">string-match</span> <span style="color:#e6db74">"\{\$1\}"</span> value)))
|
||
(add-to-list <span style="color:#e6db74">'my/latex-section-snippets</span>
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">"*"</span>)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">substring</span> value <span style="color:#ae81ff">0</span> star-index)
|
||
<span style="color:#e6db74">"*"</span>
|
||
(<span style="color:#a6e22e">substring</span> value star-index))
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">" with *"</span>)))
|
||
(add-to-list <span style="color:#e6db74">'my/latex-section-snippets</span>
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> key <span style="color:#e6db74">"l"</span>)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> value <span style="color:#e6db74">"%\n\\label{sec:$2}"</span>)
|
||
<span style="color:#f92672">,</span>(<span style="color:#a6e22e">concat</span> desc <span style="color:#e6db74">" with label"</span>)))))
|
||
|
||
(dolist (elem my/latex-section-snippets)
|
||
(setf (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem) (<span style="color:#a6e22e">concat</span> (<span style="color:#a6e22e">nth</span> <span style="color:#ae81ff">1</span> elem) <span style="color:#e6db74">"\n$0"</span>)))
|
||
|
||
(yas-define-snippets
|
||
<span style="color:#e6db74">'latex-mode</span>
|
||
my/latex-section-snippets)
|
||
</code></pre></div><h3 id="other-markup-languages">Other markup languages</h3>
|
||
<h4 id="markdown">Markdown</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package markdown-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.md\\'"</span>
|
||
:config
|
||
(setq markdown-command
|
||
(<span style="color:#a6e22e">concat</span>
|
||
<span style="color:#e6db74">"pandoc"</span>
|
||
<span style="color:#e6db74">" --from=markdown --to=html"</span>
|
||
<span style="color:#e6db74">" --standalone --mathjax --highlight-style=pygments"</span>
|
||
<span style="color:#e6db74">" --css=pandoc.css"</span>
|
||
<span style="color:#e6db74">" --quiet"</span>
|
||
))
|
||
(setq markdown-live-preview-delete-export <span style="color:#e6db74">'delete-on-export</span>)
|
||
(setq markdown-asymmetric-header <span style="color:#66d9ef">t</span>)
|
||
(setq markdown-open-command <span style="color:#e6db74">"/home/pavel/bin/scripts/chromium-sep"</span>)
|
||
(add-hook <span style="color:#e6db74">'markdown-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'markdown-mode-map</span>
|
||
<span style="color:#e6db74">"M-<left>"</span> <span style="color:#e6db74">'markdown-promote</span>
|
||
<span style="color:#e6db74">"M-<right>"</span> <span style="color:#e6db74">'markdown-demote</span>))
|
||
|
||
<span style="color:#75715e">;; (use-package livedown</span>
|
||
<span style="color:#75715e">;; :straight (:host github :repo "shime/emacs-livedown")</span>
|
||
<span style="color:#75715e">;; :commands livedown-preview</span>
|
||
<span style="color:#75715e">;; :config</span>
|
||
<span style="color:#75715e">;; (setq livedown-browser "qutebrowser"))</span>
|
||
|
||
</code></pre></div><h4 id="plantuml">PlantUML</h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>plantuml</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package plantuml-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"(\\.\\(plantuml?\\|uml\\|puml\\)\\'"</span>
|
||
:config
|
||
(setq plantuml-executable-path <span style="color:#e6db74">"/home/pavel/.guix-extra-profiles/emacs/emacs/bin/plantuml"</span>)
|
||
(setq plantuml-default-exec-mode <span style="color:#e6db74">'executable</span>)
|
||
(setq plantuml-indent-level <span style="color:#ae81ff">2</span>)
|
||
(setq my/plantuml-indent-regexp-return <span style="color:#e6db74">"^\s*return\s+.+$"</span>)
|
||
(add-to-list
|
||
<span style="color:#e6db74">'plantuml-indent-regexp-end</span>
|
||
my/plantuml-indent-regexp-return)
|
||
(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))
|
||
(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))
|
||
(add-hook <span style="color:#e6db74">'plantuml-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
|
||
(general-nmap
|
||
:keymaps <span style="color:#e6db74">'plantuml-mode-map</span>
|
||
<span style="color:#e6db74">"RET"</span> <span style="color:#e6db74">'plantuml-preview</span>)
|
||
</code></pre></div><h4 id="languagetool">LanguageTool</h4>
|
||
<p>LanguageTool is a great offline spell checker. For some reason, the download link is nowhere to be found on the home page, so it is listed in the references as well.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://languagetool.org/">LanguageTool homepage</a></li>
|
||
<li><a href="https://dev.languagetool.org/http-server">LanguageTool http server</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package langtool
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (langtool-check)
|
||
:config
|
||
(setq langtool-language-tool-server-jar <span style="color:#e6db74">"/home/pavel/bin/LanguageTool-5.4/languagetool-server.jar"</span>)
|
||
(setq langtool-mother-tongue <span style="color:#e6db74">"ru"</span>)
|
||
(setq langtool-default-language <span style="color:#e6db74">"en-US"</span>))
|
||
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"L"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"languagetool"</span>)
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'langtool-check</span>
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'langtool-server-stop</span>
|
||
<span style="color:#e6db74">"d"</span> <span style="color:#e6db74">'langtool-check-done</span>
|
||
<span style="color:#e6db74">"n"</span> <span style="color:#e6db74">'langtool-goto-next-error</span>
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'langtool-goto-previous-error</span>
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'langtool-correct-buffer</span>)
|
||
</code></pre></div><h3 id="lisp">Lisp</h3>
|
||
<p>These are your father’s parentheses. Elegant weapons for a more… civilized age.</p>
|
||
<h4 id="meta-lisp">Meta Lisp</h4>
|
||
<p>Some packages for editing various Lisps.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lispy
|
||
:commands (lispy-mode)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(use-package lispyville
|
||
:hook (lispy-mode <span style="color:#f92672">.</span> lispyville-mode)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
|
||
(sp-with-modes sp-lisp-modes
|
||
(sp-local-pair <span style="color:#e6db74">"'"</span> <span style="color:#66d9ef">nil</span> :actions <span style="color:#66d9ef">nil</span>))
|
||
</code></pre></div><h4 id="emacs-lisp">Emacs Lisp</h4>
|
||
<h5 id="package-lint">Package Lint</h5>
|
||
<p>A package that checks for the metadata in Emacs Lisp packages.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package flycheck-package
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after flycheck
|
||
:config
|
||
(flycheck-package-setup))
|
||
</code></pre></div><h5 id="general-settings">General settings</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
<span style="color:#75715e">;; (add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode)</span>
|
||
(add-hook <span style="color:#e6db74">'emacs-lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</code></pre></div><h4 id="common-lisp">Common lisp</h4>
|
||
<h5 id="slime">SLIME</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package slime
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(setq inferior-lisp-program <span style="color:#e6db74">"sbcl"</span>)
|
||
(add-hook <span style="color:#e6db74">'slime-repl-mode</span> <span style="color:#e6db74">'smartparens-mode</span>))
|
||
</code></pre></div><h5 id="general-settings">General settings</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
<span style="color:#75715e">;; (add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode)</span>
|
||
(add-hook <span style="color:#e6db74">'lisp-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</code></pre></div><h4 id="clojure">Clojure</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package clojure-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.clj[sc]?\\'"</span>
|
||
:config
|
||
<span style="color:#75715e">;; (add-hook 'clojure-mode-hook #'smartparens-strict-mode)</span>
|
||
(add-hook <span style="color:#e6db74">'clojure-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
(add-hook <span style="color:#e6db74">'clojure-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode))
|
||
|
||
(use-package cider
|
||
:mode <span style="color:#e6db74">"\\.clj[sc]?\\'"</span>
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h4 id="hy">Hy</h4>
|
||
<p>Python requirements:</p>
|
||
<ul>
|
||
<li><code>hy</code></li>
|
||
<li><code>jedhy</code></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package hy-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.hy\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'hy-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
(add-hook <span style="color:#e6db74">'hy-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode))
|
||
</code></pre></div><h4 id="scheme">Scheme</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package geiser
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/lowpower)
|
||
:config
|
||
(setq geiser-default-implementation <span style="color:#e6db74">'guile</span>))
|
||
|
||
(use-package geiser-guile
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after geiser)
|
||
|
||
(add-hook <span style="color:#e6db74">'scheme-mode-hook</span> <span style="color:#a6e22e">#'</span>aggressive-indent-mode)
|
||
(add-hook <span style="color:#e6db74">'scheme-mode-hook</span> <span style="color:#a6e22e">#'</span>lispy-mode)
|
||
</code></pre></div><h4 id="clips">CLIPS</h4>
|
||
<p>An honorary Lisp</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package clips-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.cl\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'clips-mode</span> <span style="color:#e6db74">'lispy-mode</span>))
|
||
</code></pre></div><h3 id="python">Python</h3>
|
||
<p>Use <a href="https://github.com/Microsoft/python-language-server">Microsoft Language Server for Python</a>.</p>
|
||
<p>For some reason it doesn’t use pipenv python executable, so here is a small workaround.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/pipenv-python-alist <span style="color:#f92672">'</span>())
|
||
|
||
(defun my/get-pipenv-python ()
|
||
(let ((default-directory (projectile-project-root)))
|
||
(if (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">"Pipfile"</span>)
|
||
(let ((asc (<span style="color:#a6e22e">assoc</span> default-directory my/pipenv-python-alist)))
|
||
(if asc
|
||
(<span style="color:#a6e22e">cdr</span> asc)
|
||
(let ((python-executable
|
||
(string-trim (shell-command-to-string <span style="color:#e6db74">"PIPENV_IGNORE_VIRTUALENVS=1 pipenv run which python 2>/dev/null"</span>))))
|
||
(if (string-match-p <span style="color:#e6db74">".*not found.*"</span> python-executable)
|
||
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"Pipfile found, but not pipenv executable!"</span>)
|
||
(<span style="color:#a6e22e">message</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"Found pipenv python: %s"</span> python-executable))
|
||
(add-to-list <span style="color:#e6db74">'my/pipenv-python-alist</span> (<span style="color:#a6e22e">cons</span> default-directory python-executable))
|
||
python-executable))))
|
||
<span style="color:#e6db74">"python"</span>)))
|
||
|
||
(use-package lsp-pyright
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:defer <span style="color:#66d9ef">t</span>
|
||
:if (not my/slow-ssh)
|
||
:hook (python-mode <span style="color:#f92672">.</span> (lambda ()
|
||
(require <span style="color:#e6db74">'lsp-pyright</span>)
|
||
(setq-local lsp-pyright-python-executable-cmd (my/get-pipenv-python))
|
||
(lsp))))
|
||
|
||
(add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
</code></pre></div><h4 id="pipenv">pipenv</h4>
|
||
<p><a href="https://github.com/pypa/pipenv">Pipenv</a> is a package manager for Python.</p>
|
||
<p>Automatically creates & 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">(use-package pipenv
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:hook (python-mode <span style="color:#f92672">.</span> pipenv-mode)
|
||
:if (not my/slow-ssh)
|
||
:init
|
||
(setq
|
||
pipenv-projectile-after-switch-function
|
||
<span style="color:#a6e22e">#'</span>pipenv-projectile-after-switch-extended))
|
||
</code></pre></div><h4 id="yapf">yapf</h4>
|
||
<p><a href="https://github.com/google/yapf">yapf</a> is a formatter for Python files.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>python-yapf</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/google/yapf">yapf repo</a></li>
|
||
<li><a href="https://github.com/JorisE/yapfify">yapfify.el repo</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yapfify
|
||
:straight (:repo <span style="color:#e6db74">"JorisE/yapfify"</span> :host github)
|
||
:commands (yapfify-region
|
||
yapfify-buffer
|
||
yapfify-region-or-buffer
|
||
yapf-mode))
|
||
</code></pre></div><p>Global config:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ini" data-lang="ini"><span style="color:#66d9ef">[style]</span>
|
||
<span style="color:#a6e22e">based_on_style</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">facebook</span>
|
||
<span style="color:#a6e22e">column_limit</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">80</span>
|
||
</code></pre></div><h4 id="isort">isort</h4>
|
||
<p><a href="https://github.com/PyCQA/isort">isort</a> is a Python package to sort Python imports.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>python-isort</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://pycqa.github.io/isort/">isort docs</a></li>
|
||
<li><a href="https://github.com/paetzke/py-isort.el">py-isort.el repo</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package py-isort
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (py-isort-buffer py-isort-region))
|
||
</code></pre></div><p>The following bindings calls yapf & isort on the buffer</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def
|
||
:keymaps <span style="color:#e6db74">'python-mode-map</span>
|
||
<span style="color:#e6db74">"rr"</span> (lambda ()
|
||
(interactive)
|
||
(unless (and (<span style="color:#a6e22e">fboundp</span> <span style="color:#a6e22e">#'</span>org-src-edit-buffer-p) (org-src-edit-buffer-p))
|
||
(py-isort-buffer))
|
||
(yapfify-buffer)))
|
||
</code></pre></div><h4 id="sphinx-doc">sphinx-doc</h4>
|
||
<p>A package to generate sphinx-compatible docstrings.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package sphinx-doc
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:hook (python-mode <span style="color:#f92672">.</span> sphinx-doc-mode)
|
||
:config
|
||
(my-leader-def
|
||
:keymaps <span style="color:#e6db74">'sphinx-doc-mode-map</span>
|
||
<span style="color:#e6db74">"rd"</span> <span style="color:#e6db74">'sphinx-doc</span>))
|
||
</code></pre></div><h4 id="pytest">pytest</h4>
|
||
<p><a href="https://docs.pytest.org/en/6.2.x/">pytest</a> is an unit testing framework for Python.</p>
|
||
<p>Once again a function to set pytest executable from pipenv.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://docs.pytest.org/en/6.2.x/">pytest docs</a></li>
|
||
<li><a href="https://github.com/wbolster/emacs-python-pytest">emacs-python-pytest</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/set-pipenv-pytest ()
|
||
(setq-local
|
||
python-pytest-executable
|
||
(<span style="color:#a6e22e">concat</span> (my/get-pipenv-python) <span style="color:#e6db74">" -m pytest"</span>)))
|
||
|
||
(use-package python-pytest
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (python-pytest-dispatch)
|
||
:init
|
||
(my-leader-def
|
||
:keymaps <span style="color:#e6db74">'python-mode-map</span>
|
||
:infix <span style="color:#e6db74">"t"</span>
|
||
<span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'python-pytest-dispatch</span>)
|
||
:config
|
||
<<override-pytest-run>>
|
||
(add-hook <span style="color:#e6db74">'python-mode-hook</span> <span style="color:#a6e22e">#'</span>my/set-pipenv-pytest)
|
||
(when (derived-mode-p <span style="color:#e6db74">'python-mode</span>)
|
||
(my/set-pipenv-pytest)))
|
||
</code></pre></div><h5 id="fix-comint-buffer-width">Fix comint buffer width</h5>
|
||
<p>For some reason default comint output width is way too large.</p>
|
||
<p>To fix that, I’ve modified the following function in the <code>python-pytest</code> package.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(cl-defun python-pytest--run-as-comint (<span style="color:#66d9ef">&key</span> command)
|
||
<span style="color:#e6db74">"Run a pytest comint session for COMMAND."</span>
|
||
(let* ((buffer (python-pytest--get-buffer))
|
||
(process (<span style="color:#a6e22e">get-buffer-process</span> buffer)))
|
||
(with-current-buffer buffer
|
||
(when (comint-check-proc buffer)
|
||
(unless (or compilation-always-kill
|
||
(<span style="color:#a6e22e">yes-or-no-p</span> <span style="color:#e6db74">"Kill running pytest process?"</span>))
|
||
(<span style="color:#a6e22e">user-error</span> <span style="color:#e6db74">"Aborting; pytest still running"</span>)))
|
||
(when process
|
||
(<span style="color:#a6e22e">delete-process</span> process))
|
||
(let ((inhibit-read-only <span style="color:#66d9ef">t</span>))
|
||
(<span style="color:#a6e22e">erase-buffer</span>))
|
||
(unless (<span style="color:#a6e22e">eq</span> major-mode <span style="color:#e6db74">'python-pytest-mode</span>)
|
||
(python-pytest-mode))
|
||
(compilation-forget-errors)
|
||
(display-buffer buffer)
|
||
(setq command (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"export COLUMNS=%s; %s"</span>
|
||
(<span style="color:#a6e22e">-</span> (window-width (<span style="color:#a6e22e">get-buffer-window</span> buffer)) <span style="color:#ae81ff">5</span>)
|
||
command))
|
||
(<span style="color:#a6e22e">insert</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"cwd: %s\ncmd: %s\n\n"</span> default-directory command))
|
||
(setq python-pytest--current-command command)
|
||
(when python-pytest-pdb-track
|
||
(add-hook
|
||
<span style="color:#e6db74">'comint-output-filter-functions</span>
|
||
<span style="color:#e6db74">'python-pdbtrack-comint-output-filter-function</span>
|
||
<span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">t</span>))
|
||
(<span style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">'python-pytest-setup-hook</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 style="color:#a6e22e">run-hooks</span> <span style="color:#e6db74">'python-pytest-started-hook</span>)
|
||
(setq process (<span style="color:#a6e22e">get-buffer-process</span> buffer))
|
||
(<span style="color:#a6e22e">set-process-sentinel</span> process <span style="color:#a6e22e">#'</span>python-pytest--process-sentinel))))
|
||
</code></pre></div><h4 id="code-cells">code-cells</h4>
|
||
<p>Support for text with magic comments.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package code-cells
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (code-cells-mode))
|
||
</code></pre></div><h4 id="tensorboard">tensorboard</h4>
|
||
<p>A function to start up <a href="https://www.tensorflow.org/tensorboard">TensorBoard</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/tensorboard-buffer <span style="color:#e6db74">"TensorBoard-out"</span>)
|
||
|
||
(defun my/tensorboard ()
|
||
(interactive)
|
||
(<span style="color:#a6e22e">start-process</span>
|
||
<span style="color:#e6db74">"tensorboard"</span>
|
||
my/tensorboard-buffer
|
||
<span style="color:#e6db74">"tensorboard"</span>
|
||
<span style="color:#e6db74">"serve"</span>
|
||
<span style="color:#e6db74">"--logdir"</span>
|
||
(<span style="color:#a6e22e">car</span> (find-file-read-args <span style="color:#e6db74">"Directory: "</span> <span style="color:#66d9ef">t</span>)))
|
||
(display-buffer my/tensorboard-buffer))
|
||
</code></pre></div><h3 id="java">Java</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lsp-java
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (lsp)
|
||
:config
|
||
(setq lsp-java-jdt-download-url <span style="color:#e6db74">"https://download.eclipse.org/jdtls/milestones/0.57.0/jdt-language-server-0.57.0-202006172108.tar.gz"</span>))
|
||
|
||
(add-hook <span style="color:#e6db74">'java-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
<span style="color:#75715e">;; (add-hook 'java-mode-hook #'hs-minor-mode)</span>
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'java-mode</span>)
|
||
</code></pre></div><h3 id="go">Go</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package go-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.go\\'"</span>
|
||
:config
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'go-mode</span>)
|
||
(add-hook <span style="color:#e6db74">'go-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'go-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode))
|
||
</code></pre></div><h3 id="dot-net">.NET</h3>
|
||
<h4 id="c">C#</h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependencies</th>
|
||
<th>Disabled</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>omnisharp</td>
|
||
<td>t</td>
|
||
</tr>
|
||
<tr>
|
||
<td>dotnet</td>
|
||
<td>t</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csharp-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.cs\\'"</span>
|
||
:config
|
||
(setq lsp-csharp-server-path (executable-find <span style="color:#e6db74">"omnisharp-wrapper"</span>))
|
||
(add-hook <span style="color:#e6db74">'csharp-mode-hook</span> <span style="color:#a6e22e">#'</span>csharp-tree-sitter-mode)
|
||
(add-hook <span style="color:#e6db74">'csharp-tree-sitter-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'csharp-mode-hook</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'csharp-tree-sitter-mode</span>))
|
||
</code></pre></div><h4 id="msbuild">MSBuild</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csproj-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.csproj\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'csproj-mode</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
</code></pre></div><h3 id="fish">fish</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package fish-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.fish\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'fish-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode))
|
||
</code></pre></div><h3 id="sh">sh</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'sh-mode-hook</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
</code></pre></div><h3 id="haskell">Haskell</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package haskell-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.hs\\'"</span>)
|
||
|
||
(use-package lsp-haskell
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (lsp haskell-mode))
|
||
</code></pre></div><h3 id="lua">Lua</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lua-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.lua\\'"</span>
|
||
:hook (lua-mode <span style="color:#f92672">.</span> smartparens-mode))
|
||
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'lua-mode</span>)
|
||
</code></pre></div><h3 id="json">JSON</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package json-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.json\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'json-mode</span> <span style="color:#a6e22e">#'</span>smartparens-mode)
|
||
(add-hook <span style="color:#e6db74">'json-mode</span> <span style="color:#a6e22e">#'</span>hs-minor-mode)
|
||
(my/set-smartparens-indent <span style="color:#e6db74">'json-mode</span>))
|
||
</code></pre></div><h3 id="sql">SQL</h3>
|
||
<p><a href="https://github.com/zeroturnaround/sql-formatter">sql-formatter</a> is a nice JavaScript package for pretty-printing SQL queries. It is not packaged for Emacs, so the easiest way to use it seems to be to define a custom formatter via <a href="https://github.com/purcell/emacs-reformatter">reformatter</a>.</p>
|
||
<p>Also, I’ve 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 qute package is handy.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/sqlformatter-dialect-choice
|
||
<span style="color:#f92672">'</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>))
|
||
|
||
(setq my/sqlformatter-dialect <span style="color:#e6db74">"postgresql"</span>)
|
||
|
||
(defun my/sqlformatter-set-dialect ()
|
||
<span style="color:#e6db74">"Set dialect for sql-formatter"</span>
|
||
(interactive)
|
||
(setq my/sqlformatter-dialect
|
||
(<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Dialect: "</span> my/sqlformatter-dialect-choice)))
|
||
|
||
(reformatter-define sqlformat
|
||
:program (executable-find <span style="color:#e6db74">"sql-formatter"</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>))
|
||
|
||
(my-leader-def
|
||
:keymaps <span style="color:#f92672">'</span>(sql-mode-map)
|
||
<span style="color:#e6db74">"rr"</span> <span style="color:#a6e22e">#'</span>sqlformat-buffer)
|
||
</code></pre></div><h3 id="yaml">YAML</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package yaml-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.yml\\'"</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'yaml-mode-hook</span> <span style="color:#e6db74">'smartparens-mode</span>)
|
||
(add-hook <span style="color:#e6db74">'yaml-mode-hook</span> <span style="color:#e6db74">'highlight-indent-guides-mode</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)))
|
||
</code></pre></div><h3 id="dot-env">.env</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dotenv-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.env\\..*\\'"</span>)
|
||
</code></pre></div><h3 id="csv">CSV</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package csv-mode
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:mode <span style="color:#e6db74">"\\.csv\\'"</span>)
|
||
</code></pre></div><h3 id="off--pdf"><span class="org-todo done OFF">OFF</span> (OFF) PDF</h3>
|
||
<p>A decent package to view PDFs in Emacs, but I prefer Zathura.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/vedang/pdf-tools/">https://github.com/vedang/pdf-tools/</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pdf-tools
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (pdf-tools-install))
|
||
</code></pre></div><h3 id="docker">Docker</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package dockerfile-mode
|
||
:mode <span style="color:#e6db74">"Dockerfile\\'"</span>
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:config
|
||
(add-hook <span style="color:#e6db74">'dockerfile-mode</span> <span style="color:#e6db74">'smartparens-mode</span>))
|
||
</code></pre></div><h3 id="crontab">crontab</h3>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package crontab-mode
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><h2 id="apps-and-misc">Apps & Misc</h2>
|
||
<h3 id="managing-dotfiles">Managing dotfiles</h3>
|
||
<p>A bunch of functions for managing dotfiles with yadm.</p>
|
||
<h4 id="open-emacs-config">Open Emacs config</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/edit-configuration ()
|
||
<span style="color:#e6db74">"Open the init file."</span>
|
||
(interactive)
|
||
(find-file <span style="color:#e6db74">"~/Emacs.org"</span>))
|
||
|
||
<span style="color:#75715e">;; (defun my/edit-exwm-configuration ()</span>
|
||
<span style="color:#75715e">;; "Open the exwm config file."</span>
|
||
<span style="color:#75715e">;; (interactive)</span>
|
||
<span style="color:#75715e">;; (find-file "~/.emacs.d/exwm.org"))</span>
|
||
|
||
(general-define-key <span style="color:#e6db74">"C-c c"</span> <span style="color:#e6db74">'my/edit-configuration</span>)
|
||
<span style="color:#75715e">;; (general-define-key "C-c C" 'my/edit-exwm-configuration)</span>
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"c"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"configuration"</span>)
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#e6db74">'my/edit-configuration</span>)
|
||
</code></pre></div><h4 id="open-magit-for-yadm">Open Magit for yadm</h4>
|
||
<p>Idea:</p>
|
||
<ul>
|
||
<li><a href="https://www.reddit.com/r/emacs/comments/gjukb3/yadm%5Fmagit/">https://www.reddit.com/r/emacs/comments/gjukb3/yadm%5Fmagit/</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'tramp</span>
|
||
(add-to-list <span style="color:#e6db74">'tramp-methods</span>
|
||
<span style="color:#f92672">`</span>(<span style="color:#e6db74">"yadm"</span>
|
||
(tramp-login-program <span style="color:#e6db74">"yadm"</span>)
|
||
(tramp-login-args ((<span style="color:#e6db74">"enter"</span>)))
|
||
(tramp-login-env ((<span style="color:#e6db74">"SHELL"</span>) <span style="color:#e6db74">"/bin/sh"</span>))
|
||
(tramp-remote-shell <span style="color:#e6db74">"/bin/sh"</span>)
|
||
(tramp-remote-shell-args (<span style="color:#e6db74">"-c"</span>)))))
|
||
|
||
|
||
(defun my/yadm-magit ()
|
||
(interactive)
|
||
(magit-status <span style="color:#e6db74">"/yadm::"</span>))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"cm"</span> <span style="color:#e6db74">'my/yadm-magit</span>)
|
||
</code></pre></div><h4 id="open-a-dotfile">Open a dotfile</h4>
|
||
<p>Open a file managed by yadm.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/open-yadm-file ()
|
||
<span style="color:#e6db74">"Open a file managed by yadm"</span>
|
||
(interactive)
|
||
(find-file
|
||
(<span style="color:#a6e22e">concat</span>
|
||
(<span style="color:#a6e22e">file-name-as-directory</span> (getenv <span style="color:#e6db74">"HOME"</span>))
|
||
(<span style="color:#a6e22e">completing-read</span>
|
||
<span style="color:#e6db74">"yadm files: "</span>
|
||
(split-string
|
||
(shell-command-to-string <span style="color:#e6db74">"yadm ls-files $HOME --full-name"</span>) <span style="color:#e6db74">"\n"</span>)))))
|
||
|
||
(general-define-key <span style="color:#e6db74">"C-c f"</span> <span style="color:#e6db74">'my/open-yadm-file</span>)
|
||
(my-leader-def <span style="color:#e6db74">"cf"</span> <span style="color:#e6db74">'my/open-yadm-file</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">(unless (or my/is-termux my/remote-server)
|
||
(load-file (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"mail.el"</span> user-emacs-directory)))
|
||
</code></pre></div><h4 id="elfeed">Elfeed</h4>
|
||
<p><a href="https://github.com/skeeto/elfeed">elfeed</a> is an Emacs RSS client.</p>
|
||
<p>The advice there sets <code>shr-use-fonts</code> to nil while rendering HTML, so the <code>elfeed-show</code> buffer will use monospace font.</p>
|
||
<p>Using my own fork until the modifications are merged into master.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package elfeed
|
||
:straight (:repo <span style="color:#e6db74">"SqrtMinusOne/elfeed"</span> :host github)
|
||
:if (not my/remote-server)
|
||
:commands (elfeed)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ae"</span> <span style="color:#e6db74">'elfeed</span>)
|
||
:config
|
||
(setq elfeed-db-directory <span style="color:#e6db74">"~/.elfeed"</span>)
|
||
(setq elfeed-enclosure-default-dir (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Downloads"</span>))
|
||
(advice-add <span style="color:#a6e22e">#'</span>elfeed-insert-html
|
||
:around
|
||
(lambda (fun <span style="color:#66d9ef">&rest</span> r)
|
||
(let ((shr-use-fonts <span style="color:#66d9ef">nil</span>))
|
||
(<span style="color:#a6e22e">apply</span> fun r))))
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'elfeed-search-mode-map</span>
|
||
<span style="color:#e6db74">"o"</span> <span style="color:#a6e22e">#'</span>my/elfeed-search-filter-source
|
||
<span style="color:#e6db74">"c"</span> <span style="color:#a6e22e">#'</span>elfeed-search-clear-filter
|
||
<span style="color:#e6db74">"gl"</span> (lambda () (interactive) (elfeed-search-set-filter <span style="color:#e6db74">"+later"</span>)))
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'elfeed-show-mode-map</span>
|
||
<span style="color:#e6db74">"ge"</span> <span style="color:#a6e22e">#'</span>my/elfeed-show-visit-eww))
|
||
</code></pre></div><p><a href="https://github.com/remyhonig/elfeed-org">elfeed-org</a> allows configuring Elfeed feeds with an Org file.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package elfeed-org
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (elfeed)
|
||
:config
|
||
(setq rmh-elfeed-org-files <span style="color:#f92672">'</span>(<span style="color:#e6db74">"~/.emacs.d/private.org"</span>))
|
||
(elfeed-org))
|
||
</code></pre></div><h5 id="some-additions">Some additions</h5>
|
||
<p>Filter elfeed search buffer by the feed under the cursor.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/elfeed-search-filter-source (entry)
|
||
<span style="color:#e6db74">"Filter elfeed search buffer by the feed under cursor."</span>
|
||
(interactive (<span style="color:#a6e22e">list</span> (elfeed-search-selected :ignore-region)))
|
||
(when (elfeed-entry-p entry)
|
||
(elfeed-search-set-filter
|
||
(<span style="color:#a6e22e">concat</span>
|
||
<span style="color:#e6db74">"@6-months-ago "</span>
|
||
<span style="color:#e6db74">"+unread "</span>
|
||
<span style="color:#e6db74">"="</span>
|
||
(replace-regexp-in-string
|
||
(rx <span style="color:#e6db74">"?"</span> (<span style="color:#a6e22e">*</span> not-newline) eos)
|
||
<span style="color:#e6db74">""</span>
|
||
(elfeed-feed-url (elfeed-entry-feed entry)))))))
|
||
</code></pre></div><p>Open a URL with eww.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/elfeed-show-visit-eww ()
|
||
<span style="color:#e6db74">"Visit the current entry in eww"</span>
|
||
(interactive)
|
||
(let ((link (elfeed-entry-link elfeed-show-entry)))
|
||
(when link
|
||
(eww link))))
|
||
</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">(defface elfeed-videos-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'red</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tag \"videos\""</span>)
|
||
|
||
(defface elfeed-twitter-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'blue</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tah \"twitter\""</span>)
|
||
|
||
(defface elfeed-emacs-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'magenta</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tah \"emacs\""</span>)
|
||
|
||
(defface elfeed-music-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'green</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tah \"music\""</span>)
|
||
|
||
(defface elfeed-podcasts-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'yellow</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tag \"podcasts\""</span>)
|
||
|
||
(defface elfeed-blogs-entry
|
||
<span style="color:#f92672">`</span>((<span style="color:#66d9ef">t</span> :foreground <span style="color:#f92672">,</span>(doom-color <span style="color:#e6db74">'orange</span>)))
|
||
<span style="color:#e6db74">"Face for the elfeed entries with tag \"blogs\""</span>)
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'elfeed</span>
|
||
(setq elfeed-search-face-alist
|
||
<span style="color:#f92672">'</span>((twitter elfeed-twitter-entry)
|
||
(podcasts elfeed-podcasts-entry)
|
||
(music elfeed-music-entry)
|
||
(videos elfeed-videos-entry)
|
||
(emacs elfeed-emacs-entry)
|
||
(blogs elfeed-blogs-entry)
|
||
(unread elfeed-search-unread-title-face))))
|
||
</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">(defun my/update-my-theme-elfeed (<span style="color:#66d9ef">&rest</span> _)
|
||
(custom-theme-set-faces
|
||
<span style="color:#e6db74">'my-theme-1</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 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 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 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 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 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>)))))
|
||
(enable-theme <span style="color:#e6db74">'my-theme-1</span>))
|
||
|
||
(advice-add <span style="color:#e6db74">'load-theme</span> :after <span style="color:#a6e22e">#'</span>my/update-my-theme-elfeed)
|
||
(when (<span style="color:#a6e22e">fboundp</span> <span style="color:#e6db74">'doom-color</span>)
|
||
(my/update-my-theme-elfeed))
|
||
</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">(defun my/elfeed-toggle-score-sort ()
|
||
(interactive)
|
||
(setq elfeed-search-sort-function
|
||
(if elfeed-search-sort-function
|
||
<span style="color:#66d9ef">nil</span>
|
||
<span style="color:#a6e22e">#'</span>elfeed-score-sort))
|
||
(<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>))
|
||
(elfeed-search-update--force))
|
||
|
||
(use-package elfeed-score
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (elfeed)
|
||
:init
|
||
(setq elfeed-score-serde-score-file <span style="color:#e6db74">"~/.emacs.d/elfeed.score"</span>)
|
||
:config
|
||
(elfeed-score-enable)
|
||
(setq elfeed-search-print-entry-function <span style="color:#a6e22e">#'</span>elfeed-score-print-entry)
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#f92672">'</span>(elfeed-search-mode-map)
|
||
<span style="color:#e6db74">"="</span> elfeed-score-map)
|
||
(general-define-key
|
||
:keymaps <span style="color:#f92672">'</span>(elfeed-score-map)
|
||
<span style="color:#e6db74">"="</span> <span style="color:#a6e22e">#'</span>my/elfeed-toggle-score-sort))
|
||
</code></pre></div><h5 id="youtube-and-emms">YouTube & 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>The following function converts URLs from Invidious and the like to YouTube.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/get-youtube-url (link)
|
||
(let ((watch-id (cadr
|
||
(<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">"watch?v"</span>
|
||
(url-parse-query-string
|
||
(<span style="color:#a6e22e">substring</span>
|
||
(url-filename
|
||
(url-generic-parse-url link))
|
||
<span style="color:#ae81ff">1</span>))))))
|
||
(<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"https://www.youtube.com/watch?v="</span> watch-id)))
|
||
</code></pre></div><p>Now, a function to add YouTube link with metadata from elfeed to EMMS.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
(define-emms-source elfeed (entry)
|
||
(let ((track (emms-track
|
||
<span style="color:#e6db74">'url</span> (my/get-youtube-url (elfeed-entry-link entry)))))
|
||
(emms-track-set track <span style="color:#e6db74">'info-title</span> (elfeed-entry-title entry))
|
||
(emms-playlist-insert-track track))))
|
||
|
||
(defun my/elfeed-add-emms-youtube ()
|
||
(interactive)
|
||
(emms-add-elfeed elfeed-show-entry)
|
||
(elfeed-tag elfeed-show-entry <span style="color:#e6db74">'watched</span>)
|
||
(elfeed-show-refresh))
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'elfeed</span>
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'elfeed-show-mode-map</span>
|
||
<span style="color:#e6db74">"gm"</span> <span style="color:#a6e22e">#'</span>my/elfeed-add-emms-youtube))
|
||
</code></pre></div><h4 id="emms">EMMS</h4>
|
||
<p>EMMS is the Emacs Multi-Media System. I use it to control MPD & 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">(use-package emms
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (not my/remote-server)
|
||
:commands (emms-smart-browse
|
||
emms-browser
|
||
emms-add-url
|
||
emms-add-file
|
||
emms-add-find)
|
||
:if (not my/is-termux)
|
||
:init
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"as"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"emms"</span>)
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#e6db74">'emms-smart-browse</span>
|
||
<span style="color:#e6db74">"b"</span> <span style="color:#e6db74">'emms-browser</span>
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'emms-pause</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'emms-stop</span>
|
||
<span style="color:#e6db74">"h"</span> <span style="color:#e6db74">'emms-previous</span>
|
||
<span style="color:#e6db74">"l"</span> <span style="color:#e6db74">'emms-next</span>
|
||
<span style="color:#e6db74">"u"</span> <span style="color:#e6db74">'emms-player-mpd-connect</span>)
|
||
(setq emms-mode-line-icon-enabled-p <span style="color:#66d9ef">nil</span>)
|
||
:config
|
||
(require <span style="color:#e6db74">'emms-setup</span>)
|
||
(require <span style="color:#e6db74">'emms-player-mpd</span>)
|
||
(require <span style="color:#e6db74">'emms-player-mpv</span>)
|
||
(emms-all)
|
||
<span style="color:#75715e">;; MPD setup</span>
|
||
<<emms-mpd-setup>>
|
||
<span style="color:#75715e">;; MPV setup</span>
|
||
<<emms-mpv-setup>>
|
||
<span style="color:#75715e">;; evil-lion and evil-commentary shadow some gX bindings</span>
|
||
<span style="color:#75715e">;; (add-hook 'emms-browser-mode-hook</span>
|
||
<span style="color:#75715e">;; (lambda ()</span>
|
||
<span style="color:#75715e">;; (evil-lion-mode -1)</span>
|
||
<span style="color:#75715e">;; (evil-commentary-mode -1)</span>
|
||
<span style="color:#75715e">;; ))</span>
|
||
<span style="color:#75715e">;; I have everything I need in polybar</span>
|
||
(emms-mode-line-mode <span style="color:#ae81ff">-1</span>)
|
||
(emms-playing-time-display-mode <span style="color:#ae81ff">-1</span>)
|
||
<<emms-fixes>>)
|
||
</code></pre></div><h5 id="mpd">MPD</h5>
|
||
<p><a href="https://www.musicpd.org/">mpd</a> is a server for playing music. It has a couple of first-class clients, including curses-based <a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp</a>, but of course, I want to use Emacs.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq emms-source-file-default-directory (<span style="color:#a6e22e">expand-file-name</span> <span style="color:#e6db74">"~/Music/"</span>))
|
||
(add-to-list <span style="color:#e6db74">'emms-info-functions</span> <span style="color:#e6db74">'emms-info-mpd</span>)
|
||
(add-to-list <span style="color:#e6db74">'emms-player-list</span> <span style="color:#e6db74">'emms-player-mpd</span>)
|
||
(setq emms-player-mpd-server-name <span style="color:#e6db74">"localhost"</span>)
|
||
(setq emms-player-mpd-server-port <span style="color:#e6db74">"6600"</span>)
|
||
(setq emms-player-mpd-music-directory <span style="color:#e6db74">"~/Music"</span>)
|
||
</code></pre></div><p>Connect on setup. For some reason, it stops the mpd playback whenever it connects, but it is not a big issue.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(emms-player-mpd-connect)
|
||
</code></pre></div><p>Clear MPD playlist on clearing EMMS playlist. IDK if this is fine for MPD library playlist, I don’t use them anyhow.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(add-hook <span style="color:#e6db74">'emms-playlist-cleared-hook</span> <span style="color:#e6db74">'emms-player-mpd-clear</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">(emms-player-set emms-player-mpd
|
||
<span style="color:#e6db74">'regex</span>
|
||
(emms-player-simple-regexp
|
||
<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>))
|
||
</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="color:#a6e22e">script-opts</span><span style="color:#f92672">=</span><span style="color:#e6db74">ytdl_hook-ytdl_path=yt-dlp</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">(add-to-list <span style="color:#e6db74">'emms-player-list</span> <span style="color:#e6db74">'emms-player-mpv</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">(emms-player-set emms-player-mpv
|
||
<span style="color:#e6db74">'regex</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 style="color:#a6e22e">+</span> (<span style="color:#e6db74">? </span>(or <span style="color:#e6db74">"https://"</span> <span style="color:#e6db74">"http://"</span>))
|
||
(<span style="color:#a6e22e">*</span> nonl)
|
||
(regexp (<span style="color:#a6e22e">eval</span> (emms-player-simple-regexp
|
||
<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>)))))))
|
||
</code></pre></div><p>By default MPV plays the video in the best possible quality, which may be pretty high, even too high with limited bandwidth. So here is the logic to choose the quality.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq my/youtube-dl-quality-list
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"bestvideo[height<=720]+bestaudio/best[height<=720]"</span>
|
||
<span style="color:#e6db74">"bestvideo[height<=480]+bestaudio/best[height<=480]"</span>
|
||
<span style="color:#e6db74">"bestvideo[height<=1080]+bestaudio/best[height<=1080]"</span>))
|
||
|
||
(setq my/default-emms-player-mpv-parameters
|
||
<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>))
|
||
|
||
(defun my/set-emms-mpd-youtube-quality (quality)
|
||
(interactive <span style="color:#e6db74">"P"</span>)
|
||
(unless quality
|
||
(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>)))
|
||
(setq emms-player-mpv-parameters
|
||
<span style="color:#f92672">`</span>(<span style="color:#f92672">,@</span>my/default-emms-player-mpv-parameters <span style="color:#f92672">,</span>(<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"--ytdl-format=%s"</span> quality))))
|
||
|
||
(my/set-emms-mpd-youtube-quality (<span style="color:#a6e22e">car</span> my/youtube-dl-quality-list))
|
||
</code></pre></div><p>Now <code>emms-add-url</code> should work on YouTube URLs just fine. Just keep in mind that it will only add the URL to the playlist, not play it right away.</p>
|
||
<h5 id="cache-cleanup">Cache cleanup</h5>
|
||
<p>All the added URLs reside in the EMMS cache after being played. I don’t want them to stay there for a long time, so here is a handy function to clean it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/emms-cleanup-urls ()
|
||
(interactive)
|
||
(let ((keys-to-delete <span style="color:#f92672">'</span>()))
|
||
(<span style="color:#a6e22e">maphash</span> (lambda (key value)
|
||
(when (<span style="color:#a6e22e">eq</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'type</span> value)) <span style="color:#e6db74">'url</span>)
|
||
(add-to-list <span style="color:#e6db74">'keys-to-delete</span> key)))
|
||
emms-cache-db)
|
||
(dolist (key keys-to-delete)
|
||
(<span style="color:#a6e22e">remhash</span> key emms-cache-db)))
|
||
(setq emms-cache-dirty <span style="color:#66d9ef">t</span>))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"asc"</span> <span style="color:#a6e22e">#'</span>my/emms-cleanup-urls)
|
||
</code></pre></div><h5 id="fetching-lyrics">Fetching lyrics</h5>
|
||
<p>My package for fetching EMMS lyrics and album covers.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package lyrics-fetcher
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (emms)
|
||
:init
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"ast"</span> <span style="color:#a6e22e">#'</span>lyrics-fetcher-show-lyrics
|
||
<span style="color:#e6db74">"asT"</span> <span style="color:#a6e22e">#'</span>lyrics-fetcher-show-lyrics-query)
|
||
:config
|
||
(setq lyrics-fetcher-genius-access-token
|
||
(password-store-get <span style="color:#e6db74">"My_Online/APIs/genius.com"</span>))
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(emacs normal)
|
||
:keymaps <span style="color:#e6db74">'emms-browser-mode-map</span>
|
||
<span style="color:#e6db74">"gl"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-show-at-point</span>
|
||
<span style="color:#e6db74">"gC"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-fetch-covers-at-point</span>
|
||
<span style="color:#e6db74">"go"</span> <span style="color:#e6db74">'lyrics-fetcher-emms-browser-open-large-cover-at-point</span>))
|
||
</code></pre></div><h5 id="some-keybindings">Some keybindings</h5>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'emms-browser</span>
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'emms-browser-mode-map</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'quit-window</span>))
|
||
|
||
(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'emms-playlist-mode-map</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'quit-window</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">(defun emms-info-mpd-process (track info)
|
||
(dolist (data info)
|
||
(let ((name (<span style="color:#a6e22e">car</span> data))
|
||
(value (<span style="color:#a6e22e">cdr</span> data)))
|
||
(setq name (cond ((string= name <span style="color:#e6db74">"artist"</span>) <span style="color:#e6db74">'info-artist</span>)
|
||
((string= name <span style="color:#e6db74">"albumartist"</span>) <span style="color:#e6db74">'info-albumartist</span>)
|
||
((string= name <span style="color:#e6db74">"composer"</span>) <span style="color:#e6db74">'info-composer</span>)
|
||
((string= name <span style="color:#e6db74">"performer"</span>) <span style="color:#e6db74">'info-performer</span>)
|
||
((string= name <span style="color:#e6db74">"title"</span>) <span style="color:#e6db74">'info-title</span>)
|
||
((string= name <span style="color:#e6db74">"album"</span>) <span style="color:#e6db74">'info-album</span>)
|
||
((string= name <span style="color:#e6db74">"track"</span>) <span style="color:#e6db74">'info-tracknumber</span>)
|
||
((string= name <span style="color:#e6db74">"disc"</span>) <span style="color:#e6db74">'info-discnumber</span>)
|
||
((string= name <span style="color:#e6db74">"date"</span>) <span style="color:#e6db74">'info-year</span>)
|
||
((string= name <span style="color:#e6db74">"genre"</span>) <span style="color:#e6db74">'info-genre</span>)
|
||
((string= name <span style="color:#e6db74">"time"</span>)
|
||
(setq value (<span style="color:#a6e22e">string-to-number</span> value))
|
||
<span style="color:#e6db74">'info-playing-time</span>)
|
||
(<span style="color:#66d9ef">t</span> <span style="color:#66d9ef">nil</span>)))
|
||
(when name
|
||
(emms-track-set track name value)))))
|
||
</code></pre></div><p>Also, <code>emms-player-mpd-get-alists</code> has an interesting bug. This function parses the response to <code>listallinfo</code>, which looks something like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">tag1: value1
|
||
tag2: value2
|
||
...
|
||
tag1: value1'
|
||
tag2: value2'
|
||
</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">(("tag1" . "value1"
|
||
"tag2" . "value2")
|
||
("tag1" . "value1'"
|
||
("tag2" . "value2'")))
|
||
</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">(defun emms-player-mpd-get-alists (info)
|
||
<span style="color:#e6db74">"Turn the given parsed INFO from MusicPD into an list of alists.
|
||
</span><span style="color:#e6db74">
|
||
</span><span style="color:#e6db74">The list will be in reverse order."</span>
|
||
(when (and info
|
||
(<span style="color:#a6e22e">null</span> (<span style="color:#a6e22e">car</span> info)) <span style="color:#75715e">; no error has occurred</span>
|
||
(<span style="color:#a6e22e">cdr</span> info)) <span style="color:#75715e">; data exists</span>
|
||
(let ((alists <span style="color:#66d9ef">nil</span>)
|
||
(alist <span style="color:#66d9ef">nil</span>)
|
||
cell)
|
||
(dolist (line (<span style="color:#a6e22e">cdr</span> info))
|
||
(when (setq cell (emms-player-mpd-parse-line line))
|
||
(if (<span style="color:#a6e22e">member</span> (<span style="color:#a6e22e">car</span> cell) <span style="color:#f92672">'</span>(<span style="color:#e6db74">"file"</span> <span style="color:#e6db74">"directory"</span> <span style="color:#e6db74">"playlist"</span>))
|
||
(setq alists (<span style="color:#a6e22e">cons</span> alist alists)
|
||
alist (<span style="color:#a6e22e">list</span> cell))
|
||
(setq alist (<span style="color:#a6e22e">cons</span> cell alist)))))
|
||
(when alist
|
||
(setq alists (<span style="color:#a6e22e">cons</span> alist alists)))
|
||
alists)))
|
||
</code></pre></div><h4 id="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">(use-package ytel
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (ytel)
|
||
:config
|
||
(setq ytel-invidious-api-url <span style="color:#e6db74">"https://invidio.xamh.de/"</span>)
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'ytel-mode-map</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#a6e22e">#'</span>ytel-quit
|
||
<span style="color:#e6db74">"s"</span> <span style="color:#a6e22e">#'</span>ytel-search
|
||
<span style="color:#e6db74">"L"</span> <span style="color:#a6e22e">#'</span>ytel-search-next-page
|
||
<span style="color:#e6db74">"H"</span> <span style="color:#a6e22e">#'</span>ytel-search-previous-page
|
||
<span style="color:#e6db74">"RET"</span> <span style="color:#a6e22e">#'</span>my/ytel-add-emms))
|
||
</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">(with-eval-after-load <span style="color:#e6db74">'emms</span>
|
||
(define-emms-source ytel (video)
|
||
(let ((track (emms-track
|
||
<span style="color:#e6db74">'url</span> (<span style="color:#a6e22e">concat</span> <span style="color:#e6db74">"https://www.youtube.com/watch?v="</span>
|
||
(ytel-video-id video)))))
|
||
(emms-track-set track <span style="color:#e6db74">'info-title</span> (ytel-video-title video))
|
||
(emms-track-set track <span style="color:#e6db74">'info-artist</span> (ytel-video-author video))
|
||
(emms-playlist-insert-track track))))
|
||
|
||
(defun my/ytel-add-emms ()
|
||
(interactive)
|
||
(emms-add-ytel (ytel-get-current-video)))
|
||
</code></pre></div><h4 id="eww">EWW</h4>
|
||
<p>Emacs built-in web browser. <del>I wonder if anyone actually uses it.</del></p>
|
||
<p>I use it occasionally to open links in elfeed.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/toggle-shr-use-fonts ()
|
||
<span style="color:#e6db74">"Toggle the shr-use-fonts variable in buffer"</span>
|
||
(interactive)
|
||
(setq-local shr-use-fonts (not shr-use-fonts)))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"aw"</span> <span style="color:#e6db74">'eww</span>)
|
||
|
||
(general-define-key
|
||
:keymaps <span style="color:#e6db74">'eww-mode-map</span>
|
||
<span style="color:#e6db74">"+"</span> <span style="color:#e6db74">'text-scale-increase</span>
|
||
<span style="color:#e6db74">"-"</span> <span style="color:#e6db74">'text-scale-decrease</span>)
|
||
</code></pre></div><h4 id="erc">ERC</h4>
|
||
<p>ERC is a built-it Emacs IRC client.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package erc
|
||
:commands (erc erc-tls)
|
||
:straight (:type built-in)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ai"</span> <span style="color:#a6e22e">#'</span>erc-tls)
|
||
:config
|
||
<span style="color:#75715e">;; Logging</span>
|
||
(setq erc-log-channels-directory <span style="color:#e6db74">"~/.erc/logs"</span>)
|
||
(setq erc-save-buffer-on-part <span style="color:#66d9ef">t</span>)
|
||
<span style="color:#75715e">;; Config of my ZNC instance.</span>
|
||
(setq erc-server <span style="color:#e6db74">"sqrtminusone.xyz"</span>)
|
||
(setq erc-port <span style="color:#ae81ff">1984</span>)
|
||
(setq erc-nick <span style="color:#e6db74">"sqrtminusone"</span>)
|
||
(setq erc-user-full-name <span style="color:#e6db74">"Pavel Korytov"</span>)
|
||
(setq erc-password (password-store-get <span style="color:#e6db74">"Selfhosted/ZNC"</span>))
|
||
(setq erc-kill-buffer-on-part <span style="color:#66d9ef">t</span>)
|
||
(setq erc-track-shorten-start <span style="color:#ae81ff">8</span>))
|
||
</code></pre></div><p>Exclude everything but actual messages from notifications.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq erc-track-exclude-types <span style="color:#f92672">'</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 style="color:#e6db74">"301"</span> <span style="color:#75715e">; away notice</span>
|
||
<span style="color:#e6db74">"305"</span> <span style="color:#75715e">; return from awayness</span>
|
||
<span style="color:#e6db74">"306"</span> <span style="color:#75715e">; set awayness</span>
|
||
<span style="color:#e6db74">"324"</span> <span style="color:#75715e">; modes</span>
|
||
<span style="color:#e6db74">"329"</span> <span style="color:#75715e">; channel creation date</span>
|
||
<span style="color:#e6db74">"332"</span> <span style="color:#75715e">; topic notice</span>
|
||
<span style="color:#e6db74">"333"</span> <span style="color:#75715e">; who set the topic</span>
|
||
<span style="color:#e6db74">"353"</span> <span style="color:#75715e">; Names notice</span>
|
||
))
|
||
</code></pre></div><p>A plugin to highlight IRC nicknames:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package erc-hl-nicks
|
||
:hook (erc-mode <span style="color:#f92672">.</span> erc-hl-nicks-mode)
|
||
:after (erc)
|
||
:straight <span style="color:#66d9ef">t</span>)
|
||
</code></pre></div><p>ZNC support. Seems to provide a few nice features for ZNC.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package znc
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:after (erc))
|
||
</code></pre></div><h4 id="google-translate">Google Translate</h4>
|
||
<p>Emacs interface to Google Translate.</p>
|
||
<p>Can’t make it load lazily for some strange reason.</p>
|
||
<p>References:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/atykhonov/google-translate">google-translate repo</a></li>
|
||
<li><a href="https://github.com/atykhonov/google-translate/issues/137#issuecomment-728278849">issue with ttk error fix</a></li>
|
||
</ul>
|
||
<!--listend-->
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package google-translate
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:functions (my-google-translate-at-point google-translate--search-tkk)
|
||
:custom
|
||
(google-translate-backend-method <span style="color:#e6db74">'curl</span>)
|
||
:config
|
||
(require <span style="color:#e6db74">'facemenu</span>)
|
||
(defun google-translate--search-tkk ()
|
||
<span style="color:#e6db74">"Search TKK."</span>
|
||
(<span style="color:#a6e22e">list</span> <span style="color:#ae81ff">430675</span> <span style="color:#ae81ff">2721866130</span>))
|
||
(defun my-google-translate-at-point()
|
||
<span style="color:#e6db74">"reverse translate if prefix"</span>
|
||
(interactive)
|
||
(if current-prefix-arg
|
||
(google-translate-at-point)
|
||
(google-translate-at-point-reverse)))
|
||
(setq google-translate-translation-directions-alist
|
||
<span style="color:#f92672">'</span>((<span style="color:#e6db74">"en"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"ru"</span>)
|
||
(<span style="color:#e6db74">"ru"</span> <span style="color:#f92672">.</span> <span style="color:#e6db74">"en"</span>))))
|
||
|
||
(my-leader-def
|
||
:infix <span style="color:#e6db74">"at"</span>
|
||
<span style="color:#e6db74">""</span> <span style="color:#f92672">'</span>(:which-key <span style="color:#e6db74">"google translate"</span>)
|
||
<span style="color:#e6db74">"p"</span> <span style="color:#e6db74">'google-translate-at-point</span>
|
||
<span style="color:#e6db74">"P"</span> <span style="color:#e6db74">'google-translate-at-point-reverse</span>
|
||
<span style="color:#e6db74">"q"</span> <span style="color:#e6db74">'google-translate-query-translate</span>
|
||
<span style="color:#e6db74">"Q"</span> <span style="color:#e6db74">'google-translate-query-translate-reverse</span>
|
||
<span style="color:#e6db74">"t"</span> <span style="color:#e6db74">'google-translate-smooth-translate</span>)
|
||
</code></pre></div><h3 id="reading-documentation">Reading documentation</h3>
|
||
<h4 id="tldr">tldr</h4>
|
||
<p><a href="https://tldr.sh/">tldr</a> is a collaborative project providing cheatsheets for various console commands. For some reason, the built-in download in the package is broken, so I use my own function.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package tldr
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (tldr)
|
||
:config
|
||
(setq tldr-source-zip-url <span style="color:#e6db74">"https://github.com/tldr-pages/tldr/archive/refs/heads/main.zip"</span>)
|
||
|
||
(defun tldr-update-docs ()
|
||
(interactive)
|
||
(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))
|
||
(when (<span style="color:#a6e22e">file-exists-p</span> <span style="color:#e6db74">"/tmp/tldr"</span>)
|
||
(delete-directory <span style="color:#e6db74">"/tmp/tldr"</span> <span style="color:#66d9ef">t</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))
|
||
(when (<span style="color:#a6e22e">file-exists-p</span> tldr-directory-path)
|
||
(delete-directory tldr-directory-path <span style="color:#e6db74">'recursive</span> <span style="color:#e6db74">'no-trash</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))))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"hT"</span> <span style="color:#e6db74">'tldr</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">(setq Man-width-max <span style="color:#ae81ff">180</span>)
|
||
(my-leader-def <span style="color:#e6db74">"hM"</span> <span style="color:#e6db74">'man</span>)
|
||
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'Info-mode-map</span>
|
||
(kbd <span style="color:#e6db74">"RET"</span>) <span style="color:#e6db74">'Info-follow-nearest-node</span>)
|
||
|
||
(defun my/man-fix-width (<span style="color:#66d9ef">&rest</span> _)
|
||
(setq-local Man-width (<span style="color:#a6e22e">-</span> (window-width) <span style="color:#ae81ff">4</span>)))
|
||
|
||
(advice-add <span style="color:#a6e22e">#'</span>Man-update-manpage :before <span style="color:#a6e22e">#'</span>my/man-fix-width)
|
||
</code></pre></div><h4 id="devdocs-dot-io">devdocs.io</h4>
|
||
<p>Finally, there is also an Emacs plugin for <a href="https://devdocs.io">devdocs.io</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package devdocs
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (devdocs-install devdocs-lookup)
|
||
:init
|
||
(my-leader-def
|
||
<span style="color:#e6db74">"he"</span> <span style="color:#a6e22e">#'</span>devdocs-lookup
|
||
<span style="color:#e6db74">"hE"</span> <span style="color:#a6e22e">#'</span>devdocs-install))
|
||
</code></pre></div><h3 id="utilities">Utilities</h3>
|
||
<h4 id="pass">pass</h4>
|
||
<p>I use <a href="https://www.passwordstore.org/">pass</a> as my password manager. Expectedly, there is Emacs frontend for it.</p>
|
||
<p>Although I use <a href="https://github.com/carnager/rofi-pass">this rofi frontend</a> for actually inserting passwords.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pass
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (pass)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ak"</span> <span style="color:#a6e22e">#'</span>pass)
|
||
:config
|
||
(setq pass-show-keybindings <span style="color:#66d9ef">nil</span>))
|
||
</code></pre></div><h4 id="docker">Docker</h4>
|
||
<p>A package to manage docker containers from Emacs.</p>
|
||
<p>The file <code>progidy-config.el</code> sets variable <code>my/docker-directories</code>, which allows to</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package docker
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (docker)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ao"</span> <span style="color:#e6db74">'docker</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">(setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
|
||
|
||
(defun my/docker-override-dir (fun <span style="color:#66d9ef">&rest</span> args)
|
||
(let ((default-directory (or my/selected-docker-directory default-directory)))
|
||
(setq my/selected-docker-directory <span style="color:#66d9ef">nil</span>)
|
||
(<span style="color:#a6e22e">apply</span> fun args)))
|
||
</code></pre></div><p>It overrides <code>default-directory</code> for the first launch of a function. Now, add the advice to the required functions from <code>docker.el</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(with-eval-after-load <span style="color:#e6db74">'docker</span>
|
||
(advice-add <span style="color:#a6e22e">#'</span>docker-compose-run-docker-compose-async :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
(advice-add <span style="color:#a6e22e">#'</span>docker-compose-run-docker-compose :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
(advice-add <span style="color:#a6e22e">#'</span>docker-run-docker-async :around <span style="color:#a6e22e">#'</span>my/docker-override-dir)
|
||
(advice-add <span style="color:#a6e22e">#'</span>docker-run-docker :around <span style="color:#a6e22e">#'</span>my/docker-override-dir))
|
||
</code></pre></div><p>And here is a function which prompts the user for the directory. File <code>progidy-config.el</code> sets an alist of possible directories, look the section about <a href="#progidy">progidy</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/docker-from-dir ()
|
||
(interactive)
|
||
(when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/docker-directories</span>))
|
||
(<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"prodigy-config"</span>)))
|
||
(let* ((directories
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (el) (<span style="color:#a6e22e">cons</span> (<span style="color:#a6e22e">format</span> <span style="color:#e6db74">"%-30s %s"</span> (<span style="color:#a6e22e">car</span> el) (<span style="color:#a6e22e">cdr</span> el)) (<span style="color:#a6e22e">cdr</span> el)))
|
||
my/docker-directories))
|
||
(selected-directory
|
||
(<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> (<span style="color:#a6e22e">completing-read</span> <span style="color:#e6db74">"Docker: "</span> directories <span style="color:#66d9ef">nil</span> <span style="color:#66d9ef">nil</span> <span style="color:#e6db74">"^"</span>)
|
||
directories))))
|
||
(setq my/selected-docker-directory selected-directory)
|
||
(docker)))
|
||
|
||
(my-leader-def <span style="color:#e6db74">"aO"</span> <span style="color:#e6db74">'my/docker-from-dir</span>)
|
||
</code></pre></div><h4 id="progidy">Progidy</h4>
|
||
<p><a href="https://github.com/rejeep/prodigy.el">prodigy.el</a> is a package to run various services. I’ve previously used tmuxp + tmux, but want to try this as well.</p>
|
||
<p>The actual service definitions are in the <code>~/.emacs.d/prodigy.org</code>, which tangles to <code>prodigy-config.el</code>. Both files are encrypted in yadm, as they contain personal data.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package prodigy
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (prodigy)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"aP"</span> <span style="color:#e6db74">'prodigy</span>)
|
||
:config
|
||
(when (not (<span style="color:#a6e22e">boundp</span> <span style="color:#e6db74">'my/docker-directories</span>))
|
||
(<span style="color:#a6e22e">load</span> (<span style="color:#a6e22e">concat</span> user-emacs-directory <span style="color:#e6db74">"prodigy-config"</span>)))
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'prodigy-view-mode-map</span>
|
||
<span style="color:#e6db74">"C-h"</span> <span style="color:#e6db74">'evil-window-left</span>
|
||
<span style="color:#e6db74">"C-l"</span> <span style="color:#e6db74">'evil-window-right</span>
|
||
<span style="color:#e6db74">"C-k"</span> <span style="color:#e6db74">'evil-window-up</span>
|
||
<span style="color:#e6db74">"C-j"</span> <span style="color:#e6db74">'evil-window-down</span>))
|
||
</code></pre></div><p>A few functions to work with apps on ports.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(defun my/get-apps-on-ports ()
|
||
(<span style="color:#a6e22e">mapcar</span>
|
||
(lambda (line)
|
||
(let* ((split (split-string line (rx (| (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">" "</span>) (<span style="color:#a6e22e">+</span> <span style="color:#e6db74">"\t"</span>)))))
|
||
(process (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">6</span>)))
|
||
<span style="color:#f92672">`</span>((netid <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">0</span>))
|
||
(state <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">1</span>))
|
||
(recv-q <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">2</span>))
|
||
(send-q <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">3</span>))
|
||
<span style="color:#f92672">,@</span>(let ((data (<span style="color:#a6e22e">elt</span> split <span style="color:#ae81ff">4</span>)))
|
||
(save-match-data
|
||
(<span style="color:#a6e22e">string-match</span> (rx (group-n <span style="color:#ae81ff">1</span> (<span style="color:#a6e22e">*</span> nonl)) <span style="color:#e6db74">":"</span> (group-n <span style="color:#ae81ff">2</span> (or (<span style="color:#a6e22e">+</span> num) <span style="color:#e6db74">"*"</span>))) data)
|
||
<span style="color:#f92672">`</span>((local-address <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(match-string <span style="color:#ae81ff">1</span> data))
|
||
(local-port <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(match-string <span style="color:#ae81ff">2</span> data)))))
|
||
<span style="color:#f92672">,@</span>(unless (string-empty-p process)
|
||
<span style="color:#f92672">`</span>((pid <span style="color:#f92672">.</span> <span style="color:#f92672">,</span>(save-match-data
|
||
(<span style="color:#a6e22e">string-match</span> (rx <span style="color:#e6db74">"pid="</span> (<span style="color:#a6e22e">+</span> num)) process)
|
||
(<span style="color:#a6e22e">string-to-number</span> (<span style="color:#a6e22e">substring</span> (match-string <span style="color:#ae81ff">0</span> process) <span style="color:#ae81ff">4</span>)))))))))
|
||
(seq-filter
|
||
(lambda (s) (not (string-empty-p s)))
|
||
(split-string
|
||
(shell-command-to-string <span style="color:#e6db74">"ss -tulpnH | grep LISTEN"</span>) <span style="color:#e6db74">"\n"</span>))))
|
||
|
||
(defun my/kill-app-on-port (port <span style="color:#66d9ef">&optional</span> <span style="color:#a6e22e">signal</span>)
|
||
(let ((apps (my/get-apps-on-ports)))
|
||
(dolist (app apps)
|
||
(when (<span style="color:#a6e22e">string-equal</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'local-port</span> app)) port)
|
||
(<span style="color:#a6e22e">signal-process</span> (<span style="color:#a6e22e">cdr</span> (<span style="color:#a6e22e">assoc</span> <span style="color:#e6db74">'pid</span> app)) (or <span style="color:#a6e22e">signal</span> <span style="color:#ae81ff">15</span>))
|
||
(<span style="color:#a6e22e">message</span> <span style="color:#e6db74">"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)))))))
|
||
</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">(use-package screenshot
|
||
:straight (:repo <span style="color:#e6db74">"tecosaur/screenshot"</span> :host github :files (<span style="color:#e6db74">"screenshot.el"</span>) :commit <span style="color:#e6db74">"f8204e82dc0c1158c401735d36a143e6f6d24cf5"</span>)
|
||
:if (display-graphic-p)
|
||
:commands (screenshot)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"S"</span> <span style="color:#e6db74">'screenshot</span>))
|
||
</code></pre></div><h4 id="proced">proced</h4>
|
||
<p>proced is an Emacs built-it process viewer, like top.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my-leader-def <span style="color:#e6db74">"ah"</span> <span style="color:#e6db74">'proced</span>)
|
||
(setq proced-auto-update-interval <span style="color:#ae81ff">1</span>)
|
||
(add-hook <span style="color:#e6db74">'proced-mode-hook</span> (lambda ()
|
||
(visual-line-mode <span style="color:#ae81ff">-1</span>)
|
||
(setq-local truncate-lines <span style="color:#66d9ef">t</span>)
|
||
(proced-toggle-auto-update <span style="color:#ae81ff">1</span>)))
|
||
</code></pre></div><h4 id="guix">Guix</h4>
|
||
<p>An Emacs package to help managing GNU Guix.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package guix
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:commands (guix)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ag"</span> <span style="color:#e6db74">'guix</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">(use-package pomm
|
||
:straight (:host github :repo <span style="color:#e6db74">"SqrtMinusOne/pomm.el"</span> :files (:defaults <span style="color:#e6db74">"resources"</span>))
|
||
<span style="color:#75715e">;; :straight (:local-repo "~/Code/Emacs/pomm" :files (:defaults "resources"))</span>
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"ap"</span> <span style="color:#a6e22e">#'</span>pomm)
|
||
:config
|
||
(setq alert-default-style <span style="color:#e6db74">'libnotify</span>)
|
||
(add-hook <span style="color:#e6db74">'pomm-on-tick-hook</span> <span style="color:#e6db74">'pomm-update-mode-line-string</span>)
|
||
(add-hook <span style="color:#e6db74">'pomm-on-status-changed-hook</span> <span style="color:#e6db74">'pomm-update-mode-line-string</span>))
|
||
</code></pre></div><h4 id="off--pomidor"><span class="org-todo done OFF">OFF</span> (OFF) Pomidor</h4>
|
||
<p>A simple pomodoro technique timer.</p>
|
||
<p>Disabled it in favour of my own package.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package pomidor
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:disabled
|
||
:commands (pomidor)
|
||
:init
|
||
(my-leader-def <span style="color:#e6db74">"aP"</span> <span style="color:#a6e22e">#'</span>pomidor)
|
||
:config
|
||
(setq pomidor-sound-tick <span style="color:#66d9ef">nil</span>)
|
||
(setq pomidor-sound-tack <span style="color:#66d9ef">nil</span>)
|
||
(general-define-key
|
||
:states <span style="color:#f92672">'</span>(normal)
|
||
:keymaps <span style="color:#e6db74">'pomidor-mode-map</span>
|
||
(kbd <span style="color:#e6db74">"q"</span>) <span style="color:#a6e22e">#'</span>quit-window
|
||
(kbd <span style="color:#e6db74">"Q"</span>) <span style="color:#a6e22e">#'</span>pomidor-quit
|
||
(kbd <span style="color:#e6db74">"R"</span>) <span style="color:#a6e22e">#'</span>pomidor-reset
|
||
(kbd <span style="color:#e6db74">"h"</span>) <span style="color:#a6e22e">#'</span>pomidor-hold
|
||
(kbd <span style="color:#e6db74">"H"</span>) <span style="color:#a6e22e">#'</span>pomidor-unhold
|
||
(kbd <span style="color:#e6db74">"RET"</span>) <span style="color:#a6e22e">#'</span>pomidor-stop
|
||
(kbd <span style="color:#e6db74">"M-RET"</span>) <span style="color:#a6e22e">#'</span>pomidor-break))
|
||
</code></pre></div><h4 id="calendar">Calendar</h4>
|
||
<p>Emacs' built-in calendar. Can even calculate sunrise and sunset times.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(setq calendar-date-style <span style="color:#e6db74">'iso</span>) <span style="color:#75715e">;; YYYY/mm/dd</span>
|
||
(setq calendar-week-start-day <span style="color:#ae81ff">1</span>)
|
||
(setq calendar-time-display-form <span style="color:#f92672">'</span>(24-hours <span style="color:#e6db74">":"</span> minutes))
|
||
|
||
(setq calendar-latitude <span style="color:#ae81ff">59.9375</span>)
|
||
(setq calendar-longitude <span style="color:#ae81ff">30.308611</span>)
|
||
</code></pre></div><h3 id="fun">Fun</h3>
|
||
<h4 id="discord-integration">Discord integration</h4>
|
||
<p>Integration with Discord. Shows which file is being edited in Emacs.</p>
|
||
<p>In order for this to work in Guix, a service is necessary - <a href="/configs/desktop/">Discord rich presence</a>.</p>
|
||
<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">(defun my/elcord-mask-buffer-name (name)
|
||
(cond
|
||
((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 style="color:#e6db74">"<ORG-ROAM>"</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 style="color:#e6db74">"<ORG-JOURNAL>"</span>)
|
||
((string-match-p (rx bos <span style="color:#e6db74">"EXWM"</span>) name)
|
||
<span style="color:#e6db74">"<EXWM>"</span>)
|
||
(<span style="color:#66d9ef">t</span> name)))
|
||
|
||
(defun my/elcord-buffer-details-format-functions ()
|
||
(<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>))))
|
||
|
||
(defun my/elcord-update-presence-mask-advice (r)
|
||
(<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)))
|
||
</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">(use-package elcord
|
||
:straight <span style="color:#66d9ef">t</span>
|
||
:if (and (or
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"indigo"</span>)
|
||
(string= (<span style="color:#a6e22e">system-name</span>) <span style="color:#e6db74">"eminence"</span>))
|
||
(not my/slow-ssh)
|
||
(not my/remote-server))
|
||
:config
|
||
(setq elcord-buffer-details-format-function <span style="color:#a6e22e">#'</span>my/elcord-buffer-details-format-functions)
|
||
(advice-add <span style="color:#e6db74">'elcord--try-update-presence</span> :filter-args <span style="color:#a6e22e">#'</span>my/elcord-update-presence-mask-advice)
|
||
(elcord-mode))
|
||
</code></pre></div><h4 id="snow">Snow</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package snow
|
||
:straight (:repo <span style="color:#e6db74">"alphapapa/snow.el"</span> :host github)
|
||
:commands (snow))
|
||
</code></pre></div><h4 id="zone">Zone</h4>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(use-package zone
|
||
:ensure <span style="color:#66d9ef">nil</span>
|
||
:config
|
||
(setq original-zone-programs (<span style="color:#a6e22e">copy-sequence</span> zone-programs)))
|
||
|
||
(defun my/zone-with-select ()
|
||
(interactive)
|
||
(ivy-read <span style="color:#e6db74">"Zone programs"</span>
|
||
(cl-pairlis
|
||
(cl-mapcar <span style="color:#e6db74">'symbol-name</span> original-zone-programs)
|
||
original-zone-programs)
|
||
:action (lambda (elem)
|
||
(setq zone-programs (<span style="color:#a6e22e">vector</span> (<span style="color:#a6e22e">cdr</span> elem)))
|
||
(zone))))
|
||
</code></pre></div><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">(defun my/ytel-kill-url ()
|
||
(interactive)
|
||
(kill-new
|
||
(<span style="color:#a6e22e">concat</span>
|
||
<span style="color:#e6db74">"https://www.youtube.com/watch?v="</span>
|
||
(ytel-video-id (ytel-get-current-video)))))
|
||
</code></pre></div><h2 id="guix-settings">Guix settings</h2>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Guix dependency</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>emacs-vterm</td>
|
||
<td>A vterm package</td>
|
||
</tr>
|
||
<tr>
|
||
<td>ripgrep</td>
|
||
<td>A recursive search tool</td>
|
||
</tr>
|
||
<tr>
|
||
<td>the-silver-searcher</td>
|
||
<td>Another recursive search tool</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><a id="code-snippet--packages"></a></p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(my/format-guix-dependencies)
|
||
</code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-scheme" data-lang="scheme">(<span style="color:#a6e22e">specifications->manifest</span>
|
||
<span style="color:#f92672">'</span>(<span style="color:#e6db74">"emacs-native-comp"</span>
|
||
<<packages()>>))
|
||
</code></pre></div>
|
||
</div>
|
||
|
||
</div><div id="footer" class="mb-5">
|
||
<hr>
|
||
<div class="container text-center">
|
||
|
||
</div>
|
||
|
||
<div class="container text-center">
|
||
<a href="https://sqrtminusone.xyz/" title="Pavel Korytov, 2021"><small>Pavel Korytov, 2021</small></a>
|
||
</div>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|