<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - productivity</title>
    <link>https://emresahin.net/categories/productivity/</link>
    <description>Posts in the productivity category</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/categories/productivity/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>bits 17</title>
      <published>2025-09-28T17:20:37+00:00</published>
      <updated>2025-09-28T17:20:37+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sun, 28 Sep 2025 17:20:37 +0000</pubDate>
      <link>https://emresahin.net/bits-17/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-17/</guid>
      <description>I wanted to calculate the number of words added between commits in my blog posts. I asked Gemini for a Nushell pipeline based on git diff : It proposed the following: git diff --word-diff=plain -- "*.md" | rg -o '\{\+(.*?)\+\}' | str replace -r '\{\+|\+\}' '' | str join " " | str words | length H...</description>
      <category>shell</category>
      <category>productivity</category>
      <category>Gemini</category>
      <category>nushell</category>
      <category>git</category>
      <category>regex</category>
      <category>ai</category>
      <content:encoded><![CDATA[<p>I wanted to calculate the number of words added between commits in my blog posts. I asked Gemini for a Nushell pipeline based on <code>git diff</code>:</p>
<p>It proposed the following:</p>
<pre><code class="language-nushell">git diff --word-diff=plain -- "*.md" | rg -o '\{\+(.*?)\+\}' | str replace -r '\{\+|\+\}' '' | str join " " | str words | length
</code></pre>
<p>However, I ended up using this simplified version:</p>
<pre><code class="language-nushell">git diff --word-diff=plain -- "*.md" | rg -o '\{\+(.*?)\+\}' | str replace -a "{+" "" | str replace -a "+}" "" | str replace -a ' ' "\n" | lines | length
</code></pre>
<p>I’ve noticed that LLMs often lean toward overly complex solutions. I’m not sure if this is due to being trained to generate as many tokens as possible, but using regular expressions where a simple string replacement would suffice is often a sign of unnecessary complexity.</p>]]></content:encoded>
    </item>
    <item>
      <title>bits 13</title>
      <published>2024-11-26T17:28:37+00:00</published>
      <updated>2024-11-26T17:28:37+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 26 Nov 2024 17:28:37 +0000</pubDate>
      <link>https://emresahin.net/bits-13/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-13/</guid>
      <description>I needed a Markdown server to preview my Zettelkasten notes on mobile. I tried installing Lanyon , but its installation instructions are outdated, and the project hasn’t been updated in seven years. I also looked at rustmark , but configuring it simply to list Markdown files felt like too much ef...</description>
      <category>publishing</category>
      <category>productivity</category>
      <category>markdown</category>
      <category>dufs</category>
      <category>zettelkasten</category>
      <category>self-hosting</category>
      <category>lanyon</category>
      <category>rustmark</category>
      <category>go</category>
      <content:encoded><![CDATA[<p>I needed a Markdown server to preview my <a href="https://zettelkasten.de/overview/">Zettelkasten</a> notes on mobile. I tried installing <a href="https://github.com/mkaz/lanyon">Lanyon</a>, but its installation instructions are outdated, and the project hasn’t been updated in seven years.</p>
<p>I also looked at <a href="https://docs.rs/crate/rustmark/latest">rustmark</a>, but configuring it simply to list Markdown files felt like too much effort.</p>
<p>Ultimately, I decided to use <a href="https://github.com/sigoden/dufs">dufs</a> and view the files as plain text. It supports basic file operations and WebDAV, which is more than sufficient for my needs.</p>]]></content:encoded>
    </item>
    <item>
      <title>bits 12</title>
      <published>2024-08-12T09:50:51+00:00</published>
      <updated>2024-08-12T09:50:51+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 12 Aug 2024 09:50:51 +0000</pubDate>
      <link>https://emresahin.net/bits-12/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-12/</guid>
      <description>I decided I needed a random colorscheme selector for those moments when you want to change things up but don’t want to make a specific choice. LazyVim already has &lt;leader&gt;uC for selecting a colorscheme, but it can be too mentally taxing as it requires you to manually select one. This script simpl...</description>
      <category>neovim</category>
      <category>productivity</category>
      <category>colorscheme</category>
      <category>random</category>
      <category>neovim</category>
      <category>lua</category>
      <category>vim</category>
      <content:encoded><![CDATA[<p>I decided I needed a random colorscheme selector for those moments when you want to change things up but don’t want to make a specific choice. LazyVim already has <code>&lt;leader&gt;uC</code> for selecting a colorscheme, but it can be too <em>mentally taxing</em> as it requires you to manually <em>select</em> one. This script simply switches to a random one.</p>
<p><code>RandomColorScheme</code> returns the name of a random colorscheme after searching through all available paths. <code>SetRandomColorScheme</code> sets the colorscheme to that choice. The keybinding is mapped to <code>&lt;leader&gt;uR</code>.</p>
<pre><code class="language-lua">function RandomColorScheme()
  local color_schemes = vim.fn.globpath(vim.o.rtp, "colors/*.vim", false, true)
  for i, fullpath in ipairs(color_schemes) do
    color_schemes[i] = fullpath:match(".*/(.*).vim$")
  end

  -- Generate a random index
  local index = math.random(#color_schemes)

  local random_color_scheme = color_schemes[index]

  vim.notify("Random Color Scheme: " .. random_color_scheme)
  -- Select a random color scheme
  return random_color_scheme
end

function SetRandomColorScheme()
  vim.cmd("colorscheme " .. RandomColorScheme())
end

vim.api.nvim_set_keymap("n", "&lt;leader&gt;uR", ":lua SetRandomColorScheme()&lt;CR&gt;", { noremap = true, silent = true })
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>bits 10</title>
      <published>2024-05-24T21:04:10+00:00</published>
      <updated>2024-05-24T21:04:10+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Fri, 24 May 2024 21:04:10 +0000</pubDate>
      <link>https://emresahin.net/bits-10/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-10/</guid>
      <description>I believe in the value of reducing friction when taking notes. Today, I added a function to my Neovim configuration to create a timestamped file and open it for editing. function CreateTimestampedFile() local zkdir = os.getenv("HOME") .. "/github.com/iesahin/garden/zk/" local timestamp = os.date(...</description>
      <category>tools</category>
      <category>productivity</category>
      <category>neovim</category>
      <category>lazyvim</category>
      <category>zettelkasten</category>
      <category>lua</category>
      <category>note-taking</category>
      <category>workflow</category>
      <content:encoded><![CDATA[<p>I believe in the value of reducing friction when taking notes. Today, I added a function to my Neovim configuration to create a timestamped file and open it for editing.</p>
<pre><code class="language-lua">function CreateTimestampedFile()
  local zkdir = os.getenv("HOME") .. "/github.com/iesahin/garden/zk/"
  local timestamp = os.date("%Y%m%d%H%M%S")
  local filename = zkdir .. "/" .. timestamp .. ".md"
  vim.cmd("edit " .. filename)
end

vim.api.nvim_set_keymap("n", "&lt;leader&gt;F", ":lua CreateTimestampedFile()&lt;CR&gt;", { noremap = true, silent = true })
</code></pre>
<p>Now, I can just hit <code>&lt;leader&gt;F</code> (which is <code>&lt;Space&gt;F</code> in my setup) and immediately start adding a note to my zettelkasten.</p>]]></content:encoded>
    </item>
    <item>
      <title>Regular and Recurring Tasks in todo.txt</title>
      <published>2018-02-06T10:23:22+00:00</published>
      <updated>2018-02-06T10:23:22+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 06 Feb 2018 10:23:22 +0000</pubDate>
      <link>https://emresahin.net/recurrent-todo-txt-14085-74577/</link>
      <guid isPermaLink="true">https://emresahin.net/recurrent-todo-txt-14085-74577/</guid>
      <description>I use the todo.txt format to manage some of my daily tasks. It’s a plain-text format, and both iOS and Android have apps, such as SimpleTasks . Emacs and Vim also support the format. Actually, you don’t need a special editor for it; the format is so simple that even Notepad is sufficient. I have ...</description>
      <category>Productivity</category>
      <category>Automation</category>
      <category>todo.txt</category>
      <category>zsh</category>
      <category>productivity</category>
      <category>cron</category>
      <category>linux</category>
      <content:encoded><![CDATA[<p>I use the <a href="http://todotxt.org/">todo.txt format</a> to manage some of my daily tasks. It’s a
plain-text format, and both iOS and Android have apps, such as
<a href="https://play.google.com/store/apps/details?id=nl.mpcjanssen.todotxtholo">SimpleTasks</a>. <a href="https://github.com/avillafiorita/todotxt-mode">Emacs</a> and <a href="https://github.com/freitass/todo.txt-vim">Vim</a> also support
the format. Actually, you don’t need a special editor for it; the format
is so simple that even Notepad is sufficient.</p>
<p>I have a shell script to add daily recurring tasks, such as “Drink Water” or
“Pray Maghreb,” to this file. SimpleTasks expects the file to be at
<code>$HOME/Dropbox/todo/todo.txt</code>, and I use a template file, such as <code>template.txt</code>,
to populate it. However, as anyone who has used TODO files knows, there are
always unfinished tasks; for instance, I don’t always drink my daily allotted
amount of water.</p>
<p>So, my evening script moves completed tasks (marked as DONE) to their own file,
removes recurring tasks from <code>todo.txt</code>, and repopulates them for a new day.
(Note: The code below is not usable as-is; you must define the <code>TODO</code>, <code>DONE</code>,
and <code>TEMPLATE</code> file paths correctly.)</p>
<pre><code class="language-zsh">
TODO=.../todo.txt
DONE=.../$(date +%F)-done.txt
TEMPLATE=.../template.txt

#Move Done to $DONE
grep -wE '^x ' $TODO &gt;&gt; $DONE
sed -i '/^x /d' $TODO

#Delete lines with @Evening, @Morning or @Regular tags from todo
sed -i "/\b\(@Morning|@Evening|@Regular\)\b/d" $TODO
cat $TODO_TEMPLATE &gt;&gt; $TODO
</code></pre>
<p>I have configured <code>cron</code> to run this every day at 6 PM. (My “evening” starts
earlier than my morning.)</p>]]></content:encoded>
    </item>
  </channel>
</rss>
