<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:media="http://search.yahoo.com/mrss/"><channel>
<title>Emacs Tipps &amp; Tricks</title>
<atom:link href="https://www.draketo.de/software/emacs-tipps.xml" rel="self" type="application/rss+xml" />
<link>https://www.draketo.de/software</link>
<description><![CDATA[]]></description>
<language>en</language>
<pubDate>Sat, 07 Mar 2026 17:35:46 +0100</pubDate>
<lastBuildDate>Sat, 07 Mar 2026 17:35:46 +0100</lastBuildDate>
<generator>Emacs 31.0 Org-mode 9.7.39</generator>
<webMaster>arne@fluss (ArneBab)</webMaster>
<image>
<url>https://www.draketo.de/assets/portrait.png</url>
<title>Emacs Tipps &amp; Tricks</title>
<link>https://www.draketo.de/software</link>
</image>

<div id="head">
  <div id="preamble">
    <div id="nav-list">
      <a href="../wissen.html" class="category-tab tab-inactive tab-wissen">Wissen</a>
      <a href="../software.html" class="category-tab tab-inactive tab-software">Software</a>
      <a href="../politik.html" class="category-tab tab-inactive tab-politik">Politik</a>
      <a href="../index.html" class="category-tab tab-inactive tab-photo" title="Startpage" aria-label="Startpage"> </a>
      <a href="../anderes.html" class="category-tab tab-inactive tab-anderes">Anderes</a>
      <a href="../kreatives.html" class="category-tab tab-inactive tab-kreatives">Kreatives</a>
      <a href="../rollenspiel.html" class="category-tab tab-inactive tab-rollenspiel">Rollenspiel</a>
    </div>
  </div>
</div>
<!-- Search your soul and add the goal to favor building with Guile Wisp.-->

<div class="dark-mode-toggle"><a onclick="invert()">(dark mode)<span class="icon">🌓︎</span></a></div>

<p>
Emacs is the Program I live in.
</p>

<p>
I don’t use Emacs for everything, because it is not best for
everything, but any tool that cannot be integrated with Emacs requires
considerably more context switches than if it can be integrated.
</p>

<p>
Also see the <a href="org-mode-tipps.html">org-mode tipps</a>. Org-mode is what binds Emacs together for
me.
</p>

<p>
Other larger topics have their own articles:
</p>

<ul class="org-ul">
<li><a href="emacs-javascript.html">Emacs for Javascript development</a> — it keeps up on the raw coding
part, and the integration turns it into the best tool. Jumping from
the org-mode planning document into the code project and back knows
no equal.</li>
<li><a href="intellij-emacs.html">What I need from IntelliJ and what I miss when not using Emacs</a> — why
I don’t (yet?) use Emacs for Java development.</li>
</ul>

<div class="sourcebox" markdown="1" >
<a href="emacs-tipps.pdf"><img width="168" height="235" title="PDF" src="../assets/pdf-thumbnail.png" /></a><br />
<a href="emacs-tipps.pdf">PDF</a> (drucken)
</div>

<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#use-package">Initialize use-package</a></li>
<li><a href="#exwm-setup"><span class="todo TODO">TODO</span> Simple EXWM setup</a></li>
<li><a href="#exwm-two-screens">Simple EXWM setup for two screens</a></li>
<li><a href="#exwm-pulseaudio">Controlling pulseaudio from EXWM</a></li>
<li><a href="#elfeed-emms">elfeed and emms: listen to podcast with convenience</a></li>
<li><a href="#window-configuration-to-register">Save the frame configuration to a register</a></li>
<li><a href="#pgp-key-mu4e">select pgp key to use for mu4e</a></li>
<li><a href="#make-window-dedicated">make-window-dedicated: prevent replacing of buffers</a></li>
<li><a href="#create-packages">Create simple packages (tutorial)</a></li>
<li><a href="#lsp-dap">LSP and DAP mode (language server and debug adapter)</a></li>
<li><a href="#ido-everywhere-except">Use ido everywhere, except in specific functions</a></li>
<li><a href="#type-break-slideview">type-break with image-slideshow from workrave using slideview</a></li>
<li><a href="#find-current-file-as-root">find-current-as-root</a></li>
<li><a href="#diff-hl-set-reference-rev">see complete changes with M-x diff-hl-set-reference-rev</a></li>
<li><a href="#agenda-notifications-calendar">Org-Agenda with desktop notifications and Outlook calendar ics</a></li>
<li><a href="#ssh-x11">Reduce overhead over ssh X11 forwarding</a></li>
<li><a href="#vc-mode-partial">VC-mode enables partial commits for every version tracking system (Git, Mercurial, …)</a></li>
<li><a href="#mminimal-face-adjustments">Minimal face adjustments</a></li>
<li><a href="#xref-dumb-jump-ts">xref/dumb-jump setup for typescript: mouse and keyboard</a></li>
<li><a href="#browse-unicode">Browse Unicode Letters</a></li>
<li><a href="#python-setup-eglot">Simple Python Setup with eglot/lsp</a></li>
<li><a href="#auto-revert-notify">reliable auto-revert: disable notify</a></li>
<li><a href="#shell-mode-history">Emacs shell-mode with full history search</a></li>
<li><a href="#ansi-colors">Show ansi colors (shell-colors) in any buffer</a></li>
<li><a href="#org-rifle-knowledge-base">helm-org-rifle as knowledge base</a></li>
<li><a href="#mu4e-autocrypt-import-keys">Setup autocrypt for mu4e to import found keys into gpg</a></li>
</ul>
</div>
</nav>
<item>
<title>Initialize use-package</title>
<link>https://www.draketo.de/software/emacs-tipps.html#use-package</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#use-package</guid>
<pubDate>Thu, 03 Apr 2025 22:25:00 +0200</pubDate>

<description><![CDATA[<p>
This is the basis for most of the setups here. Put it into <code>$HOME/.emacs.de/init.el</code>
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">package</span>)
(add-to-list 'package-archives '(<span style="color: #8b2252;">"melpa"</span> . <span style="color: #8b2252;">"https://melpa.org/packages/"</span>) t)
<span style="color: #b22222;">;; </span><span style="color: #b22222;">Also see `package-archive-priorities` and `package-pinned-packages`.</span>
(package-initialize)
<span style="color: #b22222;">;; </span><span style="color: #b22222;">This is only needed once, near the top of the file</span>
(<span style="color: #a020f0;">eval-when-compile</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Following line is not needed if use-package.el is in ~/.emacs.d</span>
  (add-to-list 'load-path <span style="color: #8b2252;">"&lt;path where use-package is installed&gt;"</span>)
  (<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">use-package</span>))
</pre>
</div>
]]></description>
</item>
<item>
<title>Simple EXWM setup</title>
<link>https://www.draketo.de/software/emacs-tipps.html#exwm-setup</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#exwm-setup</guid>
<pubDate>Thu, 06 Jan 2022 23:40:00 +0100</pubDate>

<description><![CDATA[<p>
<a href="https://github.com/ch11ng/exwm">EXWM</a> is a window manager running in Emacs. It’s actually awesome to
work in it, though it still has some rough edges.
</p>

<p>
I started using exwm seriously when Gnome Shell killed my keyboard
layout once too often while switching users and Chromium corrupted its
shortcuts when I set my keyboard layout again. Now exwm is my
regular work environment.
</p>

<p>
I’m typing this from my Emacs running exwm.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #b22222;">;;; </span><span style="color: #b22222;">Setup EXWM</span>
(<span style="color: #a020f0;">use-package</span> exwm <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:custom</span> <span style="color: #b22222;">;; </span><span style="color: #b22222;">move/resize floating buffers </span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">with Alt left-click/Alt right-click</span>
  (exwm-input-move-event [M-down-mouse-1])
  (exwm-input-resize-event [M-down-mouse-3])
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">make window borders easier to grab to</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">enable resizing outside the modeline</span>
  (exwm-floating-border-width 2)
  (window-divider-default-right-width 6)
  (window-divider-default-bottom-width 0) <span style="color: #b22222;">;; </span><span style="color: #b22222;">use the modeline</span>
  (desktop-environment-update-exwm-global-keys nil)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">use a larger systemtray for (exwm-systemtray-mode)</span>
  (exwm-systemtray-height 32)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Make buffer name more meaningful</span>
  (exwm-update-title-hook
   '((<span style="color: #a020f0;">lambda</span> nil
       (exwm-workspace-rename-buffer exwm-class-name))))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">always enable switching to any buffer from any workspace</span>
  (exwm-workspace-show-all-buffers t)
  <span style="color: #483d8b;">:config</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Allow resizing with mouse, of non-floating windows.</span>
  (<span style="color: #a020f0;">setq</span> window-divider-default-bottom-width 2)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">do not open new frame for ediff: that would break</span>
  (<span style="color: #a020f0;">setq</span> ediff-window-setup-function #'ediff-setup-windows-plain)
  (window-divider-mode)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">show the time in the modeline (also see the customization in the variables)</span>
  (display-time-mode)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">disable CTRL-z (pause), because it breaks my workflows and exwm</span>
  (global-unset-key (kbd <span style="color: #8b2252;">"C-z"</span>)))

<span style="color: #b22222;">;;; </span><span style="color: #b22222;">Start pinentry, so passwords for ssh and gnupg use Emacs mechanisms</span>
(<span style="color: #a020f0;">use-package</span> pinentry
  <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:config</span>
  (pinentry-start))

<span style="color: #b22222;">;;; </span><span style="color: #b22222;">Setup type-break mode such that it does not block EXWM</span>
(<span style="color: #a020f0;">use-package</span> type-break
  <span style="color: #483d8b;">:custom</span>
  (type-break-demo-boring-stats t)
  (type-break-mode-line-message-mode t)
  <span style="color: #483d8b;">:config</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">ignore errors for type-break mode. A missing type-break stats</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">file can break startup otherwise.</span>
  (<span style="color: #a020f0;">ignore-errors</span> (type-break-mode t))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">the regular y-or-n-p or yes-or-no-p break exwm when in an X11 window.</span>
  (add-hook 'exmw-init
            (<span style="color: #a020f0;">lambda</span> ()
              (<span style="color: #a020f0;">setq</span> type-break-query-function
                    (<span style="color: #a020f0;">lambda</span> (msg)
                      (ding)
                      (alert msg
                             <span style="color: #483d8b;">:severity</span> 'high
                             <span style="color: #483d8b;">:title</span> <span style="color: #8b2252;">"M-x type-break"</span>
                             <span style="color: #483d8b;">:icon</span> <span style="color: #8b2252;">"warning"</span>))))))
</pre>
</div>

<p>
I currently start my session as normal in Gnome Shell (to get all the
monitor setup and tweaks), then start Emacs and just run
</p>

<div class="org-src-container">
<pre class="src src-example">M-x exwm-init
</pre>
</div>

<p>
(answer <code>yes</code>: replace existing window manager)
</p>

<p>
To be able to switch back, you can get the current window manager with
</p>

<div class="org-src-container">
<pre class="src src-bash">wmctrl -m
<span style="color: #b22222;"># </span><span style="color: #b22222;">in guix you can install and run it in one step:</span>
<span style="color: #b22222;"># </span><span style="color: #b22222;">guix shell wmctrl -- wmctrl -m</span>
</pre>
</div>
]]></description>
</item>
<item>
<title>Simple EXWM setup for two screens</title>
<link>https://www.draketo.de/software/emacs-tipps.html#exwm-two-screens</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#exwm-two-screens</guid>
<pubDate>Tue, 05 Jul 2022 08:14:00 +0200</pubDate>

<description><![CDATA[<p>
The tutorials I found to setup EXWM for two screens are much too complex.
</p>

<p>
In addition to the changes above, you just need exwm-randr.
</p>

<p>
I have two screens: HDMI-1, the primary screen, and DP-1, the
secondary that is somewhat smaller than the primary.
</p>

<p>
Use arandr to find the correct position for the secondary screen. For
me it is <code>1920x120</code>: The width of the primary screen and the
difference in height (resolution) between both.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #b22222;">;; </span><span style="color: #b22222;">Enable exwm-randr before exwm-init gets called</span>
(<span style="color: #a020f0;">use-package</span> exwm-randr
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">:if dw/exwm-enabled</span>
  <span style="color: #483d8b;">:after</span> (exwm)
  <span style="color: #483d8b;">:custom</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">two workspaces</span>
  (exwm-workspace-number 2)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">move the second workspace to the secondary monitor, </span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">the others are on the primary display</span>
  (exwm-randr-workspace-monitor-plist '(1 <span style="color: #8b2252;">"DP-1"</span>))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">enable switching to any buffer from any workspace</span>
  (exwm-workspace-show-all-buffers t)
  (exwm-layout-show-all-buffers t)
  <span style="color: #483d8b;">:config</span>
  (exwm-randr-enable)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">update the screen setup when a screen is turned on or off</span>
  (add-hook 'exwm-randr-screen-change-hook
            (<span style="color: #a020f0;">lambda</span> ()
              (start-process-shell-command
               <span style="color: #8b2252;">"xrandr"</span> nil 
  <span style="color: #8b2252;">"xrandr --output HDMI-3 --primary --auto --pos 0x0 --output DP-1 --auto --pos 1920x120"</span>))))
</pre>
</div>
]]></description>
</item>
<item>
<title>Controlling pulseaudio from EXWM</title>
<link>https://www.draketo.de/software/emacs-tipps.html#exwm-pulseaudio</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#exwm-pulseaudio</guid>
<pubDate>Thu, 06 Jan 2022 23:40:00 +0100</pubDate>

<description><![CDATA[<p>
I need mouse-controlled volume. The desktop-environment package
provides it, but out of the box only for amixer. I adjusted it for
pulseaudio.
</p>

<p>
Also I added the volume to the modline, with scrollwheel control:
Scroll up or down to increase or decrease volume.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> desktop-environment <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:custom</span>
  (desktop-environment-screenshot-directory <span style="color: #8b2252;">"~/Bilder"</span>)
  (desktop-environment-volume-normal-decrement <span style="color: #8b2252;">"-5%"</span>)
  (desktop-environment-volume-normal-increment <span style="color: #8b2252;">"+5%"</span>)
  (desktop-environment-volume-get-command
   <span style="color: #8b2252;">"LC_ALL=C pacmd list-sinks|grep -A 15 '* index'| awk '/volume: front/{ print $5 }' | sed 's/,//g'"</span>)
  (desktop-environment-volume-set-command 
   <span style="color: #b22222;">;; </span><span style="color: #b22222;">auto-detect the active sink.</span>
   <span style="color: #8b2252;">"LC_ALL=C pactl set-sink-volume $(pacmd list-sinks|grep -o '* index.*' | grep -o '</span><span style="color: #008b8b;">:.*</span><span style="color: #8b2252;">' | cut -c 2-) %s"</span>)
  (desktop-environment-volume-small-decrement <span style="color: #8b2252;">"-1%"</span>)
  (desktop-environment-volume-small-increment <span style="color: #8b2252;">"+1%"</span>)
  <span style="color: #483d8b;">:config</span>
  (desktop-environment-mode)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">the sigma and pi commands are optimized for https://www.neo-layout.org/</span>
  (global-set-key (kbd <span style="color: #8b2252;">"M-&#963;"</span>) 'desktop-environment-volume-decrement-slowly)
  (global-set-key (kbd <span style="color: #8b2252;">"M-&#960;"</span>) 'desktop-environment-volume-increment-slowly)
  (global-set-key (kbd <span style="color: #8b2252;">"M--"</span>) 'desktop-environment-volume-decrement)
  (global-set-key (kbd <span style="color: #8b2252;">"M-+"</span>) 'desktop-environment-volume-increment))


(<span style="color: #a020f0;">define-minor-mode</span> <span style="color: #0000ff;">display-volume-mode</span>
  <span style="color: #8b2252;">"Toggle display of volume in mode lines.</span>

<span style="color: #8b2252;">Depends on desktop-environment.</span>

<span style="color: #8b2252;">When Display Time mode is enabled, it queries the volume from</span>
<span style="color: #8b2252;">your system on every displaying using</span>
<span style="color: #8b2252;">desktop-environment-volume-get (which you can customize)."</span>
  <span style="color: #483d8b;">:global</span> t <span style="color: #483d8b;">:group</span> 'desktop-environment
  (<span style="color: #a020f0;">or</span> global-mode-string (<span style="color: #a020f0;">setq</span> global-mode-string '(<span style="color: #8b2252;">""</span>)))
  (<span style="color: #a020f0;">setq</span> display-volume-keymap (make-sparse-keymap))
  (define-key display-volume-keymap (kbd <span style="color: #8b2252;">"&lt;mode-line&gt; &lt;mouse-4&gt;"</span>) 
   'desktop-environment-volume-increment-slowly)
  (define-key display-volume-keymap (kbd <span style="color: #8b2252;">"&lt;mode-line&gt; &lt;mouse-5&gt;"</span>)
   'desktop-environment-volume-decrement-slowly)
  (<span style="color: #a020f0;">setq</span> display-volume-modeline-entry
        '(<span style="color: #483d8b;">:eval</span> (propertize (format <span style="color: #8b2252;">" V:%s%% "</span>(desktop-environment-volume-get))
                            'keymap display-volume-keymap)))
  (<span style="color: #a020f0;">if</span> display-volume-mode
      (<span style="color: #a020f0;">progn</span>
        (<span style="color: #a020f0;">or</span> (memq display-volume-modeline-entry global-mode-string)
            (<span style="color: #a020f0;">setq</span> global-mode-string
                  (append global-mode-string (list display-volume-modeline-entry)))))))

(display-volume-mode)
</pre>
</div>
]]></description>
</item>
<item>
<title>elfeed and emms: listen to podcast with convenience</title>
<link>https://www.draketo.de/software/emacs-tipps.html#elfeed-emms</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#elfeed-emms</guid>
<pubDate>Fri, 25 Feb 2022 18:06:00 +0100</pubDate>

<description><![CDATA[<p>
<a href="https://github.com/skeeto/elfeed">Elfeed</a> enables the nicest podcast integration I know: Treat podcast
entries as regular RSS entries, but hit <code>A</code> to enqueue them in <a href="https://www.gnu.org/software/emms/">emms</a>.
</p>

<p>
Usage:
</p>

<ul class="org-ul">
<li>Prepare emms with <code>M-x emms-playlist-mode-go</code></li>
<li>Update your feeds with <code>M-x elfeed-update</code></li>
<li>Read your feeds with <code>M-x elfeed</code>; hit <code>enter</code> to open an entry, then <code>n</code> and <code>p</code> to switch between them <i>quickly</i> (that’s the speed I wish to have everywhere).</li>
<li>Hit <code>A</code> to enqueue the file in emms.</li>
<li>Start listening to media with <code>M-x emms-start</code>.</li>
<li>Keep queueing up further interesting entries from elfeed.</li>
<li>Do something else while listening :-)</li>
<li>Pause emms with <code>M-x emms-pause</code> when needed.</li>
</ul>
<ul class="org-ul">
<li><a id="ID-ccb70d7e-fda8-43a2-979d-d8b42c100dfa"></a>Setup<br />
<div class="outline-text-3" id="text-org214e89a">
<p>
(needs <a href="#use-package">Initialize use-package</a>)
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> elfeed <span style="color: #483d8b;">:ensure</span> t)
(elfeed-add-feed <span style="color: #8b2252;">"https://www.deutschlandfunk.de/informationen-am-morgen-102.xml"</span>)
(<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">emms-setup</span>)
(emms-all)
(emms-default-players)
(<span style="color: #a020f0;">setq</span> emms-source-file-default-directory <span style="color: #8b2252;">"/path/to/your/media/files/"</span>)
</pre>
</div>

<p>
<span class="timestamp-wrapper"><span class="timestamp">[2022-02-25 Fr]</span></span>
</p>
</div>
</li>
</ul>
]]></description>
</item>
<item>
<title>Save the frame configuration to a register</title>
<link>https://www.draketo.de/software/emacs-tipps.html#window-configuration-to-register</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#window-configuration-to-register</guid>
<pubDate>Sat, 18 Jun 2022 18:15:00 +0200</pubDate>

<description><![CDATA[<p>
With <code>C-x r f LETTER</code> (<code>frame-configuration-to-register</code>) and <code>C-x r j LETTER</code>
(<code>jump-to-register</code>) you can store and restore the the exact
layout of buffers in Emacs.
</p>

<p>
When you use exwm that’s almost a super-power, because you can prepare
several exact window setups for different tasks, but it is also useful
in regular emacs usage
</p>

<p>
This is similar to switching between perspectives in Eclipse, but if
you use exwm, this encompasses <i>all programs</i>.
</p>

<p>
Use the regular window splitting in Emacs (<code>C-x 2</code> for each vertical
split, <code>C-x 3</code> for each horizontal split), then hit <code>C-x r f LETTER</code>
to store the exact setup in the letter LETTER. Then hack away, move
around, split and unify buffers, whatever you need. Then hit <code>C-x r j
LETTER</code> to restore the saved setup, down to the positions of the
cursors in all the files.
</p>

<div class="kasten" id="orge780d26">
<p>
<i>When I have the files in front of me that I need right now and a colleague asks me something, <code>C-x r f a</code> stores the window, <code>C-x 1</code> switches to single-window layout and we look together. When we’re done, <code>C-x r j a</code> restores my context and I continue hacking.</i>
</p>

</div>

<p>
I have not used more than 3 frame-configurations at the same time yet,
but even like that this has already been a huge asset.
</p>

<p>
<i>Aside</i>: You can also use the registers to store content, position in the
file, and even the position of all Emacs windows. For details see
<a href="https://www.emacswiki.org/emacs/Registers">https://www.emacswiki.org/emacs/Registers</a>
</p>


<p>

</p>
]]></description>
</item>
<item>
<title>select pgp key to use for mu4e</title>
<link>https://www.draketo.de/software/emacs-tipps.html#pgp-key-mu4e</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#pgp-key-mu4e</guid>
<pubDate>Sat, 23 Jul 2022 16:35:00 +0200</pubDate>

<description><![CDATA[<p>
If recipients cannot decrypt your emails, check the Mml Secure Key Preferences: 
</p>

<pre class="example">
M-x customize-variable mml-secure-key-preferences
</pre>


<p>
There you can add their key.
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>make-window-dedicated: prevent replacing of buffers</title>
<link>https://www.draketo.de/software/emacs-tipps.html#make-window-dedicated</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#make-window-dedicated</guid>
<pubDate>Fri, 19 Aug 2022 10:13:00 +0200</pubDate>

<description><![CDATA[<p>
When you use commands that open new buffers or can split windows — or
if emms opens videos in exwm buffers — it is annoying when emacs
replaces some content you always want to see. To fix that, you can use make-window-dedicated:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">make-window-dedicated</span> (arg)
  <span style="color: #8b2252;">"Set the current window as dedicated, </span>
<span style="color: #8b2252;">so it will not be chosen as target for other buffers.</span>
<span style="color: #8b2252;">With C-u (ARG != 1; some prefix argument) </span>
<span style="color: #8b2252;">set window as non-dedicated."</span>
  (<span style="color: #a020f0;">interactive</span> <span style="color: #8b2252;">"p"</span>)
  (set-window-dedicated-p nil (<span style="color: #a020f0;">if</span> (= 1 arg) t nil)))
</pre>
</div>

<p>
Usage: 
</p>

<ul class="org-ul">
<li>Enter the window with the buffer you want to keep visible.</li>
<li><code>M-x make-window-dedicated</code> to prevent replacing the buffer.</li>
<li><code>C-u M-x make-window-dedicated</code> in a dedicated window to make it non-dedicated.</li>
</ul>

<p>

</p>
]]></description>
</item>
<item>
<title>Create simple packages (tutorial)</title>
<link>https://www.draketo.de/software/emacs-tipps.html#create-packages</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#create-packages</guid>
<pubDate>Sun, 02 Oct 2022 12:04:00 +0200</pubDate>

<description><![CDATA[<p>
Here’s a complete and quick to read description for creating and
submitting your own Emacs packages. It covers the whole process and
shows how to customize the compilation mode:
</p>

<p>
<a href="https://spin.atomicobject.com/2016/05/27/write-emacs-package/">https://spin.atomicobject.com/2016/05/27/write-emacs-package/</a>
</p>
]]></description>
</item>
<item>
<title>LSP and DAP mode (language server and debug adapter)</title>
<link>https://www.draketo.de/software/emacs-tipps.html#lsp-dap</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#lsp-dap</guid>
<pubDate>Mon, 03 Oct 2022 00:05:00 +0200</pubDate>

<description><![CDATA[<p>
With language servers and debug adapters, Emacs can be used for
languages that require complex IDE support to work efficiently.
</p>

<p>
See <a href="https://emacs-lsp.github.io/dap-mode/page/configuration/">https://emacs-lsp.github.io/dap-mode/page/configuration/</a><br />
and <a href="https://github.com/emacs-lsp/dap-mode">https://github.com/emacs-lsp/dap-mode</a>
</p>

<p>
For Java this does not scale to the source repository at work, but for
Typescript it is good enough.
</p>

<p>
For Javascript <a href="emacs-javascript.html">js2-mode is better</a>.
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Use ido everywhere, except in specific functions</title>
<link>https://www.draketo.de/software/emacs-tipps.html#ido-everywhere-except</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#ido-everywhere-except</guid>
<pubDate>Mon, 31 Oct 2022 08:07:00 +0100</pubDate>

<description><![CDATA[<p>
Ido is great to select existing entries, with <a href="https://github.com/DarwinAwardWinner/ido-completing-read-plus">ido-cr+</a> even more so,
but if I want to create a new one, or just want the last matching
folder, it can be annoying. To precisely disable ido (and ido-cr+)
there, use M-x customize-variable to change
<code>ido-read-file-name-non-ido</code> and <code>ido-cr+-disable-list</code>. I do that in
my ido-preview setup:
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> ido-completing-read+ <span style="color: #483d8b;">:ensure</span> t <span style="color: #483d8b;">:defer</span> 1
  <span style="color: #483d8b;">:config</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">disable ido-cr+ where it does not fit.</span>
  (add-to-list 'ido-cr+-disable-list 'journal t)
  (add-to-list 'ido-cr+-disable-list 'gnus-mime-save-part t)
  (add-to-list 'ido-cr+-disable-list 'bbdb-read-string)
  <span style="color: #483d8b;">:custom</span>
  (ido-cr+-auto-update-blacklist t)
  (ido-cr+-function-whitelist nil)
  (ido-cr+-max-items 30000)
  (ido-cr+-replace-completely nil)
  (ido-ubiquitous-mode t))

(<span style="color: #a020f0;">use-package</span> ido-preview <span style="color: #b22222;">;; </span><span style="color: #b22222;">no need to ensure: it is part of emacs</span>
  <span style="color: #483d8b;">:defer</span> 2
  <span style="color: #483d8b;">:config</span>
  (add-hook 'ido-setup-hook
            (<span style="color: #a020f0;">lambda</span>()
              (define-key ido-completion-map (kbd <span style="color: #8b2252;">"C-M-p"</span>) (lookup-key ido-completion-map (kbd <span style="color: #8b2252;">"C-p"</span>)))
              (define-key ido-completion-map (kbd <span style="color: #8b2252;">"C-M-n"</span>) (lookup-key ido-completion-map (kbd <span style="color: #8b2252;">"C-n"</span>))) <span style="color: #b22222;">; </span><span style="color: #b22222;">currently, this makes nothing. Maybe they'll make C-n key lately.</span>
              (define-key ido-completion-map (kbd <span style="color: #8b2252;">"C-p"</span>) 'ido-preview-backward)
              (define-key ido-completion-map (kbd <span style="color: #8b2252;">"C-n"</span>) 'ido-preview-forward)))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">disable ido where it does not fit.</span>
  (add-to-list 'ido-read-file-name-non-ido 'journal t)
  (add-to-list 'ido-read-file-name-non-ido 'gnus-mime-save-part t)
  <span style="color: #483d8b;">:custom</span>
  (ido-all-frames t)
  (ido-buffer-disable-smart-matches nil)
  (ido-enable-dot-prefix t)
  (ido-enable-flex-matching t)
  (ido-everywhere t)
  (ido-max-work-file-list 10)
  (ido-max-dir-file-cache 20)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">reduce number of prospects to reduce window size changes</span>
  (ido-max-prospects 10)
  (ido-mode (<span style="color: #a020f0;">quote</span> both) nil (ido))
  (ido-read-file-name-non-ido
   '(tramp-rename-these-files tramp-rename-files
     journal gnus-mime-save-part))
  (ido-use-filename-at-point (<span style="color: #a020f0;">quote</span> guess))
  (ido-use-url-at-point t))

<span style="color: #b22222;">;; </span><span style="color: #b22222;">Ignore ido save errors; they can block emacs shutdown on disk-full,</span>
<span style="color: #b22222;">;; </span><span style="color: #b22222;">and the history is not important enough for that.</span>
(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">ido-kill-emacs-hook</span> ()
  (<span style="color: #a020f0;">ignore-errors</span> (ido-save-history)))

<span style="color: #b22222;">;; </span><span style="color: #b22222;">my disable list for ido-cr+:</span>
<span style="color: #b22222;">;; </span><span style="color: #b22222;">(ido-cr+-disable-list </span>
<span style="color: #b22222;">;;  </span><span style="color: #b22222;">'(read-file-name-internal read-buffer</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">internal-complete-buffer todo-add-category</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">gnus-emacs-completing-read gnus-iswitchb-completing-read</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">grep-read-files magit-builtin-completing-read ess-completing-read</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">Info-read-node-name tmm-prompt org-tags-completion-function</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">ffap-read-file-or-url ffap-read-file-or-url-internal</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">sly-read-symbol-name org-olpath-completing-read bbdb-read-string</span>
<span style="color: #b22222;">;;   </span><span style="color: #b22222;">journal gnus-mime-save-part)</span>
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>type-break with image-slideshow from workrave using slideview</title>
<link>https://www.draketo.de/software/emacs-tipps.html#type-break-slideview</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#type-break-slideview</guid>
<pubDate>Mon, 12 Dec 2022 16:11:00 +0100</pubDate>

<description><![CDATA[<p>
Show workrave exercises during typing breaks. Requires <a href="https://www.workrave.org">workrave</a>
installed. This replaces workrave in exwm for me, because workrave
tends to lock up the screen (I do not know why).
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #b22222;">;; </span><span style="color: #b22222;">add demo images to type-break</span>
(<span style="color: #a020f0;">use-package</span> slideview <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:config</span>
  (add-hook 'image-mode-hook 'slideview-mode)
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">type-break-demo-slideview</span> ()
    <span style="color: #8b2252;">"Take a typing break with a training slideshow."</span>
    (<span style="color: #a020f0;">and</span> (get-buffer <span style="color: #8b2252;">"*Slideview*"</span>)
         (kill-buffer <span style="color: #8b2252;">"*Slideview*"</span>))
    (<span style="color: #a020f0;">condition-case</span> ()
        (<span style="color: #a020f0;">progn</span>
          (<span style="color: #a020f0;">with-temp-buffer</span>
            (rename-buffer <span style="color: #8b2252;">"*Slideview*"</span>)
            (<span style="color: #a020f0;">let*</span> ((files (directory-files
                           <span style="color: #8b2252;">"~/.guix-profile/share/workrave/exercises/"</span> t))
                   (len-files (length files))
                   <span style="color: #b22222;">;; </span><span style="color: #b22222;">compensate that random selection of a range</span>
                   <span style="color: #b22222;">;; </span><span style="color: #b22222;">start favors later entries.</span>
                   (compensate 5)
                   (random-exercise-index (- (random len-files) compensate))
                   (starting-exercise-index 
                    (<span style="color: #a020f0;">if</span> (&lt; random-exercise-index compensate)
                        (random (min compensate len-files))
                      random-exercise-index))
                   (excercise (nth starting-exercise-index files)))
              (find-file excercise))
            (<span style="color: #a020f0;">let</span> ((timer (run-with-timer 30 10 'slideview-next-file)))
              <span style="color: #b22222;">;; </span><span style="color: #b22222;">Wait for user to come back.</span>
              (read-event)
                  (type-break-catch-up-event)
              (cancel-timer timer)))
          (kill-buffer <span style="color: #8b2252;">"*Slideview*"</span>))
      (quit
       (read-event)
       (type-break-catch-up-event)
       (<span style="color: #a020f0;">and</span> (get-buffer <span style="color: #8b2252;">"*Slideview*"</span>)
            (kill-buffer <span style="color: #8b2252;">"*Slideview*"</span>)))))
  (add-to-list 'type-break-demo-functions 'type-break-demo-slideview)
  )

</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>find-current-as-root</title>
<link>https://www.draketo.de/software/emacs-tipps.html#find-current-file-as-root</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#find-current-file-as-root</guid>
<pubDate>Mon, 19 Dec 2022 01:05:00 +0100</pubDate>

<description><![CDATA[<p>
<b>THIS IS BROKEN FOR ME AT THE MOMENT! (2024)</b><br />
<b>Error: <code>tramp-get-ls-command: Couldn't find a proper `ls' command</code></b>
</p>

<p>
I often find myself needing to edit a file in <code>/etc/</code>. 
</p>

<p>
To avoid having to remember the tramp syntax for this, I have the
command <code>M-x find-current-as-root</code>. This simply re-opens the current
file in the current buffer with root permissions.
</p>

<p>
To get it, just add the following to your <code>~/.emacs.d/init.el</code> or
<code>~/.emacs</code>:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #b22222;">;;; </span><span style="color: #b22222;">Open files as root - quickly</span>
(<span style="color: #a020f0;">defcustom</span> <span style="color: #a0522d;">find-file-root-prefix</span> <span style="color: #8b2252;">"/sudoedit::"</span>
<span style="color: #8b2252;">"Tramp root prefix to use."</span>)

(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">find-file-as-root</span> ()
  <span style="color: #8b2252;">"Like `ido-find-file, but automatically edit the file with</span>
<span style="color: #8b2252;">root-privileges (using tramp/sudo), if the file is not writable by</span>
<span style="color: #8b2252;">user."</span>
  (<span style="color: #a020f0;">interactive</span>)
  (<span style="color: #a020f0;">let</span> ((file (ido-read-file-name <span style="color: #8b2252;">"Edit as root: "</span>)))
    (<span style="color: #a020f0;">unless</span> (file-writable-p file)
      (<span style="color: #a020f0;">setq</span> file (concat find-file-root-prefix file)))
    (find-file file)))
<span style="color: #b22222;">;; </span><span style="color: #b22222;">or some other keybinding...</span>
<span style="color: #b22222;">;; </span><span style="color: #b22222;">(global-set-key (kbd "C-x F") 'djcb-find-file-as-root)</span>

(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">find-current-as-root</span> ()
  <span style="color: #8b2252;">"Reopen current file as root"</span>
  (<span style="color: #a020f0;">interactive</span>)
  (set-visited-file-name (concat find-file-root-prefix (buffer-file-name)))
  (<span style="color: #a020f0;">setq</span> buffer-read-only nil))

</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>see complete changes with M-x diff-hl-set-reference-rev</title>
<link>https://www.draketo.de/software/emacs-tipps.html#diff-hl-set-reference-rev</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#diff-hl-set-reference-rev</guid>
<pubDate>Tue, 17 Jan 2023 16:08:00 +0100</pubDate>

<description><![CDATA[<p>
When you’re working on a patch series you may want to see not just the
lines changed compared to the last commit, but the change by your
patch series. You can do that in by selecting
the last commit before your changes as reference revision:
</p>

<div class="org-src-container">
<pre class="src src-shell">M-x diff-hl-mode
M-x diff-hl-set-reference-rev RET &lt;revision&gt;
</pre>
</div>

<p>
Now your buffers fringes will highlight added, removed and changed
lines compared to this reference revision.
</p>

<p>
That can come in very handy when you’re creating atomic commits.
</p>

<p>
Or when you step back into a project after a 2 years break to finish a
pull-request.
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Org-Agenda with desktop notifications and Outlook calendar ics</title>
<link>https://www.draketo.de/software/emacs-tipps.html#agenda-notifications-calendar</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#agenda-notifications-calendar</guid>
<pubDate>Tue, 17 Jan 2023 16:57:00 +0100</pubDate>

<description><![CDATA[<p>
This is my emacs OWA calendar setup. Replace <code>example.com</code> and
<code>SECRET</code> by the right values.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> org-agenda
  <span style="color: #483d8b;">:defer</span> 6
  <span style="color: #483d8b;">:custom</span>
  (org-agenda-diary-file <span style="color: #8b2252;">"~/.emacs.d/diaries/calexport"</span>)
  (calendar-mark-diary-entries-flag t)
  (calendar-view-diary-initially-flag t)
  (alert-default-style 'libnotify)
  (appt-disp-window-function 'alert-for-appt)
  (org-agenda-include-diary t)
  (appt-delete-window-function (<span style="color: #a020f0;">lambda</span> ()))
  (org-agenda-clock-consistency-checks
   (<span style="color: #a020f0;">quote</span>
    (<span style="color: #483d8b;">:max-duration</span> <span style="color: #8b2252;">"12:00"</span> <span style="color: #483d8b;">:min-duration</span> 0 <span style="color: #483d8b;">:max-gap</span> <span style="color: #8b2252;">"0:05"</span> <span style="color: #483d8b;">:gap-ok-around</span>
                   (<span style="color: #8b2252;">"4:00"</span> <span style="color: #8b2252;">"12:00"</span>)
                   <span style="color: #483d8b;">:default-face</span>
                   ((<span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"DarkRed"</span>)
                    (<span style="color: #483d8b;">:foreground</span> <span style="color: #8b2252;">"white"</span>))
                   <span style="color: #483d8b;">:overlap-face</span> nil <span style="color: #483d8b;">:gap-face</span> nil <span style="color: #483d8b;">:no-end-time-face</span> nil <span style="color: #483d8b;">:long-face</span> nil <span style="color: #483d8b;">:short-face</span> nil)))
  (org-agenda-clockreport-parameter-plist (<span style="color: #a020f0;">quote</span> (<span style="color: #483d8b;">:link</span> t <span style="color: #483d8b;">:maxlevel</span> 2 <span style="color: #483d8b;">:properties</span> (<span style="color: #8b2252;">"Effort"</span>))))
  (org-agenda-start-with-clockreport-mode nil)
  <span style="color: #483d8b;">:config</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Rebuild the reminders everytime the agenda is displayed</span>
  (add-hook 'org-agenda-finalize-hook (<span style="color: #a020f0;">lambda</span> () (org-agenda-to-appt t)))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Run once when Emacs starts</span>
  (org-agenda-to-appt t)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Activate appointments so we get notifications</span>
  (appt-activate t)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Add calendar, option 3  https://www.ict4g.net/adolfo/notes/emacs/emacs-caldav.html</span>
  (<span style="color: #a020f0;">setq</span> diary-location <span style="color: #8b2252;">"~/.emacs.d/diaries/"</span>)
  (add-hook 'diary-list-entries-hook 'diary-include-other-diary-files)
  (add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files)
  (<span style="color: #a020f0;">setq</span> calendars
        '((<span style="color: #8b2252;">"calexport"</span> . <span style="color: #8b2252;">"https://example.com/owa/SECRET@example.com/SECRET/calendar.ics"</span>)))
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">getcal</span> (url file)
    <span style="color: #8b2252;">"Download ics file and add it to file"</span>
    (<span style="color: #a020f0;">let</span> ((tmpfile (url-file-local-copy url)))
      (icalendar-import-file tmpfile file)
      <span style="color: #b22222;">;; </span><span style="color: #b22222;">fixup %2B (+) from +49 phone numbers ;; TODO: report bug for icalendar-import-file</span>
      (<span style="color: #a020f0;">let</span> ((unhexed (url-unhex-string (buffer-string))))
        (erase-buffer)
        (insert unhexed))
      <span style="color: #b22222;">;; </span><span style="color: #b22222;">preserve previous calendar entries in case of network problems</span>
      (<span style="color: #a020f0;">when</span> (string-blank-p (buffer-string)) (undo))
      (kill-buffer (car (last (split-string tmpfile <span style="color: #8b2252;">"/"</span>))))))
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">getcals</span> ()
    <span style="color: #8b2252;">"Load a set of ICS calendars into Emacs diary files"</span>
    (<span style="color: #a020f0;">interactive</span>)
    (<span style="color: #a020f0;">save-mark-and-excursion</span>
      (<span style="color: #a020f0;">save-window-excursion</span>
        (<span style="color: #a020f0;">with-silent-modifications</span>
          (mapcar #'(<span style="color: #a020f0;">lambda</span> (x)
                    (<span style="color: #a020f0;">let</span> ((file (concat diary-location (car x)))
                          (url (cdr x)))
                      (message (concat <span style="color: #8b2252;">"Loading "</span> url <span style="color: #8b2252;">" into "</span> file))
                      (find-file file)
                      <span style="color: #b22222;">;; </span><span style="color: #b22222;">(flush-lines "^[&amp; ]") ;; if you import ical as non marking</span>
                      (erase-buffer) <span style="color: #b22222;">;; </span><span style="color: #b22222;">to avoid duplicating events</span>
                      (getcal url file)))
                  calendars)))))
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">appt-reparse-diary-file</span> ()
    <span style="color: #8b2252;">"force reparsing the diary file"</span>
    (appt-check t))
  (add-to-list 'midnight-hook 'getcals)
  (add-to-list 'midnight-hook 'appt-reparse-diary-file))
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>Reduce overhead over ssh X11 forwarding</title>
<link>https://www.draketo.de/software/emacs-tipps.html#ssh-x11</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#ssh-x11</guid>
<pubDate>Fri, 21 Jun 2024 00:37:00 +0200</pubDate>

<description><![CDATA[<p>
Popping up dialogs is pretty disturbing when working over SSH X11
forwarding. This disables the dialog boxes and keeps everything within
the Emacs frame.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">setq</span> use-dialog-box nil
      use-system-tooltips nil)
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>VC-mode enables partial commits for every version tracking system (Git, Mercurial, …)</title>
<link>https://www.draketo.de/software/emacs-tipps.html#vc-mode-partial</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#vc-mode-partial</guid>
<pubDate>Fri, 19 Jul 2024 10:27:00 +0200</pubDate>

<description><![CDATA[<p>
Just open the directory with <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html">vc mode</a>, get the diff, adjust the diff,
and commit from there.
</p>

<pre class="example" id="orgbaa53a7">
C-x v d RETURN
= (to show the complete diff)
k on the hunk header to remove the hunk (one part of the diff)
C-c C-s to split a hunk (you can then delete parts)
C-x v v to commit the cleaned diff
</pre>

<p>
To undo a change, just reverse the diff with <code>C-c C-r</code> and then apply
the respective reversed hunk with <code>C-c C-a</code>.
</p>

<p>
Aside: <a href="https://ananthakumaran.in/monky/index.html">monky</a> provides a magit-inspired Mercurial-interface, but with
fewer options than magit itself. It may be a good match if you want to
stage files for commit instead of removing hunks you don’t want to
commit (as is done with vc-mode).
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Minimal face adjustments</title>
<link>https://www.draketo.de/software/emacs-tipps.html#mminimal-face-adjustments</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#mminimal-face-adjustments</guid>
<pubDate>Fri, 11 Oct 2024 21:18:00 +0200</pubDate>

<description><![CDATA[<p>
These are the changes to the default faces that I really need:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(custom-set-faces
 <span style="color: #b22222;">;; </span><span style="color: #b22222;">show VCS additions more strongly.</span>
 '(diff-hl-insert ((t (<span style="color: #483d8b;">:inherit</span> diff-added 
                       <span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"#ccffcc"</span>
                       <span style="color: #483d8b;">:foreground</span> <span style="color: #8b2252;">"green4"</span>))))
 <span style="color: #b22222;">;; </span><span style="color: #b22222;">show the active window with color, because I</span>
 <span style="color: #b22222;">;; </span><span style="color: #b22222;">always had to look twice to search the focus.</span>
 '(mode-line ((t (<span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"light goldenrod"</span>
                  <span style="color: #483d8b;">:foreground</span> <span style="color: #8b2252;">"black"</span>
                  <span style="color: #483d8b;">:box</span> (<span style="color: #483d8b;">:line-width</span> (1 . -1)
                  <span style="color: #483d8b;">:style</span> released-button)))))
 <span style="color: #b22222;">;; </span><span style="color: #b22222;">show org-mode block start and end more strongly.</span>
 '(org-block-begin-line ((t (<span style="color: #483d8b;">:inherit</span> org-meta-line
                             <span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"wheat"</span>))))
 '(org-block-end-line ((t (<span style="color: #483d8b;">:inherit</span> org-meta-line
                           <span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"wheat"</span>))))
 <span style="color: #b22222;">;; </span><span style="color: #b22222;">highlight the region more strongly.</span>
 '(region ((t (<span style="color: #483d8b;">:extend</span> t <span style="color: #483d8b;">:background</span> <span style="color: #8b2252;">"cornsilk"</span>)))))
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>xref/dumb-jump setup for typescript: mouse and keyboard</title>
<link>https://www.draketo.de/software/emacs-tipps.html#xref-dumb-jump-ts</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#xref-dumb-jump-ts</guid>
<pubDate>Fri, 08 Nov 2024 23:59:00 +0100</pubDate>

<description><![CDATA[<p>
Emacs <a href="https://github.com/jacktasia/dumb-jump">dumb jump</a> with ripgrep integration provides faster
jump-to-definition than <code>lsp</code> (language server) solutions and needs no
caching that could go stale (looking at you, IntelliJ).
</p>

<p>
What I want is the single shortcut <code>C-M-g</code> for jump-to-definition when
I’m on a reference and jump-to-references when I’m on a definition.
</p>

<p>
Also I want a CTRL-click mouse action to jump to the definition or
references.
</p>

<p>
This snippet sets up both, as well as <code>C-M-p</code> for jumping backwards.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> dumb-jump <span style="color: #483d8b;">:ensure</span> t <span style="color: #483d8b;">:defer</span> 10
  <span style="color: #483d8b;">:custom</span>
  (dumb-jump-rg-search-args '())
  <span style="color: #483d8b;">:config</span>
  (<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">xref</span>)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">Only use completing-read if you use vertical completion. I use ido, so I do not use it.</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">(setq xref-show-definitions-function #'xref-show-definitions-completing-read</span>
  <span style="color: #b22222;">;;       </span><span style="color: #b22222;">xref-show-xrefs-function       #'xref-show-definitions-completing-read)</span>
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">find-definition-or-references</span> ()
    (<span style="color: #a020f0;">interactive</span>)
    (<span style="color: #a020f0;">let</span> ((buffer-and-point (cons (buffer-name) (point)))
          (xref-prompt-for-identifier nil))
      (<span style="color: #a020f0;">condition-case</span> nil
          (call-interactively 'xref-find-definitions)
        (<span style="color: #ff0000; font-weight: bold;">error</span>
         (<span style="color: #a020f0;">when</span> (equal buffer-and-point (cons (buffer-name (window-buffer)) (point)))
           (call-interactively 'xref-find-references))))))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">add proper typescript handling</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">thanks to https://github.com/amake/.emacs.d/commit/c4307e9605b71d2e603fde9ca4354cd60fac359f#diff-82c647c7e6a8e02d1b94a30268eb483ff5aadf926762a759fcd0f4c5850356bf</span>
  (nconc dumb-jump-language-file-exts
         '((<span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span> <span style="color: #483d8b;">:ext</span> <span style="color: #8b2252;">"ts"</span> <span style="color: #483d8b;">:agtype</span> <span style="color: #8b2252;">"ts"</span> <span style="color: #483d8b;">:rgtype</span> nil)
           (<span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span> <span style="color: #483d8b;">:ext</span> <span style="color: #8b2252;">"tsx"</span> <span style="color: #483d8b;">:agtype</span> <span style="color: #8b2252;">"ts"</span> <span style="color: #483d8b;">:rgtype</span> <span style="color: #8b2252;">"ts"</span>)))
  (nconc dumb-jump-language-comments
         '((<span style="color: #483d8b;">:comment</span> <span style="color: #8b2252;">"//"</span> <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>)))
  (nconc dumb-jump-find-rules
         <span style="color: #b22222;">;; </span><span style="color: #b22222;">Rules translated from link below, except where noted</span>
         <span style="color: #b22222;">;; </span><span style="color: #b22222;">https://github.com/jacktasia/dumb-jump/issues/97#issuecomment-346441412</span>
         '((<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"type"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+(abstract\\s+)?)?class\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"class test"</span> <span style="color: #8b2252;">"export class test"</span> <span style="color: #8b2252;">"abstract class test"</span>
                          <span style="color: #8b2252;">"export abstract class test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"class testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"module"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(declare\\s+)?namespace\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"declare namespace test"</span> <span style="color: #8b2252;">"namespace test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"declare testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"module"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?module\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"export module test"</span> <span style="color: #8b2252;">"module test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"module testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"function"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?(async\\s+)?function\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"function test"</span> <span style="color: #8b2252;">"export function test"</span> <span style="color: #8b2252;">"export async function test"</span>
                          <span style="color: #8b2252;">"async function test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"function testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"variable"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"export\\s+(var|let|const)\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"export var test"</span> <span style="color: #8b2252;">"let test"</span> <span style="color: #8b2252;">"const test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"var testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"variable"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(var|let|const)\\s+JJJ\\s*=\\s*function\\s*\\*?\\s*\</span><span style="color: #8b2252; font-weight: bold;">\</span><span style="color: #ff0000; font-weight: bold;">\</span><span style="color: #8b2252; font-weight: bold;">(</span><span style="color: #8b2252;">\</span><span style="color: #8b2252; font-weight: bold;">\</span><span style="color: #ff0000; font-weight: bold;">\</span><span style="color: #8b2252; font-weight: bold;">)</span><span style="color: #8b2252;">"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"var test = function ()"</span> <span style="color: #8b2252;">"let test = function()"</span> <span style="color: #8b2252;">"const test=function*()"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"var testnot = function ()"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"variable"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?(public|protected|private)\\s+(static\\s+)?(abstract\\s+)?(((get|set)\\s+)|(async\\s+))?JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"public test"</span> <span style="color: #8b2252;">"protected static test"</span> <span style="color: #8b2252;">"private abstract get test"</span>
                          <span style="color: #8b2252;">"export public static set test"</span> <span style="color: #8b2252;">"export protected abstract async test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"public testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"type"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?interface\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"interface test"</span> <span style="color: #8b2252;">"export interface test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"interface testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"type"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?type\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"type test"</span> <span style="color: #8b2252;">"export type test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"type testnot"</span>))
           (<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"enum"</span> <span style="color: #483d8b;">:supports</span> (<span style="color: #8b2252;">"ag"</span> <span style="color: #8b2252;">"grep"</span> <span style="color: #8b2252;">"rg"</span> <span style="color: #8b2252;">"git-grep"</span>) <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                  <span style="color: #483d8b;">:regex</span> <span style="color: #8b2252;">"(export\\s+)?enum\\s+JJJ\\b"</span>
                  <span style="color: #483d8b;">:tests</span> (<span style="color: #8b2252;">"enum test"</span> <span style="color: #8b2252;">"export enum test"</span>)
                  <span style="color: #483d8b;">:not</span> (<span style="color: #8b2252;">"enum testnot"</span>))))
           <span style="color: #b22222;">;; </span><span style="color: #b22222;">Custom definition for public methods without "public" keyword.</span>
           <span style="color: #b22222;">;; </span><span style="color: #b22222;">Fragile! Requires brace on same line.</span>
           <span style="color: #b22222;">;; </span><span style="color: #b22222;">(:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "typescript"</span>
           <span style="color: #b22222;">;;        </span><span style="color: #b22222;">:regex "\\bJJJ\\s*\\(.*\\{"</span>
           <span style="color: #b22222;">;;        </span><span style="color: #b22222;">:tests ("test() {" "test(foo: bar) {")</span>
           <span style="color: #b22222;">;;        </span><span style="color: #b22222;">:not ("testnot() {"))))</span>
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">understand types (this is non-standard for dumb-jump, but seems to work)</span>
  (add-to-list 'dumb-jump-language-contexts '(<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"type"</span> <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                                                    <span style="color: #483d8b;">:left</span> <span style="color: #8b2252;">": "</span> <span style="color: #483d8b;">:right</span> <span style="color: #8b2252;">";</span><span style="color: #8b2252; font-weight: bold;">\\</span><span style="color: #8b2252; font-weight: bold;">|</span><span style="color: #ff0000; font-weight: bold;">\</span><span style="color: #8b2252;">)</span><span style="color: #8b2252; font-weight: bold;">\\</span><span style="color: #8b2252; font-weight: bold;">|</span><span style="color: #8b2252;">,"</span>))
  (add-to-list 'dumb-jump-language-contexts '(<span style="color: #483d8b;">:type</span> <span style="color: #8b2252;">"type"</span> <span style="color: #483d8b;">:language</span> <span style="color: #8b2252;">"typescript"</span>
                                                    <span style="color: #483d8b;">:left</span> <span style="color: #8b2252;">"(type =|interface)"</span>))
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">use dumb-jump as xref-searcher (no setup and fast)</span>
  (add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">use C-M-g as shortcut</span>
  (define-key global-map (kbd <span style="color: #8b2252;">"C-M-g"</span>) 'find-definition-or-references)
  (define-key dumb-jump-mode-map (kbd <span style="color: #8b2252;">"C-M-g"</span>) 'find-definition-or-references)
  (define-key global-map (kbd <span style="color: #8b2252;">"C-M-p"</span>) 'xref-pop-marker-stack)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">setup CTRL-left click handling</span>
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">jump-to-mouse-position</span> (event <span style="color: #228b22;">&amp;optional</span> promote-to-region)
    (<span style="color: #a020f0;">interactive</span> <span style="color: #8b2252;">"e\np"</span>)
    (mouse-set-point event promote-to-region)
    (find-definition-or-references))
  (global-unset-key [C-down-mouse-1])
  (define-key global-map [C-mouse-1] 'jump-to-mouse-position))
</pre>
</div>


<p>

</p>
]]></description>
</item>
<item>
<title>Browse Unicode Letters</title>
<link>https://www.draketo.de/software/emacs-tipps.html#browse-unicode</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#browse-unicode</guid>
<pubDate>Sat, 29 Mar 2025 17:35:00 +0100</pubDate>

<description><![CDATA[<p>
You can browse the letters in the lower unicode planes (nicer than
with a unicode list online) by simply calling <code>M-x describe-char</code> for
a letter and then clicking on the <code>code point in charset</code> link.
</p>

<p>
If you for example have the pointer on the letter <code>⚠</code> (warning sign) and
you use <code>M-x describe-char</code>, then you see something like
</p>

<pre class="example" id="org4815348">
             position: 33357 of 33966 (98%), restriction: &lt;33037-33967&gt;, column: 51
            character: ⚠ (displayed as ⚠) (codepoint 9888, #o23240, #x26a0)
              charset: unicode-bmp (Unicode Basic Multilingual Plane (U+0000..U+FFFF))
code point in charset: 0x26A0
               script: symbol
               syntax: w 	which means: word
             category: .:Base
             to input: type "C-x 8 RET 26a0" or "C-x 8 RET WARNING SIGN"
</pre>

<p>
Click on the <code>code point in charset</code>: <code>26A0</code> and it shows the Unicode
characters from <code>0000</code> to <code>FFFF</code>.
</p>

<p>
For example:
</p>

<pre class="example" id="org79b1da4">
     0 1 2 3 4 5 6 7 8 9 A B C D E F
260x ☀ ☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☎ ☏
261x ☐ ☑ ☒ ☓ ☔ ☕ ☖ ☗ ☘ ☙ ☚ ☛ ☜ ☝ ☞ ☟
262x ☠ ☡ ☢ ☣ ☤ ☥ ☦ ☧ ☨ ☩ ☪ ☫ ☬ ☭ ☮ ☯
263x ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ☿
264x ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏
265x ♐ ♑ ♒ ♓ ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟
266x ♠ ♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ♪ ♫ ♬ ♭ ♮ ♯
267x ♰ ♱ ♲ ♳ ♴ ♵ ♶ ♷ ♸ ♹ ♺ ♻ ♼ ♽ ♾ ♿
268x ⚀ ⚁ ⚂ ⚃ ⚄ ⚅ ⚆ ⚇ ⚈ ⚉ ⚊ ⚋ ⚌ ⚍ ⚎ ⚏
269x ⚐ ⚑ ⚒ ⚓ ⚔ ⚕ ⚖ ⚗ ⚘ ⚙ ⚚ ⚛ ⚜ ⚝ ⚞ ⚟
26Ax ⚠ ⚡ ⚢ ⚣ ⚤ ⚥ ⚦ ⚧ ⚨ ⚩ ⚪ ⚫ ⚬ ⚭ ⚮ ⚯
26Bx ⚰ ⚱ ⚲ ⚳ ⚴ ⚵ ⚶ ⚷ ⚸ ⚹ ⚺ ⚻ ⚼ ⚽ ⚾ ⚿
26Cx ⛀ ⛁ ⛂ ⛃ ⛄ ⛅ ⛆ ⛇ ⛈ ⛉ ⛊ ⛋ ⛌ ⛍ ⛎ ⛏
26Dx ⛐ ⛑ ⛒ ⛓ ⛔ ⛕ ⛖ ⛗ ⛘ ⛙ ⛚ ⛛ ⛜ ⛝ ⛞ ⛟
26Ex ⛠ ⛡ ⛢ ⛣ ⛤ ⛥ ⛦ ⛧ ⛨ ⛩ ⛪ ⛫ ⛬ ⛭ ⛮ ⛯
26Fx ⛰ ⛱ ⛲ ⛳ ⛴ ⛵ ⛶ ⛷ ⛸ ⛹ ⛺ ⛻ ⛼ ⛽ ⛾ ⛿
</pre>

<p>
(but aligned as table)
</p>

<p>
Aside: you can insert any letter by name using <code>M-x insert-char</code>.
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Simple Python Setup with eglot/lsp</title>
<link>https://www.draketo.de/software/emacs-tipps.html#python-setup-eglot</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#python-setup-eglot</guid>
<pubDate>Thu, 03 Apr 2025 22:25:00 +0200</pubDate>

<description><![CDATA[<p>
Setupp Emacs for Python development with eglot and file completion
with ideo. Requires <code>ripgrep</code> and <code>pylsp</code> or similar installed.
</p>

<p>
Use <code>C-c p f</code> to select files in the repository and <code>C-c p s</code> to
search in repositroy files.
</p>

<p>
Open the project files sidebar with <code>C-x C-n</code> to see other files.
</p>

<p>
Setup (needs <a href="#use-package">Initialize use-package</a>):
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #b22222;">;; </span><span style="color: #b22222;">setup in ~/.emacs.d/init.el</span>
(<span style="color: #a020f0;">use-package</span> flycheck-eglot <span style="color: #483d8b;">:defer</span> 30 <span style="color: #483d8b;">:ensure</span> t)
(<span style="color: #a020f0;">use-package</span> flycheck-pycheckers <span style="color: #483d8b;">:defer</span> 30 <span style="color: #483d8b;">:ensure</span> t)
(<span style="color: #a020f0;">use-package</span> flycheck-mypy <span style="color: #483d8b;">:defer</span> 30 <span style="color: #483d8b;">:ensure</span> t)
(<span style="color: #a020f0;">use-package</span> pyvenv <span style="color: #483d8b;">:defer</span> 30 <span style="color: #483d8b;">:ensure</span> t)
(<span style="color: #a020f0;">use-package</span> pyvenv-auto <span style="color: #483d8b;">:defer</span> 31 <span style="color: #483d8b;">:ensure</span> t)

<span style="color: #b22222;">;; </span><span style="color: #b22222;">lsp setup</span>
(<span style="color: #a020f0;">use-package</span> eglot
  <span style="color: #483d8b;">:defer</span> 30
  <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:hook</span> ((python-mode . eglot-ensure) <span style="color: #b22222;">;; </span><span style="color: #b22222;">start eglot for python</span>
         (python-mode . flyspell-prog-mode) <span style="color: #b22222;">;; </span><span style="color: #b22222;">spell checking</span>
         (python-mode . hs-minor-mode) <span style="color: #b22222;">;; </span><span style="color: #b22222;">collapse code</span>
         (python-mode . flycheck-mode) <span style="color: #b22222;">;; </span><span style="color: #b22222;">linter</span>
         <span style="color: #b22222;">;; </span><span style="color: #b22222;">tree-sitter version</span>
         (python-ts-mode . eglot-ensure)
         (python-ts-mode . flyspell-prog-mode)
         (python-ts-mode . hs-minor-mode)
         (python-ts-mode . flycheck-mode)))

<span style="color: #b22222;">;; </span><span style="color: #b22222;">setup with use-package in ~/.emacs.d/init.el</span>
<span style="color: #b22222;">;; </span><span style="color: #b22222;">sidebar</span>
(<span style="color: #a020f0;">use-package</span> dired-sidebar
  <span style="color: #483d8b;">:bind</span> ((<span style="color: #8b2252;">"C-x C-n"</span> . dired-sidebar-toggle-sidebar))
  <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:defer</span> 30
  <span style="color: #483d8b;">:commands</span> (dired-sidebar-toggle-sidebar)
  <span style="color: #483d8b;">:custom</span>
  (dired-sidebar-subtree-line-prefix <span style="color: #8b2252;">"__"</span>)
  (dired-sidebar-theme 'vscode)
  (dired-sidebar-width 40) <span style="color: #b22222;">;; </span><span style="color: #b22222;">for Python</span>
  (dired-sidebar-use-term-integration t)
  <span style="color: #483d8b;">:init</span>
  (add-hook 'dired-sidebar-mode-hook
            (<span style="color: #a020f0;">lambda</span> ()
              (<span style="color: #a020f0;">unless</span> (file-remote-p default-directory)
                (auto-revert-mode))))
  <span style="color: #483d8b;">:config</span>
  (<span style="color: #a020f0;">push</span> 'toggle-window-split dired-sidebar-toggle-hidden-commands)
  (<span style="color: #a020f0;">push</span> 'rotate-windows dired-sidebar-toggle-hidden-commands))

<span style="color: #b22222;">;; </span><span style="color: #b22222;">open files in the project</span>
(<span style="color: #a020f0;">use-package</span> projectile <span style="color: #483d8b;">:ensure</span> t <span style="color: #483d8b;">:defer</span> 1
  <span style="color: #483d8b;">:config</span>
  (projectile-mode)
  (define-key projectile-mode-map (kbd <span style="color: #8b2252;">"C-c p"</span>) 'projectile-command-map)
  (define-key projectile-command-map (kbd <span style="color: #8b2252;">"s"</span>) 'projectile-ripgrep)
  (define-key projectile-command-map (kbd <span style="color: #8b2252;">"f"</span>) 'projectile-find-file)
  (add-to-list 'project-find-functions
    (<span style="color: #a020f0;">lambda</span> (x) (cons 'transient (projectile-project-root x))))
  <span style="color: #483d8b;">:custom</span>
  (projectile-switch-project-action 'projectile-find-file)
  <span style="color: #b22222;">;; </span><span style="color: #b22222;">hide output from too long lines</span>
  (ripgrep-arguments '(<span style="color: #8b2252;">"-M 256"</span>)))

(<span style="color: #a020f0;">use-package</span> ido
  <span style="color: #483d8b;">:config</span>
  (ido-mode 1))
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>reliable auto-revert: disable notify</title>
<link>https://www.draketo.de/software/emacs-tipps.html#auto-revert-notify</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#auto-revert-notify</guid>
<pubDate>Tue, 13 May 2025 23:50:00 +0200</pubDate>

<description><![CDATA[<p>
<code>auto-revert-mode</code> does not reliably update files edited from another
user-account. To fix: 
</p>

<p>
<code>M-x customize-variable</code>, then turn <code>auto-revert-use-notify</code> <b>off</b>
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Emacs shell-mode with full history search</title>
<link>https://www.draketo.de/software/emacs-tipps.html#shell-mode-history</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#shell-mode-history</guid>
<pubDate>Mon, 21 Jul 2025 22:11:00 +0200</pubDate>

<description><![CDATA[<p>
M-x shell provides incremental history search via M-r, then C-r and C-s move through the results.
</p>

<ul class="org-ul">
<li><code>M-r</code>: start incremental search (toggle between string and regexp when repeated)</li>
<li><code>C-r</code>: previous result</li>
<li><code>C-s</code>: next result</li>
</ul>

<p>
<i>In short</i>: M-r does what C-r does in bash, except that moving between results is with C-s and C-r.
</p>

<p>
This resolves the main reason why I couldn’t use shell-mode as daily terminal driver.
</p>

<p>
Setting M-x comint-input-ring-size to 100000 makes it match my HISTSIZE for the shell.
</p>

<p>
C-u M-x shell opens additional shell buffers.
</p>

<p>

</p>
]]></description>
</item>
<item>
<title>Show ansi colors (shell-colors) in any buffer</title>
<link>https://www.draketo.de/software/emacs-tipps.html#ansi-colors</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#ansi-colors</guid>
<pubDate>Thu, 14 Aug 2025 16:40:00 +0200</pubDate>

<description><![CDATA[<p>
To display ansi colors in arbitrary buffers, you can use the <code>ansi-color</code> package:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">ansi-color</span>)
(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">display-ansi-colors</span> ()
  (<span style="color: #a020f0;">interactive</span>)
  (ansi-color-apply-on-region (point-min) (point-max)))
</pre>
</div>

<p>
Just call M-x display-ansi-colors to replace the escapes by the colorized text. For read-only files, you first have to make them editable with <code>C-x C-q</code>.
</p>

<p>
I also use that to colorize my compilation buffer:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">colorize-compilation-buffer</span> ()
  <span style="color: #8b2252;">"show shell colors in the compilation buffer"</span>
  (read-only-mode -1)
  (ansi-color-apply-on-region compilation-filter-start (point))
  (read-only-mode))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
</pre>
</div>


<p>

</p>
]]></description>
</item>
<item>
<title>helm-org-rifle as knowledge base</title>
<link>https://www.draketo.de/software/emacs-tipps.html#org-rifle-knowledge-base</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#org-rifle-knowledge-base</guid>
<pubDate>Thu, 15 Jan 2026 08:21:00 +0100</pubDate>

<description><![CDATA[<p>
To quickly search through my notes, I use <a href="https://github.com/alphapapa/org-rifle">helm-org-rifle</a>. It’s fast,
convenient, and also searches my agenda-files. It may not be new, but
it continues to feel fresh and it just keeps working.
</p>

<p>
To recover some old note, just use <code>M-x know</code> and start typing.
</p>

<p>
To store some note, just use <code>M-x org-capture</code>, then hit <code>k</code> and type
or paste it in.
</p>

<p>
My setup:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">defvar</span> <span style="color: #a0522d;">knowledge-base-filepath</span> <span style="color: #8b2252;">"~/emacs-knowledge-base/know.org"</span> 
 <span style="color: #8b2252;">"Path to the file to read and write the knowledge base"</span>)
(<span style="color: #a020f0;">use-package</span> helm-org-rifle <span style="color: #483d8b;">:ensure</span> t <span style="color: #483d8b;">:defer</span> 10 <span style="color: #483d8b;">:after</span> org-agenda
  <span style="color: #483d8b;">:config</span>
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">know</span>()
    (<span style="color: #a020f0;">interactive</span>)
    (<span style="color: #a020f0;">with-current-buffer</span> (find-file knowledge-base-filepath)
      (helm-org-rifle)))
  (<span style="color: #a020f0;">require</span> '<span style="color: #008b8b;">org-capture</span>) <span style="color: #b22222;">;; </span><span style="color: #b22222;">for the templates</span>
  (add-to-list 'org-capture-templates
                `(<span style="color: #8b2252;">"k"</span> <span style="color: #8b2252;">"knowlege base entry"</span> entry
                  (file ,knowledge-base-filepath)
                 <span style="color: #8b2252;">""</span> <span style="color: #483d8b;">:clock-in</span> t <span style="color: #483d8b;">:clock-resume</span> t)
                t))
</pre>
</div>

<p>

</p>
]]></description>
</item>
<item>
<title>Setup autocrypt for mu4e to import found keys into gpg</title>
<link>https://www.draketo.de/software/emacs-tipps.html#mu4e-autocrypt-import-keys</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/emacs-tipps.html#mu4e-autocrypt-import-keys</guid>
<pubDate>Thu, 05 Feb 2026 08:52:00 +0100</pubDate>

<description><![CDATA[<ul class="org-ul">
<li>setup <code>autocrypt-mode</code> for all mail clients</li>
<li>on sending with mu4e, import all keys autocrypt found into gpg</li>
</ul>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">use-package</span> autocrypt <span style="color: #483d8b;">:ensure</span> t
  <span style="color: #483d8b;">:config</span>
  (add-hook 'message-mode-hook #'autocrypt-mode)
  (<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">autocrypt-import-known-keydata</span> ()
    (<span style="color: #a020f0;">interactive</span>)
    <span style="color: #8b2252;">"Import the key data of the current recipients into GPG so default message encrypting works."</span>
    (<span style="color: #a020f0;">dolist</span> (account (autocrypt-list-recipients))
      (<span style="color: #a020f0;">let</span> ((keydata (autocrypt-generate-header account)))
        (<span style="color: #a020f0;">when</span> keydata
          (<span style="color: #a020f0;">with-temp-buffer</span>
            (insert keydata)
            (goto-char (point-min))
            (kill-line) <span style="color: #b22222;">;; </span><span style="color: #b22222;">first line of the header is metadata</span>
            (insert <span style="color: #8b2252;">"-----BEGIN PGP PUBLIC KEY BLOCK-----\n"</span>)
            (goto-char (point-max))
            (insert <span style="color: #8b2252;">"\n-----End PGP PUBLIC KEY BLOCK-----\n"</span>)
            (epa-import-keys-region (point-min) (point-max)))))))
  (add-hook 'mu4e-compose-post-hook #'autocrypt-import-known-keydata))
</pre>
</div>


<p>

</p>
]]></description>
</item>
</channel>
</rss>
