<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Shun's org notes]]></title>
<description><![CDATA[Shun's org notes]]></description>
<link>https://shunueda.org/</link>
<atom:link href="https://shunueda.org/rss.xml" rel="self" type="application/rss+xml" />
<lastBuildDate>Thu, 17 Sep 2026 02:09:33 +0000</lastBuildDate>
<item>
  <title><![CDATA[Rust devshell on macOS]]></title>
  <description><![CDATA[
<p>
When I develop something, I want a devshell that needs nothing but Nix: no Xcode Command Line Tools, no homebrew, no impure global state. Here's my setup for Rust with <a href="https://github.com/nix-community/fenix">fenix</a>:
</p>

<div class="org-src-container">
<pre class="src src-nix"><code>devshells.default = {
  packages =
    with pkgs;
    [
      # ...
      clang
      inputs'.fenix.packages.stable.toolchain
      # ...
    ];

  env = lib.optionals pkgs.stdenv.isDarwin [
    # Without Xcode, clang can't find the macOS SDK, so get it from nixpkgs
    {
      name = "SDKROOT";
      value = pkgs.apple-sdk_26;
    }
    # Some crates (e.g. aws-lc-sys) need -liconv at link time
    {
      name = "LIBRARY_PATH";
      value = "${pkgs.libiconv}/lib";
    }
  ];
};
</code></pre>
</div>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="0">nix</a> <a href="https://shunueda.org/tag-rust.html" class="tag" data-tag="rust" data-index="1">rust</a> </span></div>]]></description>
  <category><![CDATA[nix]]></category>
  <category><![CDATA[rust]]></category>
  <link>https://shunueda.org/2026-08-29--rust-devshell-macos-sdk-and-libiconv.html</link>
  <guid>https://shunueda.org/2026-08-29--rust-devshell-macos-sdk-and-libiconv.html</guid>
  <pubDate>Sat, 29 Aug 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[magit forge auth: gh token in pass]]></title>
  <description><![CDATA[
<p>
<a href="https://docs.magit.vc/forge/">Forge</a> gives you PRs, issues, and code reviews inside Magit, but it needs a GitHub token to hit the API. I don't like either of the stock options:
</p>

<ol class="org-ol">
<li>(Recommended by Forge) Classic tokens are repo-wide at best and account-wide at worst, and a lot of orgs ban them outright.</li>
<li>Fine-grained tokens are scoped per-owner, so I'd need separate tokens for each org, plus a way to switch between them in Forge.</li>
</ol>

<p>
The <a href="https://cli.github.com/">gh CLI</a> already solved the hard part of auth: browser-based OAuth with device flow, SSO included. I don't want to reinvent that, so my (slightly cursed) approach is: let gh do the heavy-lifting, then capture the token, and stash it in <a href="https://www.passwordstore.org/">password-store</a> (pass):
</p>

<div class="org-src-container">
<pre class="src src-bash"><code><span style="font-weight: bold; font-style: italic;">#</span><span style="font-weight: bold; font-style: italic;">!/usr/bin/</span><span style="font-weight: bold;">env</span><span style="font-weight: bold; font-style: italic;"> bash
</span>
<span style="font-weight: bold; font-style: italic;">tmp</span>=$(<span style="font-weight: bold;">mktemp -d</span>)

<span style="font-weight: bold;">trap</span> <span style="font-style: italic;">'rm -rf $tmp'</span> EXIT

<span style="font-weight: bold;">export</span> <span style="font-weight: bold; font-style: italic;">GH_CONFIG_DIR</span>=$<span style="font-weight: bold; font-style: italic;">tmp</span>

<span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">--insecure-storage stores the token as plaintext in GH_CONFIG_DIR instead
</span><span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">of the native keychain. I don't want to pollute the global state, and the
</span><span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">token is persisted in pass.
</span>gh auth login --web --insecure-storage --git-protocol ssh --skip-ssh-key --clipboard

<span style="font-weight: bold; font-style: italic;">token</span>=$(<span style="font-weight: bold;">gh auth token</span>)

&lt;&lt;&lt;<span style="font-style: italic;">"$token"</span> pass insert -mf <span style="font-style: italic;">"ApiKeys/GH_TOKEN"</span>
</code></pre>
</div>

<p>
Now Emacs reads it back out, using <a href="https://www.gnu.org/software/emacs/manual/html_mono/auth.html#The-Unix-password-store">auth-source's native pass support</a>. Forge's API client, <a href="https://github.com/magit/ghub">ghub</a>, asks for a token, and I override <code>ghub--token</code> to pull it from pass:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><code><span style="font-weight: bold; font-style: italic;">;; </span><span style="font-weight: bold; font-style: italic;">Enable pass for auth-source
</span>(auth-source-pass-enable)

(<span style="font-weight: bold;">use-package</span> forge
  <span style="font-weight: bold;">:after</span> magit
  <span style="font-weight: bold;">:config</span>
  (advice-add 'ghub--token <span style="font-weight: bold;">:override</span>
              (<span style="font-weight: bold;">lambda</span> (<span style="font-weight: bold; text-decoration: underline;">&amp;rest</span> _)
                (string-trim (auth-source-pass-get 'secret <span style="font-style: italic;">"ApiKeys/GH_TOKEN"</span>)))))
</code></pre>
</div>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-emacs.html" class="tag" data-tag="emacs" data-index="0">emacs</a> <a href="https://shunueda.org/tag-security.html" class="tag" data-tag="security" data-index="1">security</a> </span></div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[security]]></category>
  <link>https://shunueda.org/2026-08-28--magit-forge-auth-gh-token-in-pass.html</link>
  <guid>https://shunueda.org/2026-08-28--magit-forge-auth-gh-token-in-pass.html</guid>
  <pubDate>Fri, 28 Aug 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[ghq 🤝 project.el]]></title>
  <description><![CDATA[
<p>
I use <a href="https://github.com/x-motemen/ghq">ghq</a> for remote repository management, and I make it integrate with <code>project.el</code>'s project switcher (<code>C-x p p</code>) like this:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span style="font-weight: bold;">use-package</span>
  project
  <span style="font-weight: bold;">:config</span>
  <span style="font-weight: bold; font-style: italic;">;; </span><span style="font-weight: bold; font-style: italic;">Populate the project switcher list from `ghq`
</span>  (<span style="font-weight: bold;">dolist</span>
    (project
      (split-string (shell-command-to-string <span style="font-style: italic;">"ghq list --full-path"</span>)
        <span style="font-style: italic;">"\n"</span>
        t))
    (project--remember-dir (file-name-as-directory project)))
</code></pre>
</div>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-emacs.html" class="tag" data-tag="emacs" data-index="0">emacs</a> </span></div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://shunueda.org/2026-08-18--ghq-and-project-el.html</link>
  <guid>https://shunueda.org/2026-08-18--ghq-and-project-el.html</guid>
  <pubDate>Tue, 18 Aug 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[(macOS) Suppress annoying `xcrun` popup]]></title>
  <description><![CDATA[
<p>
macOS puts a stub at <code>/usr/bin/python3</code> (and friends) that shells out to <code>xcrun</code> to find the real binary. If Xcode Command Line Tools aren't installed, this triggers an annoying GUI popup - which I really don't want since I manage everything through Nix devShells and avoid impure global installs.
</p>


<figure id="org542780a">
<img src="./assets/xcrun.png" alt="xcrun.png">

</figure>

<p>
I looked at the <a href="https://linuxcommandlibrary.com/man/xcrun">manpage</a>, and found that <code>xcrun</code> respects the envvar <code>DEVELOPER_DIR</code>, and wondered if pointing this envvar to a stub <code>xcrun</code> could suppress the popup.
</p>

<div class="org-src-container">
<pre class="src src-nix"><code>let
# Suppress annoying `xcrun` popups
stubDeveloperDir = "${pkgs.linkFarm "stub-developer-dir" [
    {
      name = "usr/bin/xcrun";
      path = pkgs.writeShellScript "stub-xcrun" ''
        &gt;&amp;2 echo "$1: command not found"
        exit 127
      '';
    }
  ]}";
in
...
environment = {
  shells = [ pkgs.bash ];
  variables = {
    DEVELOPER_DIR = stubDeveloperDir;
  };
};
launchd.user.envVariables = {
  DEVELOPER_DIR = stubDeveloperDir;
};
</code></pre>
</div>

<p>
And voila!
</p>

<div class="org-src-container">
<pre class="src src-console"><code>$ python3
python3: command not found
</code></pre>
</div>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-macos.html" class="tag" data-tag="macos" data-index="0">macOS</a> <a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="1">nix</a> </span></div>]]></description>
  <category><![CDATA[macOS]]></category>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-08-14--suppress-annoying-xcrun-popup.html</link>
  <guid>https://shunueda.org/2026-08-14--suppress-annoying-xcrun-popup.html</guid>
  <pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Learning Emacs & Nix]]></title>
  <description><![CDATA[
<p>
Very helpful tutorials that helped me get started:
</p>

<ul class="org-ul">
<li><a href="http://xahlee.info/emacs/index.html">Xah Emacs Tutorial</a></li>
<li><a href="https://code.tvl.fyi/about/nix/nix-1p">Nix - A One Pager</a></li>
</ul>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-emacs.html" class="tag" data-tag="emacs" data-index="0">emacs</a> <a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="1">nix</a> </span></div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-08-05--learning-emacs-and-nix.html</link>
  <guid>https://shunueda.org/2026-08-05--learning-emacs-and-nix.html</guid>
  <pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[(macOS) Manage display resolution via CLI]]></title>
  <description><![CDATA[
<p>
There seem to be no official way to change display resolution from the cli on macOS, but <a href="https://github.com/p00ya/displaymode">p00ya/displaymode</a> worked really well for me. I've fixed few stuffs &amp; Nixified it, so feel free to try it out:
</p>

<div class="org-src-container">
<pre class="src src-console"><code>nix run github:shunueda/monorepo#displaymode
</code></pre>
</div>

<p>
I put this in Home Manager's activation:
</p>

<div class="org-src-container">
<pre class="src src-Nix"><code>home = {
  activation = {
    # Darwin-specific activation script
    darwin = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin (
      lib.hm.dag.entryAfter [ "writeBoundary" ] ''
        # Set display resolution, mine is 14-inch.
        ${lib.getExe pkgs.displaymode} t 1800 1169
      ''
    );
  };
};
</code></pre>
</div>

<p>
<code>p00ya/displaymode</code> is licensed under the Apache-2.0 license.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-macos.html" class="tag" data-tag="macos" data-index="0">macOS</a> <a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="1">nix</a> </span></div>]]></description>
  <category><![CDATA[macOS]]></category>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-07-31--manage-display-resolution-via-cli.html</link>
  <guid>https://shunueda.org/2026-07-31--manage-display-resolution-via-cli.html</guid>
  <pubDate>Fri, 31 Jul 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[TIL: Sieve (mail filtering language)]]></title>
  <description><![CDATA[
<p>
I use Fastmail for my emails, and today I found that you can set a custom mail filtering rule using language called <a href="https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)">Sieve</a>.
</p>

<p>
Apparently there is also a <a href="https://datatracker.ietf.org/doc/html/rfc5804">protocol to manage Sieve script</a>, but Fastmail <a href="https://www.fastmail.help/hc/en-us/articles/360058753814-Sieve-frequently-asked-questions#using">doesn't support it</a> :( I thought of writing a Just script or a Terraform provider, but too bad.
</p>

<p>
However: Fastmail supports <a href="https://www.fastmail.com/dev/">JMAP API</a> (!) so if I <i>really</i> wanted to, I can use <code>SieveScript/set</code> - but I'm too lazy. JMAP is crazytown.
</p>

<p>
Side note, Fastmail is awesome. Highly recommend.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-mail.html" class="tag" data-tag="mail" data-index="0">mail</a> </span></div>]]></description>
  <category><![CDATA[mail]]></category>
  <link>https://shunueda.org/2026-07-21--til-sieve-mail-filtering-language.html</link>
  <guid>https://shunueda.org/2026-07-21--til-sieve-mail-filtering-language.html</guid>
  <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[histsync: sync shell history with pass]]></title>
  <description><![CDATA[
<p>
<a href="https://github.com/atuinsh/atuin">Atuin</a> is super cool: it let's you sync shell history across machine, but few issues for me:
</p>

<ol class="org-ol">
<li>Requires a server. I distrust managed public servers and don't want to host my own.</li>
<li>Heavy LLM usage for development. I have nothing against LLMs but I try to avoid them.</li>
</ol>

<p>
I use <a href="https://www.passwordstore.org/">password-store</a> (pass), so why don't I leverage this:
</p>

<div class="org-src-container">
<pre class="src src-nix"><code>bash = {
  enable = true;
  # ...
  initExtra = ''
    histsync() {
      # Append currently history to HISTFILE
      history -a

      # Entry name in pass - I separate history by host
      local passentry="ShellHistories/$HOSTNAME"

      # Merge HISTFILE and pass entries, remove duplicates, update HISTFILE
      (cat "$HISTFILE" 2&gt;/dev/null; pass show "$passentry" 2&gt;/dev/null) |
        awk '!a[$0]++' |
        ${pkgs.moreutils}/bin/sponge "$HISTFILE"

      # Update pass entry with the merged history
      &lt;"$HISTFILE" pass insert -mf "$passentry"

      # Reload history for current session
      history -c
      history -r
    }

    # ...
  '';
};
</code></pre>
</div>

<p>
Note: the merge logic will not work if you use timestamps.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="0">nix</a> </span></div>]]></description>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-07-16--histsync-sync-shell-history-with-pass.html</link>
  <guid>https://shunueda.org/2026-07-16--histsync-sync-shell-history-with-pass.html</guid>
  <pubDate>Thu, 16 Jul 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Does anyone find Google's AI search useful?]]></title>
  <description><![CDATA[
<p>
I've never found Google's "AI Overview" particularly helpful. It's been more distracting than useful, and worse still, there seems to be no way to turn it off.
</p>

<p>
Since then, I've switched to DuckDuckGo's “No AI” search at <a href="https://noai.duckduckgo.com/">https://noai.duckduckgo.com/</a>, and that has worked well for me.
</p>

<p>
Here's how to configure it in Home Manager. I use Librewolf, but this should work the same way in Firefox:
</p>

<div class="org-src-container">
<pre class="src src-nix"><code>librewolf = {
  enable = true;
  policies = {
    GenerativeAI.Enabled = false; # Bonus: turn off other Firefox AI features
  };
  profiles.&lt;my-profile&gt; = {
    search = {
      force = true;
      default = "ddg-noai";
      engines = {
        "ddg-noai" = {
          urls = [
            {
              template = "https://noai.duckduckgo.com/";
              params = [ (lib.nameValuePair "q" "{searchTerms}") ];
            }
          ];
          definedAliases = [ "@noai" ];
        };
      };
    };
    ...
  };
...
};
</code></pre>
</div>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="0">nix</a> </span></div>]]></description>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-07-06--no-ai-search.html</link>
  <guid>https://shunueda.org/2026-07-06--no-ai-search.html</guid>
  <pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[password-store: nerd snipe quagmire]]></title>
  <description><![CDATA[
<p>
I've been using Apple's Passwords.app, but <a href="https://www.passwordstore.org/">password-store</a> (pass) seemed very cool, and since I already did the heavy-lifting of setting up the YubiKey, I decided to migrate.
</p>

<p>
Another reason that convinced me: <a href="https://www.gnu.org/software/emacs/manual/html_mono/auth.html#The-Unix-password-store">Emacs supports pass as an auth-source natively</a>! Here is a sample:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(auth-source-pass-enable)

(auth-source-pass-get 'secret <span style="font-style: italic;">"foo/bar"</span>)
</code></pre>
</div>

<p>
You can also use <a href="https://git.zx2c4.com/password-store/tree/contrib/emacs/password-store.el">password-store.el</a> to interact with pass via Emacs.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-emacs.html" class="tag" data-tag="emacs" data-index="0">emacs</a> <a href="https://shunueda.org/tag-security.html" class="tag" data-tag="security" data-index="1">security</a> </span></div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[security]]></category>
  <link>https://shunueda.org/2026-07-02--password-store-nerd-snipe-quagmire.html</link>
  <guid>https://shunueda.org/2026-07-02--password-store-nerd-snipe-quagmire.html</guid>
  <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Setting up my YubiKey]]></title>
  <description><![CDATA[
<p>
To manage my GPG key, I set up my YubiKey (5C NFC). This guide was extremely helpful: <a href="https://github.com/drduh/YubiKey-Guide">https://github.com/drduh/YubiKey-Guide</a>.
</p>

<p>
One note: if you're using ed25519 for your signing key, make sure to set <code>KEY_TYPE=cv25519</code> before creating the encryption (E) subkey - GPG will complain otherwise.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-security.html" class="tag" data-tag="security" data-index="0">security</a> </span></div>]]></description>
  <category><![CDATA[security]]></category>
  <link>https://shunueda.org/2026-06-26--setting-up-my-yubikey.html</link>
  <guid>https://shunueda.org/2026-06-26--setting-up-my-yubikey.html</guid>
  <pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Using S3 as a Nix cache]]></title>
  <description><![CDATA[
<p>
Cachix is too expensive so I use S3 (well, technically Cloudflare R2 because it's S3-compatible and egress-free) as a Nix cache, with a following script:
</p>

<div class="org-src-container">
<pre class="src src-bash"><code><span style="font-weight: bold; font-style: italic;">#</span><span style="font-weight: bold; font-style: italic;">!/usr/bin/</span><span style="font-weight: bold;">env</span><span style="font-weight: bold; font-style: italic;"> bash
</span>
<span style="font-weight: bold;">set</span> -euo pipefail

<span style="font-weight: bold; font-style: italic;">signkey</span>=$(<span style="font-weight: bold;">mktemp</span>)

<span style="font-weight: bold;">trap</span> <span style="font-style: italic;">'rm -f $signkey'</span> EXIT

<span style="font-weight: bold;">echo</span> <span style="font-style: italic;">"$NIX_CACHE_SIGNING_KEY"</span> &gt;<span style="font-style: italic;">"$signkey"</span>

nix store sign --key-file <span style="font-style: italic;">"$signkey"</span> --all

nix path-info --all |
  grep -v -E <span style="font-style: italic;">'\.(drv|check|drv\.chroot|lock)$'</span> |
  xargs -n 50 -P 8 sudo -i nix copy --to <span style="font-style: italic;">"$NIX_CACHE_SUBSTITUTER"</span>
</code></pre>
</div>

<p>
Intended for use in CI. Signs everything is the store, filters things we're interested in, and <code>nix copy</code> (in chunks to avoid command being too long) to the backend. Pretty straight forward but works well for me.
</p>

<p>
Side note: if you're using S3 as a Nix store, check this out: <a href="https://github.com/anteriorcore/terraform-aws-s3-nix-lru-cache">anteriorcore/terraform-aws-s3-nix-lru-cache</a>. It uses S3 access logs to GC. Pretty neat.</p>
<div class="taglist"><a href="https://shunueda.org/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://shunueda.org/tag-nix.html" class="tag" data-tag="nix" data-index="0">nix</a> </span></div>]]></description>
  <category><![CDATA[nix]]></category>
  <link>https://shunueda.org/2026-06-20--using-s3-as-a-nix-cache.html</link>
  <guid>https://shunueda.org/2026-06-20--using-s3-as-a-nix-cache.html</guid>
  <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
</item>
</channel>
</rss>
