<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on ~/thomas-bergheim</title>
    <link>https://blog.thomasbergheim.com/posts/</link>
    <description>Recent content in Posts on ~/thomas-bergheim</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 05 Nov 2025 13:30:30 +0100</lastBuildDate><atom:link href="https://blog.thomasbergheim.com/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Emacs shell-mode</title>
      <link>https://blog.thomasbergheim.com/posts/you_only_need_shell_mode/</link>
      <pubDate>Sat, 25 Oct 2025 18:04:00 +0200</pubDate>
      
      <guid>https://blog.thomasbergheim.com/posts/you_only_need_shell_mode/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://blog.thomasbergheim.com/ox-hugo/emacs-shell-mode.webp&#34;
    alt=&#34;Figure 1: Emacs shell-mode integrations. dired/dirvish for navigation, woman for manuals, and orderless for narrowing completions.&#34;&gt;&lt;figcaption&gt;
      &lt;p&gt;&lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;Emacs shell-mode integrations. dired/&lt;a href=&#34;https://github.com/alexluigit/dirvish&#34;&gt;dirvish&lt;/a&gt; for navigation, &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_mono/woman.html&#34;&gt;woman&lt;/a&gt; for manuals, and &lt;a href=&#34;https://github.com/oantolin/orderless&#34;&gt;orderless&lt;/a&gt; for narrowing completions.&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A while back I replaced &lt;a href=&#34;https://github.com/alacritty/alacritty&#34;&gt;alacritty&lt;/a&gt; with &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/emacs/Shell-Mode.html&#34;&gt;shell-mode&lt;/a&gt; for (almost) everything.&lt;/p&gt;
&lt;p&gt;Emacs has a way of slowly expropriating most of your (other) operating system. Note taking, emails, file management, IRC, vim keybindings, you name it. You start to live inside Emacs. Everything is just text. Once you get used to it, life outside is not so nice anymore. Which makes it weird that after all these years I never got used to a terminal (the most text based thing ever) based workflow in Emacs. I just kept on using alacritty.&lt;/p&gt;</description>
      <content type="html"><![CDATA[<figure><img src="/ox-hugo/emacs-shell-mode.webp"
    alt="Figure 1: Emacs shell-mode integrations. dired/dirvish for navigation, woman for manuals, and orderless for narrowing completions."><figcaption>
      <p><span class="figure-number">Figure 1: </span>Emacs shell-mode integrations. dired/<a href="https://github.com/alexluigit/dirvish">dirvish</a> for navigation, <a href="https://www.gnu.org/software/emacs/manual/html_mono/woman.html">woman</a> for manuals, and <a href="https://github.com/oantolin/orderless">orderless</a> for narrowing completions.</p>
    </figcaption>
</figure>

<p>A while back I replaced <a href="https://github.com/alacritty/alacritty">alacritty</a> with <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Shell-Mode.html">shell-mode</a> for (almost) everything.</p>
<p>Emacs has a way of slowly expropriating most of your (other) operating system. Note taking, emails, file management, IRC, vim keybindings, you name it. You start to live inside Emacs. Everything is just text. Once you get used to it, life outside is not so nice anymore. Which makes it weird that after all these years I never got used to a terminal (the most text based thing ever) based workflow in Emacs. I just kept on using alacritty.</p>
<p>I think it took so much time because I tried to bend Emacs shells to my existing terminal, rather than make them fit Emacs. My shell does not feel like my old terminal anymore. It feels better!</p>
<blockquote>
<p>I use terminals less and less though. As you get comfortable with Emacs, you start replacing things with Emacs alternatives. dired, proced, mu4e, etc.</p>
<p>Still, old habits die hard. It&rsquo;s nice to have a shell sometimes.</p>
</blockquote>
<h2 id="so-why-shells-in-emacs">So why shells in Emacs?</h2>
<p>I&rsquo;m pretty happy with my zsh and tmux setup. Vim keybindings, clipboard integration - even over ssh. It&rsquo;s not bad. But it&rsquo;s not Emacs. As I move more and more workflows into Emacs I&rsquo;ve come to expect things like <a href="https://github.com/oantolin/orderless">orderless</a>, <a href="https://github.com/minad/corfu">corfu</a> and <a href="https://karthinks.com/software/fifteen-ways-to-use-embark/">embark</a> (amazing completions and selection actions) regardless of what I do, and this has no equivalent in Linux-land. Being able to use the same interface for absolutely <strong>everything</strong> is such a joy. Same colors, fonts, everything. Pretty pretty preeeetty good.</p>
<p>So while my Emacs shell experience was lacking, I knew that with some tlc and time it would most likely be better (by law of <del>Markov chains</del> Emacs; this has so far been the case for every other thing Emacs has gobbled up).</p>
<p>A few things I wanted:</p>
<ol>
<li>Immediate access to the shell I want. My tmux setup for this is pretty good. I don&rsquo;t want to spend time browsing for shell buffers</li>
<li>zsh, so I can share history easily. A good fall back, and I still use an external terminal for long running processes and remote sessions</li>
<li>A shared <code>.zshrc</code> config which disables things like <code>fzf</code>, <code>vi</code> and pagers when you start it from Emacs</li>
<li>Auto-complete that rivals fzf</li>
<li>Perfect <code>evil-mode</code> compatibility</li>
<li>A regular Emacs buffer!</li>
</ol>
<p>I want to stress that I intentionally do <strong>not</strong> want to use things like fzf or pagers like less or <a href="https://github.com/sharkdp/bat">bat</a> in my shell (Emacs is a superior pager) if I can avoid it because that means I am no longer using my unified Emacs interface (but crutches for an inferior experience 😉). No shade on fzf or anything - great tools, I use them still in a regular shell. But I want my Emacs shell to be a regular Emacs buffer, so I can grep the buffer using <a href="https://github.com/minad/consult">consult-line</a>, get history completions using <code>consult-history</code> etc.</p>
<h2 id="shell-alternatives">Shell alternatives</h2>
<p>Emacs has a bunch of shells. More than I list here. But as far as I know these are the biggest players:</p>
<ol>
<li><code>eshell</code>. A shell made in lisp. Sounds like heaven for an emacsyan<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, but it is slow, especially over TRAMP (every command is an ssh command), and since it is not a real terminal lots of things will not work here</li>
<li><code>vterm</code>. It is its own thing (you have to be able to compile libvterm), so it doesn&rsquo;t integrate into Emacs as well as the others do. Has some troubles with display artifacts. It is the fastest Emacs terminal. Not for me as at that point I might as well just use an external terminal (which will not have any rendering issues)</li>
<li><code>eat</code>. This is interesting indeed. It is fast, it supports most TUI things. Unfortunately I couldn&rsquo;t really get it to work with <code>evil-mode</code>, <code>completion-mode</code> etc in ways that was enjoyable. Seems to be <a href="https://codeberg.org/akib/emacs-eat/issues/237">abandoned</a></li>
<li><code>shell-mode</code>. I thought this would be the last thing I&rsquo;d like as it&rsquo;s.. Slower. Not compatible with ncurses (TUI) programs. Turns out it&rsquo;s great. Since it&rsquo;s just a regular Emacs buffer, you can use everything you normally use in Emacs!</li>
</ol>
<p>So despite the limitations I ended up with shell. It integrates so well with Emacs it is just perfect. That is it slower than vterm doesn&rsquo;t really matter much as you don&rsquo;t do things like cat huge files anymore, you open them in a read-only buffer in Emacs instead (which is much better anyway). And I&rsquo;ve basically stopped using terminal/ncurses based apps (replaced with Emacs alternatives) so it does not matter that support for those are sub par.</p>
<p>Note that even if things like tmux will work it will probably not be a great experience, as Emacs will shadow tmux keys. Think of it like running tmux inside screen. Also, most interactive programs, like lazygit, will not work as that is incompatible with the simple input/output model shell-mode operates in.</p>
<h2 id="a-pleasant-tramp-surprise">A pleasant TRAMP surprise</h2>
<p>This ended up being surprisingly ergonomic for remote and sudo things. If you open a file over TRAMP, and then open a shell from that buffer, <strong>you open the shell automatically there</strong>. So say you open some remote caddy config file, and you call <code>tramp-revert-buffer-with-sudo</code> so you can save it, and maybe now you want to reload caddy, well when you fire up the shell from that buffer you have the same access as the file you are viewing. Just type <code>systemctl caddy reload</code>. Done.</p>
<blockquote>
<p>With an external shell, you would open a terminal, ssh to the system, change the directory, possibly elevate your user, change a file, reload the webserver. This is caveman level people! 🤓</p>
</blockquote>
<p>You don&rsquo;t get this kind of integration and DX with an external shell. And you get the normal bookmarks support as well, for quick access to anywhere.</p>
<p>So. Shell it is!</p>
<h2 id="pimp-the-shell-out-of-it">Pimp the shell out of it</h2>
<p>To begin, we make zsh know we are from Emacs, and disable external pagers if we are:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$INSIDE_EMACS</span><span class="s2">&#34;</span> <span class="o">==</span> *<span class="s2">&#34;comint&#34;</span>* <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">YAY_PAGER</span><span class="o">=</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">PAGER</span><span class="o">=</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">GIT_PAGER</span><span class="o">=</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># don&#39;t pop up a menu after a second request for completion - use emacs for it</span>
</span></span><span class="line"><span class="cl">  unsetopt AUTO_MENU
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span></code></pre></div><p>There is no reason why a simple <code>shell-mode</code> should be simple, so lets enable <code>comint-mode</code> for all shells. This makes shell super cool because it means that things like links are now actionable (this is what <code>compile-mode</code> uses). Think error messages with a link to a file; you can just open it from there focused on the reported line number. Also set up completions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">bergheim/setup-shell</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Custom configurations for shell mode.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-input-ring-file-name</span> <span class="s">&#34;~/.histfile&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">comint-read-input-ring</span> <span class="ss">&#39;silent</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">;; stop duplicate input from appearing</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq-local</span> <span class="nv">comint-process-echoes</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">compilation-shell-minor-mode</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">completion-preview-mode</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">;; Don&#39;t add space after file completions (helps with directory traversal)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-completion-addsuffix</span> <span class="no">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">;; Better file completion settings</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-completion-autolist</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-completion-fignore</span> <span class="no">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-use-prompt-regexp</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">;; Improve history handling</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-input-autoexpand</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-completion-recexact</span> <span class="no">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">;; Ensure we can complete from history</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">setq-local</span> <span class="nv">completion-at-point-functions</span>
</span></span><span class="line"><span class="cl">              <span class="p">(</span><span class="nf">list</span> <span class="nf">#&#39;</span><span class="nv">comint-completion-at-point</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">#&#39;</span><span class="nv">comint-filename-completion</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">#&#39;</span><span class="nv">cape-file</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">#&#39;</span><span class="nv">cape-history</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">#&#39;</span><span class="nv">cape-dabbrev</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">&#39;shell-mode-hook</span> <span class="nf">#&#39;</span><span class="nv">bergheim/setup-shell</span><span class="p">)</span>
</span></span></code></pre></div><p><code>cape-dabbrev</code> makes it so that I can complete words present in all my buffers, and it makes writing commands such a breeze.</p>
<p><code>Ctrl-r</code> should use consult-history instead of fzf. Note that I use <a href="https://github.com/noctuid/general.el">general.el</a> for my keybindings:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="c1">;; don&#39;t send C-r to the shell, call our own history function</span>
</span></span><span class="line"><span class="cl"><span class="s">&#34;C-r&#34;</span> <span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nf">goto-char</span> <span class="p">(</span><span class="nf">point-max</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">comint-kill-input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">consult-history</span><span class="p">))</span>
</span></span></code></pre></div><p>Then we need a few convenience things. This is <code>evil-mode</code> specific, but if point is on the actual command line, I want <code>RET</code> in normal mode to send the command without going into insert mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="s">&#34;RET&#34;</span> <span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nv">comint-after-pmark-p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nv">comint-send-input</span><span class="p">)))</span>
</span></span></code></pre></div><p>I want to summon a shell quickly. <a href="https://github.com/kenmanheimer/EmacsMultishell">multishell</a> turns out to be a great helper for this. It&rsquo;s a package designed to help organize <code>shell-mode</code> buffers. By default I want it to open in the current directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">use-package</span> <span class="nv">multishell</span>
</span></span><span class="line"><span class="cl">  <span class="nb">:general</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">bergheim/global-menu-keys</span>
</span></span><span class="line"><span class="cl">    <span class="s">&#34;att&#34;</span> <span class="o">&#39;</span><span class="p">((</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">multishell-pop-to-shell</span> <span class="no">nil</span> <span class="p">(</span><span class="nf">expand-file-name</span> <span class="nv">default-directory</span><span class="p">)))</span> <span class="nb">:which-key</span> <span class="s">&#34;shell&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="s">&#34;atT&#34;</span> <span class="o">&#39;</span><span class="p">((</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">multishell-pop-to-shell</span> <span class="o">&#39;</span><span class="p">(</span><span class="mi">4</span><span class="p">)))</span> <span class="nb">:which-key</span> <span class="s">&#34;new shell&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">  <span class="nb">:config</span>
</span></span><span class="line"><span class="cl">  <span class="c1">;; don&#39;t ask for history confirmation on quit</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">remove-hook</span> <span class="ss">&#39;kill-buffer-query-functions</span> <span class="nf">#&#39;</span><span class="nv">multishell-kill-buffer-query-function</span><span class="p">))</span>
</span></span></code></pre></div><p>And then another shortcut:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="s">&#34;C-M-&lt;return&gt;&#34;</span> <span class="o">&#39;</span><span class="p">((</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">                 <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                 <span class="p">(</span><span class="nv">multishell-pop-to-shell</span> <span class="no">nil</span> <span class="p">(</span><span class="nf">expand-file-name</span> <span class="nv">default-directory</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">               <span class="nb">:which-key</span> <span class="s">&#34;shell&#34;</span><span class="p">)</span>
</span></span></code></pre></div><blockquote>
<p>I use <code>C-M-RET</code> because in my window manager (i3/sway) I use <code>WIN+RET</code> to open emacsclient and <code>S-WIN-RET</code> to open a terminal. Aligning your shortcuts is highly beneficial!</p>
</blockquote>
<p>Although I rarely use ncurses based applications anymore, having rudimentary support for it is still nice. <a href="https://elpa.gnu.org/devel/coterm.html">coterm</a> adds support for some basic TUI programs like top:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">use-package</span> <span class="nv">coterm</span>
</span></span><span class="line"><span class="cl">  <span class="nb">:after</span> <span class="nv">shell</span>
</span></span><span class="line"><span class="cl">  <span class="nb">:config</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">coterm-mode</span> <span class="mi">1</span><span class="p">))</span>
</span></span></code></pre></div><blockquote>
<p>(<a href="https://github.com/szermatt/mistty">mistty</a> is a newer package for this that I have not tried, but it tries to fix some of these things)</p>
</blockquote>
<p>Because I run projects using <code>compile-mode</code> I only need one shell per project (if any).</p>
<blockquote>
<p><code>compile-mode</code> makes it sound like it is made for things like <code>make build</code> commands that has a start and end. At least it did for me. But it is for everything - like for instance your <code>npm run dev</code> command that never ends</p>
</blockquote>
<p>So I want to be able to open my project shell easily. That&rsquo;s easy indeed - just bind <code>project-shell</code>. Lets also add a few other convenience shortcuts. If you call project-shell outside of a project, your project list will open, and you boot your shell into there. Pretty handy.</p>
<p>A few useful keybindings:</p>
<dl>
<dt><code>SPC bt</code></dt>
<dd>Switch between buffer terminals</dd>
<dt><code>SPC at</code></dt>
<dd>Open menu with all terminals (eat, eshell, etc)</dd>
<dt><code>SPC att</code></dt>
<dd>Open default terminal (shell in current directory)</dd>
<dt><code>SPC atT</code></dt>
<dd>Run multishell (start shell in any location)</dd>
</dl>
<blockquote>
<p>I use <code>t</code> for terminal instead of <code>s</code> for shell as I feel t is more fitting and that leaves <code>s</code> open for the search mnemonic</p>
</blockquote>
<p>This is how I switch between all shells:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">bergheim/switch-to-shell</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Switch to an active shell buffer using completion with directory info.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">if-let</span> <span class="p">((</span><span class="nv">shell-buffers</span> <span class="p">(</span><span class="nv">seq-filter</span> <span class="p">(</span><span class="nb">lambda</span> <span class="p">(</span><span class="nv">buf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                        <span class="p">(</span><span class="nb">with-current-buffer</span> <span class="nv">buf</span>
</span></span><span class="line"><span class="cl">                                          <span class="p">(</span><span class="nv">derived-mode-p</span> <span class="ss">&#39;shell-mode</span> <span class="ss">&#39;eshell-mode</span> <span class="ss">&#39;term-mode</span> <span class="ss">&#39;vterm-mode</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">                                      <span class="p">(</span><span class="nf">buffer-list</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">let*</span> <span class="p">((</span><span class="nv">candidates</span> <span class="p">(</span><span class="nf">mapcar</span> <span class="p">(</span><span class="nb">lambda</span> <span class="p">(</span><span class="nv">buf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                   <span class="p">(</span><span class="nf">cons</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;%s (%s)&#34;</span>
</span></span><span class="line"><span class="cl">                                                 <span class="p">(</span><span class="nf">buffer-name</span> <span class="nv">buf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                 <span class="p">(</span><span class="nb">with-current-buffer</span> <span class="nv">buf</span>
</span></span><span class="line"><span class="cl">                                                   <span class="p">(</span><span class="nv">abbreviate-file-name</span> <span class="nv">default-directory</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">                                         <span class="nv">buf</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                                 <span class="nv">shell-buffers</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">             <span class="p">(</span><span class="nv">choice</span> <span class="p">(</span><span class="nf">completing-read</span> <span class="s">&#34;Switch to shell: &#34;</span> <span class="nv">candidates</span> <span class="no">nil</span> <span class="no">t</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">switch-to-buffer</span> <span class="p">(</span><span class="nv">alist-get</span> <span class="nv">choice</span> <span class="nv">candidates</span> <span class="no">nil</span> <span class="no">nil</span> <span class="nf">#&#39;</span><span class="nv">string=</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">message</span> <span class="s">&#34;No active shell buffers&#34;</span><span class="p">)))</span>
</span></span></code></pre></div><p>Also, <a href="https://www.masteringemacs.org/article/disabling-prompts-emacs">I <strong>hate</strong> confirmations</a>. If I want to quit my terminal let me quit my terminal:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="c1">;; don&#39;t ask for history confirmation on quit</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">remove-hook</span> <span class="ss">&#39;kill-buffer-query-functions</span> <span class="nf">#&#39;</span><span class="nv">multishell-kill-buffer-query-function</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">comint-check-proc</span> <span class="no">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">confirm-kill-processes</span> <span class="no">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">advice-add</span> <span class="ss">&#39;shell-mode</span> <span class="nb">:after</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">              <span class="p">(</span><span class="nv">remove-hook</span> <span class="ss">&#39;kill-buffer-query-functions</span>
</span></span><span class="line"><span class="cl">                           <span class="ss">&#39;comint-kill-buffer-query-function</span> <span class="no">t</span><span class="p">)))</span>
</span></span></code></pre></div><h2 id="tl-dr">tl;dr</h2>
<p>You can now:</p>
<ol>
<li>quickly jump to and between shells</li>
<li>one-command open project or location based shells</li>
<li>open shells remotely when you use TRAMP</li>
<li>use some TUI apps if you want (using coterm)</li>
</ol>
<p>All the code for this is <a href="https://github.com/bergheim/dotfiles/blob/f52d9cf104bbdf4e44fdf0f9d7692a5272a20ec2/.config/emacs/modules/apps.el#L34">available in my dotfiles</a>.</p>
<h2 id="current-issues">Current issues <code>[1/5]</code>:</h2>
<p>Of course, everything is not perfect:</p>
<ol>
<li><input disabled="" type="checkbox"> if you ssh to a remote computer, your history will still be your local one. I&rsquo;ve spent a bit of time trying to get shell-mode to recognize if you are remote, and then make your <code>C-r</code> command pass through. I&rsquo;ve also experimented with sending the remote history back to you, but this got crazy fast. At the moment my solution to that is to just use vterm or an external terminal emulator</li>
<li><input disabled="" type="checkbox"> similarly, completions won&rsquo;t work because <code>default-directory</code> will not be updated and correct when you are on a remote system</li>
<li><input disabled="" type="checkbox"> tmux support sux0rs. I have made some things that allow you to list and connect to a window in tmux. So Emacs selects the windows, not tmux. It works, and it&rsquo;s kinda cool to have all the windows and panes in a <code>completing-read</code> buffer, but usage is not great</li>
<li><input disabled="" type="checkbox"> most things that are not strictly line based (print stuff ⮫ get input) will break in various ways. Even vterm will make something like lazygit a worse experience</li>
<li><input checked="" disabled="" type="checkbox"> shell is slow, but I know this, it&rsquo;s fine, it rarely is an issue for me</li>
</ol>
<p>That&rsquo;s it. For local things it works great.</p>
<p>Thank you to <a href="https://www.rahuljuliato.com">Rahul Juliato (LionyxML)</a> for giving me helpful feedback.</p>
<p>I was also let known of a great <a href="https://www.masteringemacs.org/article/running-shells-in-emacs-overview">shell article written by Mickey Petersen, the Mastering Emacs author</a>. It is probably what you should have read instead :p</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>According to my searches you heard this here first!&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content>
    </item>
    
    <item>
      <title>S-SPC broken on emacs-wayland (pgtk)</title>
      <link>https://blog.thomasbergheim.com/posts/s-spc-emacs-wayland-pgtk/</link>
      <pubDate>Wed, 01 Oct 2025 14:19:00 +0200</pubDate>
      
      <guid>https://blog.thomasbergheim.com/posts/s-spc-emacs-wayland-pgtk/</guid>
      <description>&lt;p&gt;Spent way too long debugging why &lt;code&gt;S-SPC&lt;/code&gt; suddenly stopped working - I figured it was my config or some updated package. It was not - I had also switched from &lt;code&gt;emacs&lt;/code&gt; to &lt;code&gt;emacs-wayland&lt;/code&gt; on my system (I use Arch btw), turns out pgtk does not support &lt;code&gt;S-SPC&lt;/code&gt; as it is used by input methods. I don&amp;rsquo;t use it (as far as I am aware) - so &lt;a href=&#34;https://github.com/bergheim/dotfiles/commit/4108ddf642f9670d7263ad41c130e4f0a2f7b646&#34;&gt;disabling it made it work again&lt;/a&gt;:&lt;/p&gt;</description>
      <content type="html"><![CDATA[<p>Spent way too long debugging why <code>S-SPC</code> suddenly stopped working - I figured it was my config or some updated package. It was not - I had also switched from <code>emacs</code> to <code>emacs-wayland</code> on my system (I use Arch btw), turns out pgtk does not support <code>S-SPC</code> as it is used by input methods. I don&rsquo;t use it (as far as I am aware) - so <a href="https://github.com/bergheim/dotfiles/commit/4108ddf642f9670d7263ad41c130e4f0a2f7b646">disabling it made it work again</a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nv">pgtk-use-im-context</span> <span class="no">nil</span><span class="p">)</span>
</span></span></code></pre></div><p>I am using it to <a href="https://github.com/bergheim/dotfiles/blob/6914be36c015eead6cb92a95d6ece324caae5a39/.config/emacs/modules/completion.el#L306">trigger corfu (and orderless)</a>, which turns out after this stopped working has become so essential that I felt like completions were completely broken without it. If you haven&rsquo;t tried setting this up I highly recommend it.</p>
<p>Anyway, maybe this helps some poor soul with the same problem.</p>
<p>Source: <a href="https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-07/msg00071.html">https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-07/msg00071.html</a></p>
]]></content>
    </item>
    
    <item>
      <title>Choose Your Application: embark-open-with for Emacs</title>
      <link>https://blog.thomasbergheim.com/posts/embark-open-with/</link>
      <pubDate>Thu, 07 Aug 2025 14:50:00 +0200</pubDate>
      
      <guid>https://blog.thomasbergheim.com/posts/embark-open-with/</guid>
      <description>&lt;p&gt;I sometimes want to open a file in Emacs with something other than the system default - maybe &lt;a href=&#34;https://okular.kde.org&#34;&gt;okular&lt;/a&gt; instead of &lt;a href=&#34;https://pwmt.org/projects/zathura/&#34;&gt;zathura&lt;/a&gt; for a PDF&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, or a different image viewer for screenshots. This is a perfect case for &lt;a href=&#34;https://github.com/oantolin/embark&#34;&gt;embark&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;embark is this nifty package for emacs that is a bit like a contextual right click system. If you haven&amp;rsquo;t tried it, I highly recommend it. It took me a while to really integrate it into my workflow - honestly because of the overwhelming number of actions you are presented with. So since embark has around a billion actions included, I was a bit surprised to find I could only open files in the default application (&lt;code&gt;embark-open-externally&lt;/code&gt;).&lt;/p&gt;</description>
      <content type="html"><![CDATA[<p>I sometimes want to open a file in Emacs with something other than the system default - maybe <a href="https://okular.kde.org">okular</a> instead of <a href="https://pwmt.org/projects/zathura/">zathura</a> for a PDF<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, or a different image viewer for screenshots. This is a perfect case for <a href="https://github.com/oantolin/embark">embark</a><sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.</p>
<p>embark is this nifty package for emacs that is a bit like a contextual right click system. If you haven&rsquo;t tried it, I highly recommend it. It took me a while to really integrate it into my workflow - honestly because of the overwhelming number of actions you are presented with. So since embark has around a billion actions included, I was a bit surprised to find I could only open files in the default application (<code>embark-open-externally</code>).</p>
<p>Naturally, this being Emacs and more important things needed to be done, I ignored all of that and made this<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">bergheim/embark-open-with</span> <span class="p">(</span><span class="nv">file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Open the current file in &#39;dired-mode&#39; with an application of your choosing.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span> <span class="s">&#34;sOpen externally: &#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nv">string-match-p</span> <span class="s">&#34;\\`[a-z]+://&#34;</span> <span class="nv">file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">setq</span> <span class="nv">file</span> <span class="p">(</span><span class="nf">expand-file-name</span> <span class="nv">file</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">when-let</span> <span class="p">((</span><span class="nv">command</span> <span class="p">(</span><span class="nf">completing-read</span> <span class="s">&#34;Open current file with: &#34;</span>
</span></span><span class="line"><span class="cl">                                       <span class="p">(</span><span class="nv">bergheim//executables-in-path</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">start-process</span> <span class="nv">command</span> <span class="no">nil</span> <span class="nv">command</span> <span class="nv">file</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">bergheim//executables-in-path</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Retrieve a list of all executable files in </span><span class="ss">`exec-path&#39;</span><span class="s">.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">(</span><span class="nv">files-in-path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">dolist</span> <span class="p">(</span><span class="nv">dir</span> <span class="nv">exec-path</span> <span class="nv">files-in-path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nv">when-let</span> <span class="p">((</span><span class="nv">files</span> <span class="p">(</span><span class="nb">and</span> <span class="nv">dir</span> <span class="p">(</span><span class="nf">file-exists-p</span> <span class="nv">dir</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                             <span class="p">(</span><span class="nf">directory-files</span> <span class="nv">dir</span> <span class="no">t</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">dolist</span> <span class="p">(</span><span class="nv">file</span> <span class="nv">files</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nf">file-executable-p</span> <span class="nv">file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                     <span class="p">(</span><span class="nv">not</span> <span class="p">(</span><span class="nf">file-directory-p</span> <span class="nv">file</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nb">push</span> <span class="p">(</span><span class="nf">file-name-nondirectory</span> <span class="nv">file</span><span class="p">)</span> <span class="nv">files-in-path</span><span class="p">)))))))</span>
</span></span></code></pre></div><p>The function prompts you to select from all executable in your PATH and launches the chosen application with the file. Wire it up with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nf">define-key</span> <span class="nv">embark-file-map</span> <span class="s">&#34;X&#34;</span> <span class="nf">#&#39;</span><span class="nv">bergheim/embark-open-with</span><span class="p">)</span>
</span></span></code></pre></div><p>Now when you&rsquo;re in dired or anywhere embark can act on a file, call <code>embark-act</code>, hit  <code>X</code> to get an interactive application picker.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>This blog post has now been a draft for a year; I have since then found <a href="https://github.com/weirdNox/org-noter">org-noter</a> and once again Emacs turns out to be superior.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>karthink has a most excellent post about various embark tricks at <a href="https://karthinks.com/software/fifteen-ways-to-use-embark/">https://karthinks.com/software/fifteen-ways-to-use-embark/</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>This is old code. I was experimenting with using // as a way to signify an internal/private function. Not sure how I feel about that when I published this.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content>
    </item>
    
    <item>
      <title>An old theme throwback</title>
      <link>https://blog.thomasbergheim.com/posts/an-old-theme-throwback/</link>
      <pubDate>Sun, 22 Nov 2020 00:00:00 +0000</pubDate>
      
      <guid>https://blog.thomasbergheim.com/posts/an-old-theme-throwback/</guid>
      <description>&lt;p&gt;I have lost most of my stuff from when I was blogging ages ago, but I have at least one image of an old version I had:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://blog.thomasbergheim.com/ox-hugo/knighthood-v3.jpg&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;I remember I never did finish the navigation part, but I was quite happy with the rest of the design. I made it all myself, mostly in Photoshop and then dividing that into HTML elements. I remember thinking it was cool that I could pipe &lt;code&gt;fortune&lt;/code&gt; to my page. Those were the days of 2advanced, gabo corp, etc.. This was all HTML/CSS though.&lt;/p&gt;</description>
      <content type="html"><![CDATA[<p>I have lost most of my stuff from when I was blogging ages ago, but I have at least one image of an old version I had:</p>
<figure><img src="/ox-hugo/knighthood-v3.jpg">
</figure>

<p>I remember I never did finish the navigation part, but I was quite happy with the rest of the design. I made it all myself, mostly in Photoshop and then dividing that into HTML elements. I remember thinking it was cool that I could pipe <code>fortune</code> to my page. Those were the days of 2advanced, gabo corp, etc.. This was all HTML/CSS though.</p>
<p>It get&rsquo;s you chick.. 😂 That was a play on Slashdot if I recall.</p>
]]></content>
    </item>
    
    <item>
      <title>org-mode &#43; hugo = ❤</title>
      <link>https://blog.thomasbergheim.com/posts/hello-org-mode/</link>
      <pubDate>Mon, 17 Dec 2018 00:00:00 +0000</pubDate>
      
      <guid>https://blog.thomasbergheim.com/posts/hello-org-mode/</guid>
      <description>&lt;p&gt;Hello world!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using &lt;a href=&#34;https://orgmode.org/&#34;&gt;org-mode&lt;/a&gt; for years and I write personal journals in it from time
to time. I also dabble way too much in optimizing how I use it to actually be
productive in it, but I digress..&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve read about blogging from org-mode and publishing that directly to static
sites. I was intrigued, and I somewhat miss blogging, which I haven&amp;rsquo;t done in
probably 10-15 years by now. So here goes, this will be me just trying out
syntax and styles.&lt;/p&gt;</description>
      <content type="html"><![CDATA[<p>Hello world!</p>
<p>I&rsquo;ve been using <a href="https://orgmode.org/">org-mode</a> for years and I write personal journals in it from time
to time. I also dabble way too much in optimizing how I use it to actually be
productive in it, but I digress..</p>
<p>I&rsquo;ve read about blogging from org-mode and publishing that directly to static
sites. I was intrigued, and I somewhat miss blogging, which I haven&rsquo;t done in
probably 10-15 years by now. So here goes, this will be me just trying out
syntax and styles.</p>
<p>If this works as easy as it says on the package, <code>that</code> <span class="underline">would</span> <code>be</code> <em>pretty</em> <strong>cool</strong>.</p>
<p>And <strong>of course</strong> it does! It really is almost ridiculous all the stuff you can do
with org-mode.</p>
<p>Lets try a simple table:</p>
<div class="ox-hugo-table table table-striped table-dark">
<div class="table-caption">
  <span class="table-number">Table 1:</span>
  This is a table
</div>
<table>
  <thead>
      <tr>
          <th>id</th>
          <th>col1</th>
          <th>col2</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>here</td>
          <td>is</td>
      </tr>
      <tr>
          <td>2</td>
          <td>some</td>
          <td>cool</td>
      </tr>
      <tr>
          <td>3</td>
          <td>table</td>
          <td>stuff</td>
      </tr>
  </tbody>
</table>
</div>
<h2 id="evaluations">Evaluations</h2>
<p>Since this is all org-mode, we can evaluate whatever we want and include the
results, on save.</p>
<h3 id="javascript">Javascript</h3>
<p><a id="code-snippet--js-example"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">three</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Hello World and </span><span class="si">${</span><span class="nx">three</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Hello World and 3
</span></span></code></pre></div><h3 id="lisp">Lisp</h3>
<p><a id="code-snippet--lisp-example"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nf">message</span> <span class="s">&#34;Hello from Lisp&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Hello from Lisp
</span></span></code></pre></div><h3 id="c">C</h3>
<p><a id="code-snippet--c-example"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-C" data-lang="C"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;time.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">srand</span><span class="p">(</span><span class="nf">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">res</span> <span class="o">=</span> <span class="nf">rand</span><span class="p">()</span> <span class="o">%</span> <span class="mi">500</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Hello from C %i!&#34;</span><span class="p">,</span> <span class="n">res</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Hello from C 80!
</span></span></code></pre></div><h2 id="well-blimey">Well blimey</h2>
<p>This works really well! How does <a href="http://duckduckgo.com">a link</a> look like?</p>
<h2 id="image-all-the-things">Image all the things! <span class="tag"><span class="ATTACH">ATTACH</span></span></h2>
<p>The images are fetched from my local source (or external) and added on the
fly when we compile this, and then added to the correct post folder
automatically. Pretty fly.</p>
<p>My current wallpaper wallpaper:
<img src="/ox-hugo/gILokWP.jpg" alt=""></p>
<p>Some house:
<img src="/ox-hugo/doublehouse.jpeg" alt=""></p>
<h2 id="lists">Lists</h2>
<h3 id="how-about-a-todo-list">How about a todo list? <code>[2/5]</code></h3>
<ul>
<li><input disabled="" type="checkbox"> Things</li>
<li><input checked="" disabled="" type="checkbox"> I</li>
<li><input disabled="" type="checkbox"> Need</li>
<li><input disabled="" type="checkbox"> To</li>
<li><input checked="" disabled="" type="checkbox"> Do</li>
</ul>
<h2 id="how-about-tags">How about tags? <span class="tag"><span class="test">test</span><span class="_life">@life</span></span></h2>
<p>Does not export. But that&rsquo;s OK - main page title tags apply.</p>
<p>This is great.</p>
]]></content>
    </item>
    
  </channel>
</rss>
