<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Emma Jansen]]></title><description><![CDATA[Emma Jansen]]></description><link>https://emma-jansen.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 30 Oct 2026 16:10:42 GMT</lastBuildDate><atom:link href="https://emma-jansen.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A plain-text notes system that's fast to search]]></title><description><![CDATA[How I keep years of writing notes in a folder of Markdown files and find anything in seconds with ripgrep and fzf]]></description><link>https://emma-jansen.hashnode.dev/a-plain-text-notes-system-that-s-fast-to-search</link><guid isPermaLink="true">https://emma-jansen.hashnode.dev/a-plain-text-notes-system-that-s-fast-to-search</guid><category><![CDATA[Productivity]]></category><category><![CDATA[markdown]]></category><category><![CDATA[command line]]></category><category><![CDATA[note-taking]]></category><dc:creator><![CDATA[Emma Jansen]]></dc:creator><pubDate>Wed, 21 Oct 2026 16:17:30 GMT</pubDate><content:encoded><![CDATA[<p>Every writer collects scraps. Half-sentences, interview notes, a quote from a book, a headline idea at 11 p.m. I've tried a lot of note apps for this, and the problem was always the same. Writing a note was easy. Finding it again six weeks later was not.</p>
<p>What finally worked for me is almost embarrassingly simple: a single folder of plain Markdown files and two command-line tools to search it. No sync service lock-in, no database, nothing that breaks when an app changes its pricing.</p>
<h2>The folder</h2>
<p>Everything lives in one directory. I don't use deep folder trees, because I never remember which branch I put something in. Instead the structure is in the file names:</p>
<pre><code>notes/
  2026-10-14-interview-questions.md
  2026-10-17-idea-slow-reading.md
  2026-10-20-quotes-on-editing.md
  inbox.md
</code></pre>
<p>The date at the front sorts everything chronologically for free. The rest of the name is a few words I'd actually search for. <code>inbox.md</code> is where quick scraps go when I don't have time to make a proper note; I empty it once a week.</p>
<h2>A few lightweight conventions</h2>
<p>Search only works if you put the right words in. I keep three small habits:</p>
<ul>
<li><strong>Tags as plain words with a hash</strong>, like <code>#editing</code> or <code>#idea</code>, on the first line. No special syntax needed, any search tool can find them.</li>
<li><strong>One topic per note.</strong> If a note starts covering two things, I split it. Short notes are easier to find and easier to reuse.</li>
<li><strong>Write the question, not just the answer.</strong> "Why do long intros lose readers?" is a much better search target than a bullet list of facts.</li>
</ul>
<h2>Searching with ripgrep</h2>
<p><code>ripgrep</code> (the command is <code>rg</code>) searches the contents of every file in a folder, very quickly. It's my main tool.</p>
<pre><code class="language-bash"># every note that mentions "first sentence", case-insensitive
rg -i "first sentence" ~/notes

# only list the file names
rg -il "first sentence" ~/notes

# all notes tagged #editing
rg -l "#editing" ~/notes

# show two lines of context around each match
rg -i -C 2 "pacing" ~/notes
</code></pre>
<p>Because the folder is just text, results come back almost instantly, even with thousands of notes.</p>
<h2>Picking a result with fzf</h2>
<p><code>fzf</code> is a fuzzy finder. You pipe a list into it and it gives you an interactive filter where you type a few letters and it narrows the list down. Combined with ripgrep, it turns the folder into something that feels like a proper search app.</p>
<p>I wrapped the parts I use daily in three small shell functions in my <code>.bashrc</code>. The first two are for finding things:</p>
<pre><code class="language-bash"># n: find a note by name and open it
n() {
  local f
  f=$(cd ~/notes &amp;&amp; rg --files | fzf --preview 'head -40 {}') || return
  ${EDITOR:-nano} ~/notes/"$f"
}

# ns: search inside notes, then open the chosen match at that line
ns() {
  local hit file line
  hit=$(cd ~/notes &amp;&amp; rg -n -i --no-heading "${1:-.}" | fzf) || return
  file=${hit%%:*}
  line=$(echo "$hit" | cut -d: -f2)
  ${EDITOR:-nano} +"$line" ~/notes/"$file"
}
</code></pre>
<p>Now <code>n</code> lets me type a few letters of a file name, and <code>ns pacing</code> shows every line that mentions pacing, lets me pick one, and opens the note right at that spot. Both <code>nano</code> and <code>nvim</code> understand the <code>+line</code> argument; for other editors you may need to adjust it.</p>
<h2>New notes with one command</h2>
<p>The other half of the problem is friction when capturing. If making a note takes more than a few seconds, I won't do it. So the third function is for writing:</p>
<pre><code class="language-bash"># nn: create a dated note with a slug from the arguments
nn() {
  local slug
  slug=$(echo "$*" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/-$//')
  local f=~/notes/$(date +%F)-${slug:-note}.md
  [ -f "$f" ] || printf '# %s\n\n' "$*" &gt; "$f"
  ${EDITOR:-nano} "$f"
}
</code></pre>
<p><code>nn idea slow reading</code> creates <code>2026-10-21-idea-slow-reading.md</code> with a heading and opens it. That's it.</p>
<h2>What I like about this setup</h2>
<ul>
<li><strong>It's fast.</strong> Searching is quicker than any app I've used, and I never wait for a sync spinner.</li>
<li><strong>It's portable.</strong> The notes open in any editor on any system. If I stop using these tools tomorrow, nothing is lost.</li>
<li><strong>It works with other tools.</strong> Most Markdown editors can open the same folder, so I can still browse the notes visually when I want to. And the folder fits naturally into a Git repository if you want history.</li>
<li><strong>It encourages better notes.</strong> Knowing that I'll search by words makes me write clearer, more specific notes.</li>
</ul>
<h2>What it doesn't do</h2>
<p>It's not great for images or PDFs, and there's no pretty graph of connections between notes. For me that's a fair trade. Most of what I need to find again is a sentence or an idea, and words are exactly what this setup is good at.</p>
<p>If you want to try it, start small: make the folder, install ripgrep and fzf, and copy the <code>nn</code> and <code>ns</code> functions. Use it for a week before you add anything else.</p>
<p>How do you search your own notes? I'm always curious about other people's small shell helpers.</p>
]]></content:encoded></item><item><title><![CDATA[Writing like a developer: my Markdown + Git workflow for prose]]></title><description><![CDATA[For a long time I wrote everything in a word processor. Files were called article_final.docx, then article_final2.docx, and eventually…]]></description><link>https://emma-jansen.hashnode.dev/writing-like-a-developer-my-markdown-git-workflow-for-prose</link><guid isPermaLink="true">https://emma-jansen.hashnode.dev/writing-like-a-developer-my-markdown-git-workflow-for-prose</guid><category><![CDATA[technical writing]]></category><category><![CDATA[markdown]]></category><category><![CDATA[Git]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[writing]]></category><dc:creator><![CDATA[Emma Jansen]]></dc:creator><pubDate>Wed, 21 Oct 2026 15:11:26 GMT</pubDate><content:encoded><![CDATA[<p>For a long time I wrote everything in a word processor. Files were called <code>article_final.docx</code>, then <code>article_final2.docx</code>, and eventually <code>article_REALLY_final.docx</code>. Anyone who writes knows the feeling. Since I switched to plain text in Markdown, with Git underneath, that problem is gone. You don't have to be a developer to work this way. Here's how I do it.</p>
<h3>1. One folder, one file per piece</h3>
<p>Every project gets its own folder, and every piece its own <code>.md</code> file:</p>
<pre><code>writing/
  2026-10-blog-writing-routine.md
  2026-10-newsletter.md
  ideas.md
  README.md
</code></pre>
<p>Putting the date first keeps everything in order automatically. <code>ideas.md</code> is a plain list of loose thoughts. <code>README.md</code> explains in three lines what the folder is for, so I still understand it six months from now.</p>
<h3>2. Frontmatter for metadata</h3>
<p>At the top of every file there's a small YAML block:</p>
<pre><code class="language-yaml">---
title: Why I write every morning
status: draft
tags: [writing, routine]
---
</code></pre>
<p>Plenty of blogging platforms and static site generators read this directly. And I can see at a glance which pieces are still in <code>draft</code>.</p>
<h3>3. One sentence per line</h3>
<p>This sounds odd, but it works really well. I put every sentence on its own line. Markdown joins lines within a paragraph anyway, so readers never notice. The benefit: when I rewrite one sentence, Git shows exactly that one line as changed instead of an entire paragraph.</p>
<h3>4. Small commits with clear messages</h3>
<pre><code class="language-bash">git add 2026-10-blog-writing-routine.md
git commit -m "Shorten intro, add second example"
</code></pre>
<p>I commit after every real writing session. I write the message for myself three months from now: what changed and why. If I want to go back to an earlier version, it's right there in <code>git log</code>.</p>
<h3>5. Look at changes word by word</h3>
<p>A regular <code>git diff</code> compares whole lines. For prose, this is much more useful:</p>
<pre><code class="language-bash">git diff --word-diff
</code></pre>
<p>It shows you, word by word, what was removed and what was added. It's like track changes in a word processor, without the document drowning in red strikethroughs.</p>
<h3>6. Branches for experiments</h3>
<p>Not sure about a different structure for a piece? I create a branch:</p>
<pre><code class="language-bash">git switch -c new-structure
</code></pre>
<p>If it doesn't work, I switch back to <code>main</code> and nothing is lost. If it does, I merge it.</p>
<h3>7. Export when someone wants Word</h3>
<p>Not everyone works in Markdown. With Pandoc you can convert a file in a single line:</p>
<pre><code class="language-bash">pandoc 2026-10-blog-writing-routine.md -o writing-routine.docx
</code></pre>
<p>My source always stays plain text, and the other person gets the format they're used to.</p>
<h3>Why this works better</h3>
<p>Plain text doesn't break, opens in any editor and will still be readable in twenty years. Git gives you a full history without you having to think about it. It takes an afternoon to get used to. After that, you won't want to go back.</p>
<p>How do you manage your writing? I'm curious whether anyone has automated this even further.</p>
]]></content:encoded></item></channel></rss>