<?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 🍃 - neovim</title>
    <link>https://emresahin.net/tags/neovim/</link>
    <description>Posts in the neovim tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 29 Sep 2026 14:57:43 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/neovim/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>devlog 8</title>
      <published>2025-01-04T12:41:16+00:00</published>
      <updated>2025-01-04T12:41:16+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sat, 04 Jan 2025 12:41:16 +0000</pubDate>
      <link>https://emresahin.net/devlog-8/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-8/</guid>
      <description>🐢 The only failure was the patch coverage in Xvc. Let’s see what needs to be done. 🐇 It looks, from the coverage page , that our additions to HStore don’t have any tests. Maybe we can add some unit tests to the new joins. 🐢 I don’t find unit tests particularly useful, but let’s use GitHub Copilot...</description>
      <category>devlog</category>
      <category>Software Development</category>
      <category>xvc</category>
      <category>rust</category>
      <category>coverage</category>
      <category>cargo-publish</category>
      <category>github-copilot</category>
      <category>claude</category>
      <category>dufs</category>
      <category>neovim</category>
      <category>testing</category>
      <content:encoded><![CDATA[<p>🐢 The only failure was the patch coverage in Xvc. Let’s see what needs to be done.</p>
<p>🐇 It looks, from the <a href="https://app.codecov.io/gh/iesahin/xvc/pull/263?src=pr&amp;el=tree&amp;utm_medium=referral&amp;utm_source=github&amp;utm_content=comment&amp;utm_campaign=pr+comments&amp;utm_term=Emre+Sahin">coverage page</a>, that our additions to HStore don’t have any tests. Maybe we can add some unit tests to the new joins.</p>
<p>🐢 I don’t find unit tests particularly useful, but let’s use GitHub Copilot to add some for us.</p>
<p>🐇 I added a unit test and a doc test for <code>full_join</code>. I think doc tests have more value; they provide documentation, and we can readily see how to use a function from its docs. It’s better to increase coverage with doc tests.</p>
<p>🐢 There are things I should keep in mind while writing doc tests. Imports must use the full path, not <code>crate</code>. Also, the tested struct doesn’t have implicit imports.</p>
<p>🐇 The ceremony for adding keys and values is a bit too much. It might be worthwhile to add an <code>insert</code> method for anything that implements <code>Into&lt;XvcEntity&gt;</code>.</p>
<p>🐢 That would certainly save time—no more typing <code>.into()</code> for each key! :)</p>
<p>🐇 Pushed to test again. Should we have some way to test coverage locally?</p>
<p>🐢 I don’t think we need to check coverage locally. It’s not worth our time right now.</p>
<p>🐇 Now, while waiting for the tests to complete, what else can we do?</p>
<pre><code class="language-bash">gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12543831360 3m54s 2024-12-30T08:15:06Z
...
</code></pre>
<p>🐢 That didn’t take too long. Let’s view the results:</p>
<pre><code class="language-bash">gh -R iesahin/xvc run view 12543831360
...
  X Run Current Dev Tests
...
To see what failed, try: 
View this run on GitHub: https://github.com/iesahin/xvc/actions/runs/12543831360
</code></pre>
<p>🐢 The current dev tests are failing for some reason. Let’s run them locally.</p>
<p>🐇 We’re missing <code>llvm-tools-preview</code> locally. How do I install this?</p>
<p>🐢 The command is <code>rustup component add llvm-tools-preview</code>:</p>
<pre><code class="language-text">info: component 'llvm-tools' for target 'aarch64-apple-darwin' is up to date
</code></pre>
<p>🐇 It’s already installed. We just need to set the environment variables.</p>
<p>🐢 Instead, we can just turn off dev tests for the time being. We don’t really need them; our local tests pass.</p>
<p>🐇 Yeah, okay. We don’t need to solve every single bit of these issues right now.</p>
<pre><code class="language-bash">gh -R iesahin/xvc run list
...
</code></pre>
<p>🐇 Okay, let’s take a look at the run again.</p>
<pre><code class="language-bash">gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12544020064 3m39s 2024-12-30T08:33:25Z

gh -R iesahin/xvc run view 12544020064
...
  X Test and Coverage
...

gh run view 12544020064 --log-failed
...
Test and Coverage (stable) Test and Coverage 2024-12-30T08:36:58.8911690Z Error: ProcessError { stdout: "", stderr: "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\ncurl: (7) Failed to connect to e1.xvc.dev port 80 after 160 ms: Couldn't connect to server\n" }
...
</code></pre>
<p>🐢 We need to start Nginx on the server. We forgot to do that yesterday.</p>
<p>🐇 Ah, right. After that <code>dufs</code> installation. Okay.</p>
<p>🐢 We also need to add a reverse proxy for <code>dufs</code> somehow, but that’s for later.</p>
<p>🐇 For this use case, I don’t think it’s necessary. We can just adjust the port to a non-standard one if we need 443 for something else. Let’s look at the tests again.</p>
<p>🐢 Let’s add another doc test, this time to <code>XvcStore</code>.</p>
<pre><code class="language-bash">cargo test -p xvc-ecs --doc
...
test result: ok. 8 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.87s
</code></pre>
<p>🐇 Sent the files again. Waiting for the tests to finish.</p>
<p>🐢 Let’s check the keymaps file in the meantime.</p>
<p>🐇 I tried reading the documentation but didn’t see an error. Maybe we should just set it to non-lazy and disallow remaps.</p>
<p>🐢 We’ve already spent too much time on this.</p>
<p>🐇 Yes, let’s check the tests again.</p>
<pre><code class="language-bash">gh -R iesahin/xvc run list
completed success v0.6.13 Rust-CI v0.6.13 pull_request 12544291068 8m10s 2024-12-30T09:00:42Z
...
</code></pre>
<p>🐢 Oh, nice, the merge is ready.</p>
<p>🐇 Patch coverage is still behind the target, though.</p>
<p>🐢 Yeah, but let’s release this one and ensure the next one is better covered. Also, I’m not sure if the doc tests actually affected the coverage report.</p>
<p>🐇 If we look at the <a href="https://app.codecov.io/gh/iesahin/xvc/pull/263?src=pr&amp;el=tree&amp;utm_medium=referral&amp;utm_source=github&amp;utm_content=comment&amp;utm_campaign=pr+comments&amp;utm_term=Emre+Sahin">coverage page</a> again, we can see.</p>
<p>🐢 It seems codecov.io doesn’t consider coverage for doc tests. That’s a bit weird, but let’s not spend more time on it.</p>
<p>🐇 Sure, let’s merge.</p>
<p>🐢 I think we forgot to bump the versions in the <code>Cargo.toml</code> files. We’ll have to do that in <code>main</code>.</p>
<p>🐇 Oh, yeah. Let’s bump them and tag the release as well.</p>
<p>🐢 Now we can wait for all the files to be produced. What’s next?</p>
<p>🐇 We can release the Python version too. It shouldn’t need any changes.</p>
<p>🐢 Right. Maybe we can add a few tests there as well.</p>
<p>🐇 Let’s bump the version first and see.</p>
<p>🐢 I’ve bumped the versions in <code>Cargo.toml</code> and run <code>maturin develop</code>.</p>
<p>🐇 It seems ready now.</p>
<p>🐢 The main branch is failing, though. The “Publish crates” action is looking for <code>libsqlite3</code>. Let’s investigate.</p>
<pre><code class="language-bash">gh -R iesahin/xvc run list
completed failure Release v0.6.13 Publish Crates v0.6.13 push 12544753359 6m1s 2024-12-30T09:41:56Z
</code></pre>
<p>🐢 The issue is that the VM doesn’t have <code>libsqlite3-dev</code>. Let’s add it.</p>
<p>🐇 We need to restart the job manually. Let’s skip tagging this time.</p>
<p>🐢 Some of the packages were already published, and now they’re causing failures because crates.io says they already exist. Maybe we can check if a package is already published before trying.</p>
<p>🐇 Let’s see if we can make <code>cargo publish</code> more forgiving.</p>
<p>🐢 There doesn’t seem to be an easy option. Let’s search for “how to skip published packages in workspace to avoid errors with cargo publish.”</p>
<p>🐇 Claude is hallucinating again. Let’s try a manual approach: how to skip already published packages?</p>
<p>🐢 It might be easier to just add a check. How do we get that info?</p>
<p>🐇 Or we can just move on to the next package if one is already available.</p>
<p>🐢 Let’s push the missing packages manually this time.</p>
<p>🐢 We should have a key to open garden files quickly. What does <code>Fzf-Lua files</code> receive as arguments?</p>
<p>🐇 Let’s check the help page: <code>fzf-lua</code>.</p>
<p>🐢 Before that, maybe we can try to fix why selected lines are not searched in Visual-Line mode?</p>
<p>🐇 Yep, let’s fix our search first.</p>
<p>🐢 How do you set a key in visual line mode in Neovim Lua?</p>
<p>🐇 The abbreviation is <code>V</code>. Let’s try that.</p>
<p>🐢 Looks like we need to restart the session.</p>
<p>🐇 It’s still not working. Let’s check <code>:map</code>.</p>
<p>🐢 It seems it needs more care; I’ll check it later.</p>
<p>👨🏾‍🦲
🐢 Bence kendini biraz daha anlamlı bir işle uğraştırmalısın.
🐇 Ne gibi?
🐢 Belki biraz daha yayın yapmalısın, biraz daha işe başvurmalısın.
🐇 “Meli”, “malı” ile geçiyor ömrümüz.</p>
<p>⌚
🐢 It looks like we can move most of the daily template to links or commands. We can call it <code>ref/daily</code>. My idea is to fill the page intentionally, without templates.</p>
<p>🐇 It might be better to start with a blank page, yeah. The template makes me a bit nervous. There are too many things to fill in, and most of them aren’t things I like being pushed into doing.</p>
<p>🐢 Let’s start by moving the daily templates to <code>ref/daily</code>. No more daily template.</p>
<p>🐇 Now we can delete the rest of this page. We’ll use the daily links page and maybe have reminders at the end of these sessions.</p>
<p>👨🏽‍⚕️</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>Bits 9</title>
      <published>2024-05-24T21:02:38+00:00</published>
      <updated>2024-05-24T21:02:38+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Fri, 24 May 2024 21:02:38 +0000</pubDate>
      <link>https://emresahin.net/bits-9/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-9/</guid>
      <description>I have quite a few LazyVim plugins, but this simple keymapping makes my life much easier: vim.keymap.set({ "n", "i" }, "&lt;F2&gt;", '&lt;esc&gt;&lt;esc&gt;yy:r!&lt;c-r&gt;"') I type a command, like ls , on a line and hit &lt;F2&gt; . That line is copied, executed, and the output is read into the buffer just below it. I use i...</description>
      <category>Bits</category>
      <category>Tools</category>
      <category>Neovim</category>
      <category>Shell</category>
      <category>LazyVim</category>
      <category>Productivity</category>
      <category>Workflow</category>
      <content:encoded><![CDATA[<p>I have quite a few LazyVim plugins, but this simple keymapping makes my life much easier:</p>
<pre><code class="language-lua">vim.keymap.set({ "n", "i" }, "&lt;F2&gt;", '&lt;esc&gt;&lt;esc&gt;yy:r!&lt;c-r&gt;"')
</code></pre>
<p>I type a command, like <code>ls</code>, on a line and hit <code>&lt;F2&gt;</code>. That line is copied, executed, and the output is read into the buffer just below it.</p>
<p>I use it for all sorts of tasks, from listing open PRs with <code>gh</code> to fetching website text with <code>w3m</code>. It has significantly improved my workflow, allowing me to use the shell effectively within textual notebooks.</p>]]></content:encoded>
    </item>
    <item>
      <title>bits 7</title>
      <published>2024-05-23T16:33:49+00:00</published>
      <updated>2024-05-23T16:33:49+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Thu, 23 May 2024 16:33:49 +0000</pubDate>
      <link>https://emresahin.net/bits-7/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-7/</guid>
      <description>I noticed it’s not possible to unmap the F1 key in Neovim using vim.api.nvim_del_keymap if it’s not already registered. Instead, you can simply override it with something like: vim.keymap.set({ "n" }, "&lt;F1&gt;", ":Telescope buffers&lt;CR&gt;", { noremap = true, desc = "Find buffer" })</description>
      <category>bits</category>
      <category>neovim</category>
      <category>lua</category>
      <category>keymaps</category>
      <category>telescope</category>
      <category>config</category>
      <content:encoded><![CDATA[<p>I noticed it’s not possible to unmap the <code>F1</code> key in Neovim using
<code>vim.api.nvim_del_keymap</code> if it’s not already registered. Instead, you can
simply override it with something like:</p>
<pre><code class="language-lua">vim.keymap.set({ "n" }, "&lt;F1&gt;", ":Telescope buffers&lt;CR&gt;", { noremap = true, desc = "Find buffer" })
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>TIL 11: Unhide Markdown Code Block Types in LazyVim</title>
      <published>2024-02-26T10:22:29+00:00</published>
      <updated>2024-02-26T10:22:29+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 26 Feb 2024 10:22:29 +0000</pubDate>
      <link>https://emresahin.net/til-11/</link>
      <guid isPermaLink="true">https://emresahin.net/til-11/</guid>
      <description>To unhide Markdown code block types in LazyVim, you can set the conceallevel to 0 . Add the following to your configuration: vim.opt.conceallevel = 0</description>
      <category>Software Development</category>
      <category>Vim</category>
      <category>LazyVim</category>
      <category>Markdown</category>
      <category>Lua</category>
      <category>Neovim</category>
      <content:encoded><![CDATA[<p>To unhide Markdown code block types in LazyVim, you can set the <code>conceallevel</code> to <code>0</code>.</p>
<p>Add the following to your configuration:</p>
<pre><code class="language-lua">vim.opt.conceallevel = 0
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>aerc and goneovim</title>
      <published>2020-05-12T18:47:03+00:00</published>
      <updated>2020-05-12T18:47:03+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 12 May 2020 18:47:03 +0000</pubDate>
      <link>https://emresahin.net/aerc-and-goneovim--3894/</link>
      <guid isPermaLink="true">https://emresahin.net/aerc-and-goneovim--3894/</guid>
      <description>aerc I’ve started using aerc as my command-line email client. Initially, I used its archived GitHub repository, but I found the software to be buggy. Switching to the active repository provided me with the fastest IMAP client I’ve ever used. Its asynchronous operations make the workflow incredibl...</description>
      <category>development</category>
      <category>tools</category>
      <category>aerc</category>
      <category>neovim</category>
      <category>goneovim</category>
      <category>hugo</category>
      <category>miniflux</category>
      <category>Go</category>
      <category>golang</category>
      <category>productivity</category>
      <content:encoded><![CDATA[<h2 id="aerc">aerc</h2>
<p>I’ve started using <a href="https://aerc-mail.org/">aerc</a> as my command-line email client. Initially, I used its archived GitHub repository, but I found the software to be buggy. Switching to the active repository provided me with the fastest IMAP client I’ve ever used. Its asynchronous operations make the workflow incredibly smooth, as you don’t have to wait for the server after deleting or archiving each email.</p>
<h2 id="goneovim">goneovim</h2>
<p>I’ve also begun using a Neovim GUI called <a href="https://github.com/akiyosi/goneovim">goneovim</a>. I previously used <a href="https://github.com/daa84/neovim-gtk">Neovim-GTK</a>, but encountered issues—possibly due to Fira Code’s ligatures or other incompatibilities—that resulted in poor visuals and noticeable lag. I’m giving this new GUI a try, and so far, Fira Code and its ligatures are working perfectly.</p>
<p>Software written in Go is occupying more mindshare than I previously anticipated. Alongside <a href="https://gohugo.io">Hugo</a>, the <a href="https://miniflux.app/">Miniflux</a> self-hosted RSS client, and the <a href="https://github.com/vkuznecovas/mouthful">Mouthful</a> comment server, these tools demonstrate that Go has truly taken off for system and performance-related tasks.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
