<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>My Setup &amp; Configuration on Clément Joly – Open-Source, Rust &amp; SQLite</title><link>https://cj.rs/blog/my-setup/</link><description>Recent content in My Setup &amp; Configuration on Clément Joly – Open-Source, Rust &amp; SQLite</description><image><title>Clément Joly – Open-Source, Rust &amp; SQLite</title><url>https://cj.rs/images/open-graph-pages.jpg</url><link>https://cj.rs/images/open-graph-pages.jpg</link></image><generator>Hugo</generator><language>en</language><copyright>Clément Joly</copyright><lastBuildDate>Mon, 04 May 2026 19:41:10 +0100</lastBuildDate><atom:link href="https://cj.rs/blog/my-setup/index.xml" rel="self" type="application/rss+xml"/><item><title>Configuration Management</title><link>https://cj.rs/blog/my-setup/chezmoi/</link><pubDate>Fri, 03 Sep 2021 19:59:01 +0100</pubDate><guid>https://cj.rs/blog/my-setup/chezmoi/</guid><description>I use Chezmoi to manage my configuration</description><content:encoded><![CDATA[



  
  
  
  

  <div class="alert alert-tldr">
    <p class="alert-heading">
      ⚡
      
        TL;DR
      
    </p>
    <p>Chezmoi follows a declarative approach to configuration management. Even if you already use a configuration-management system, you should <a href="https://www.chezmoi.io/docs/comparison/">check out how it compares</a>!</p>
  </div>



<h2 id="a-custom-configuration-makes-you-feel-at-home">A Custom Configuration Makes You Feel at Home</h2>
<p>Your git aliases, shell setup, keyboard shortcuts and even your favorite fonts are tweaked for your own needs and tastes. It’s part of what makes your computer, <em>your</em> computer. All this configuration evolves over years and is slowly refined over time. It may actually be your longuest-living project.</p>
<p>Do you want to start from scratch when you switch computer? Of course not! And you wouldn’t want to break it with adventurous changes either! Versioning it in <a href="https://drewdevault.com/2019/12/30/dotfiles.html">git</a> backs up the history and eases the management of this important work. Configuration updates are also more convenient to share between machines this way.</p>
<h2 id="enter-chezmoi">Enter Chezmoi</h2>
<p>In the git-based configuration management described above, how to account for the small variations (like between your <a href="https://utf9k.net/blog/conditional-gitconfig/">work environment and personal computer</a>)? Git supports <a href="https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/RelNotes/2.13.0.txt#n127">conditional inclusion of configuration files</a>, but how about the other tools? What if you want to encrypt your secrets in your config files, to publish your configuration on GitHub?</p>
<p><a href="https://www.chezmoi.io">Chezmoi</a> follows a <em>declarative approach</em>: it has a separate <em>source repository</em><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> to describe a target state, that then gets applied to your home directory. This is possible through templates, that are activated selectively for some files. The rest of this post shows how powerful templating can be.</p>
<h2 id="account-for-variations-between-machines">Account for Variations Between Machines</h2>
<p>Let’s start with a simple example. In the git configuration, you put your email, that’s then included in all your commits. Thus, you often want to have a different email in <code>.gitconfig</code> for your work and personal profiles. To tackle this issue, I put the following in my <code>.gitconfig</code> chezmoi template:</p>
<pre tabindex="0"><code>[user]
    email = {{ .email }}
</code></pre><p>and it gets rendered to this:</p>
<pre tabindex="0"><code>[user]
    email = me@my.home
</code></pre><p>on my personal computer and this:</p>
<pre tabindex="0"><code>[user]
    email = me@my.work
</code></pre><p>on my work computer. It serves a purpose similar to <a href="https://utf9k.net/blog/conditional-gitconfig/">conditionally setting your gitconfig</a>, but it is applicable to any program.</p>
<h2 id="even-more-variations-with-templates">Even More Variations with Templates</h2>
<p>Now, let’s cover a more powerful use of templates.</p>
<p>You can have multiple files generated from one using <a href="https://www.chezmoi.io/docs/templating/#using-chezmoitemplates">“global” templates</a>. For instance, if you use <a href="https://i3wm.org/">i3</a> and <a href="https://swaywm.org/">sway</a> as your windows manager, you likely have slightly different configurations, given that sway’s configuration is mostly compatible with that of i3. To keep everything in one file, while taking advantages of sway-specific features, you can (in your chezmoi repository):</p>
<ol>
<li>Put your configuration in <code>.chezmoitemplates/sway_i3</code>. You can keep any sway specific section in a templated <code>if</code> statement, like so:
<pre tabindex="0"><code>{{- if eq .f &#34;sway&#34; }}
# Sway specific stuff here, like output configuration
{{- end }}
</code></pre></li>
<li>In <code>dot_config/i3/config.tmpl</code> (and <code>dot_config/sway/config.tmpl</code>), use something like:
<pre tabindex="0"><code>{{/* Environment */}}
{{- $env := . -}}

{{/* Flavor */}}
{{- $f := &#34;i3&#34; -}} # &lt;--- Change this to &#34;sway&#34; in dot_config/sway/config.tmpl

{{- template &#34;sway_i3&#34; dict &#34;f&#34; $f &#34;env&#34; $env -}}
</code></pre>As you may have noticed, chezmoi renames some files in the source state, to encode parameters and for readability. So <code>dot_config/sway/config.tmpl</code> becomes <code>.config/sway/config</code> (<code>.tmpl</code> means the file is executed as a template).    <br>
Also, <code>$env</code> is used to keep the general template context, for instance to check the OS version in our template config file.</li>
</ol>
<h2 id="chezmoiignore">.chezmoiignore</h2>
<p>Finally, chezmoi supports an ignore file named <code>.chezmoiignore</code>. The concept is similar to the well known <code>.gitignore</code>: patterns listed in this file are ignored by chezmoi. In other words, some files are stored in your chezmoi repository, but do not reflect in your home. This can be used if you put a <code>README.md</code> in your configuration repository, as you don’t want this file in your home directory. Just write:</p>
<pre tabindex="0"><code>README.md
</code></pre><p>in <code>.chezmoiignore</code> and the <code>README.md</code> won’t be copied in your home.</p>
<p>You can do more advanced things with <code>.chezmoiignore</code> as it is a template by default. From <a href="https://www.chezmoi.io/docs/reference/#chezmoiignore">the documentation</a>:</p>
<pre tabindex="0"><code>{{- if ne .email &#34;firstname.lastname@company.com&#34; }}
# Ignore .company-directory unless configured with a company email
.company-directory # note that the pattern is not dot_company-directory
{{- end }}
</code></pre><h2 id="conclusion">Conclusion</h2>
<p>Chezmoi has lot more <a href="https://www.chezmoi.io/docs/reference/">features</a>, like <a href="https://www.chezmoi.io/docs/how-to/#encrypt-whole-files-with-gpg">encryption</a> or <a href="https://www.chezmoi.io/docs/how-to/#use-chezmoi-with-github-codespaces-visual-studio-codespaces-or-visual-studio-code-remote---containers">installation in GitHub Codespaces</a>. It is quite <a href="https://www.chezmoi.io">well documented</a>, in particular with a <a href="https://www.chezmoi.io/docs/quick-start/">quick start guide</a>.</p>
<p>I’ve switched to it almost two years ago, I don’t regret it at all!</p>
<h2 id="bonus-vim-snippet">Bonus: Vim Snippet</h2>
<p>To update the target state automatically when editing the source file in the chezmoi repo, I use this vim snippet (with the <a href="https://fishshell.com/">fish shell</a>):</p>
<pre tabindex="0"><code>autocmd BufWritePost ~/.local/share/chezmoi/* ! chezmoi apply --source-path %; or for f in (rg -l &#39;template &#34;%:t&#34;&#39;); chezmoi apply --source-path $f; end
</code></pre><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>You should store this source repository in a git repository to easily revert changes and share configuration update between various machines.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How I Got Started with NeoVim’s Lua Configuration</title><link>https://cj.rs/blog/my-setup/nvim-0-5/</link><pubDate>Sun, 18 Jul 2021 22:57:01 +0100</pubDate><guid>https://cj.rs/blog/my-setup/nvim-0-5/</guid><description>&lt;p&gt;Four months ago I was still using &lt;a href="https://spacevim.org/"&gt;SpaceVim&lt;/a&gt; when I stumbled upon a &lt;a href="https://oroques.dev/notes/neovim-init/"&gt;blog post&lt;/a&gt; on how to configure NeoVim with Lua. I then started to create my own configuration. In this post I’ll share the learnings acquired in the process. I hope you will find this useful to create your own configuration!&lt;/p&gt;
&lt;h2 id="why-create-your-own-vim-config-from-scratch"&gt;Why create your own Vim config from scratch?&lt;/h2&gt;
&lt;p&gt;Vim has been my daily driver for about ten years. Almost from the beginning, I used Vim distributions for ease of configuration. &lt;a href="https://vim.spf13.com"&gt;Spf13 vim&lt;/a&gt; first and then &lt;a href="https://spacevim.org/"&gt;SpaceVim&lt;/a&gt;. With a distribution, one gets a lot of bells and whistle without spending too much time configuring things. So why spend hours setting up NeoVim from scratch?&lt;/p&gt;</description><content:encoded><![CDATA[<p>Four months ago I was still using <a href="https://spacevim.org/">SpaceVim</a> when I stumbled upon a <a href="https://oroques.dev/notes/neovim-init/">blog post</a> on how to configure NeoVim with Lua. I then started to create my own configuration. In this post I’ll share the learnings acquired in the process. I hope you will find this useful to create your own configuration!</p>
<h2 id="why-create-your-own-vim-config-from-scratch">Why create your own Vim config from scratch?</h2>
<p>Vim has been my daily driver for about ten years. Almost from the beginning, I used Vim distributions for ease of configuration. <a href="https://vim.spf13.com">Spf13 vim</a> first and then <a href="https://spacevim.org/">SpaceVim</a>. With a distribution, one gets a lot of bells and whistle without spending too much time configuring things. So why spend hours setting up NeoVim from scratch?</p>
<p>SpaceVim does provide a lot of options and plugins so that everyone can find the functionalities they need and discover some new useful tricks. This ends up creating long key mappings like <code>&lt;space&gt;ff</code> and leads to long startup time. For instance on my machine with an SSD drive, it needs between 1 and 2 seconds to start. This is a common problem with distributions.</p>
<p>The long startup time issue can be mitigated by starting Vim less often or by choosing a lighter Vim distribution. One could even reuse only the core and some parts of a distribution, leaving out the rest. Regarding the long key mappings issue, shorter ones could be redefined. However, this has two major drawbacks:</p>
<ul>
<li>your customized configuration lies on the moving foundations of the underlying distributions,</li>
<li>debugging is made more difficult because of the incorporation of so much code you haven’t written and don’t know well.</li>
</ul>
<p>To solve all these problems, I found it easier and less time-consuming to have my own configuration. Additional benefits include a better recall of what exists and what functionalities are implemented<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. The good news with NeoVim 0.5 is that you can now use Lua and not an arcane language like VimScript<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. The result is also quite fast: with my configuration NeoVim starts in 100 to 110 <em>milliseconds</em>.</p>
<p>Starting your own configuration does not mean you can’t draw inspiration from other configurations! The next sections of this post reference guides, snippets and plugins I’ve found useful, so that you can evaluate them for inclusion into your own file.</p>
<h2 id="enjoy-the-ride">Enjoy the Ride!</h2>
<p>To tailor my experience to my liking, I tried my changes in a new instance of NeoVim after every addition of a plugin or of a set of mappings. Mappings in particular sometime looks good on the screen, but fingers don’t like it that much 😀.</p>
<p>In addition, NeoVim configuration can be notoriously complicated to debug. To quote the documentation:</p>




  <figure>
    <blockquote cite="https://neovim.io/doc/user/starting.html#bisect">
      <p>To find the cause of a problem in your config, you must &ldquo;bisect&rdquo; it.</p>

    </blockquote>
    
      <figcaption class="blockquote-caption">
        
          <cite style="text-align: right"><a href="https://neovim.io/doc/user/starting.html#bisect">https://neovim.io/doc/user/starting.html#bisect</a></cite>
          <br/>
        
        
      </figcaption>
    
  </figure>



<p>For this the previous point about regular testing helps, but I would advise for versioning your configuration, for instance with <a href="/blog/my-setup/chezmoi/">git and chezmoi</a>. With regular commits, you will be able to rely on the git bisect feature when things go wrong.</p>
<h2 id="guides">Guides</h2>
<p>Detailed guidance exists online to get started with your configuration. I got started with <a href="https://oroques.dev/notes/neovim-init/">a mostly one file Lua configuration</a>. This guide contains general explainations on where to put your Lua files, the reasoning behind the changes… If you are not familiar with NeoVim Lua configuration tricks, I strongly recommend reading the above link. See you in a bit 👋.</p>
<p>In addition, these links may prove useful:</p>
<ul>
<li><a href="https://github.com/mjlbach/defaults.nvim/blob/master/init.lua">Example <code>init.lua</code></a></li>
<li><a href="https://emilienl.medium.com/a-quick-guide-to-set-up-nvim-built-in-lsp-419bb6e91c0a">A quick guide to set up nvim built in LSP</a></li>
<li><a href="https://neovim.io/doc/lua-resources/">NeoVim’s Lua Resources</a></li>
</ul>
<h2 id="snippets-from-my-configuration">Snippets from my Configuration</h2>
<p>This section assumes basic knowledge of Lua configuration.</p>
<h3 id="mapping-hints">Mapping Hints</h3>
<figure>
    <img loading="lazy" src="../which-key-space.png"/> <figcaption>
            Pop up window showing the keys that can follow &lt;space&gt;
        </figcaption>
</figure>

<p><a href="https://github.com/folke/which-key.nvim">Which-Key</a> is a brilliant plugin to display a popup with the possible mappings as you press the keys of the shortcut. For instance, I have mapped <code>&lt;space&gt;j</code> to <code>:tabnew</code>, to open a new tab. On the figure above, I’ve just typed <code>&lt;space&gt;</code> (abbreviated <code>SPC</code>) and the keys that could be pressed then are displayed in a popup at the bottom of the screen.
What sets <code>which-key.nvim</code> apart is that you don’t have to configuration your mappings using a special function for it to work. It discovers most of your mappings right away and use them to populate the popup.</p>
<p>I’ve tweaked <code>timeoutlen</code> to get the popup more quickly. I’ve also changed labels for some keys to have shorter or more explicit names, like <code>SPC</code> for <code>&lt;space&gt;</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span><span style="color:#c678dd">local</span> <span style="color:#e06c75">wk</span> <span style="color:#56b6c2">=</span> <span style="color:#e06c75">require</span>(<span style="color:#98c379">&#34;which-key&#34;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">wk.setup</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#e06c75">key_labels</span> <span style="color:#56b6c2">=</span> {
</span></span><span style="display:flex;"><span>    [<span style="color:#98c379">&#34;&lt;space&gt;&#34;</span>] <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#34;SPC&#34;</span>,
</span></span><span style="display:flex;"><span>    [<span style="color:#98c379">&#34;&lt;CR&gt;&#34;</span>] <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#34;RET&#34;</span>,
</span></span><span style="display:flex;"><span>    [<span style="color:#98c379">&#34;&lt;tab&gt;&#34;</span>] <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#34;TAB&#34;</span>,
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#e06c75">vim.opt</span>.<span style="color:#e06c75">timeoutlen</span> <span style="color:#56b6c2">=</span> <span style="color:#d19a66">900</span>
</span></span></code></pre></div><h4 id="mapping-choices">Mapping Choices</h4>
<p>My custom mappings are mainly around the <code>&lt;space&gt;</code> key, often with only one key following, like <code>&lt;space&gt;s</code> to write the current file. The <code>&lt;Leader&gt;</code> key is mostly left for plugins, while the <code>&lt;LocalLeader&gt;</code> is sometimes used for some buffer local mappings.</p>
<p>In general, my mappings are heavily adapted to the <a href="https://bepo.fr">BÉPO layout</a>, a Dvorak-like keyboard for French.</p>
<h3 id="clever-f">Clever-F</h3>
<p><a href="https://github.com/rhysd/clever-f.vim">rhysd/clever-f.vim</a> extends <code>f</code>, <code>t</code>… so that:</p>
<ol>
<li>When you press <code>fc</code>, all characters <code>c</code> in the current line get highlighted</li>
<li>Another press on <code>f</code> jumps to the next occurence of <code>c</code></li>
<li>A press on <code>F</code> jumps backward</li>
</ol>
<p>This makes <code>,</code> and <code>;</code> redondant and these can be remapped.</p>
<h4 id="leaders">Leaders</h4>
<p>The universal leader is by default mapped on <code>\</code>. However, it is frequently remapped to <code>,</code>, which is easier to reach. Since clever-f freed two mappings, I reuse them like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span><span style="color:#e06c75">g.mapleader</span> <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#34;,&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#e06c75">g.maplocalleader</span> <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#34;;&#34;</span>
</span></span></code></pre></div><h3 id="buffer-jump">Buffer Jump</h3>
<p>With the awesome <a href="https://github.com/phaazon/hop.nvim">hop.nvim</a>, one can get hints to jump to various parts of a buffer (see the figure below if that does not make sense just yet). It is similiar to EasyMotions and supports jumps by line, word, characters sequences and pattern. However, in my opinion this plugin is not replacement for <code>w</code> and the like, because for short movements I find <code>w</code> or <code>f</code> shorter to type and because the need to read the screen for caracters may be quite slow compared to <code>3w</code>. It is also not a replacement for <code>/</code> because hop.nvim highlights whats visible on the current buffer. Thus it fills the void left for medium range move.</p>
<figure>
    <img loading="lazy" src="../hop-nvim-word.png"
         alt="I invoqued HopWord from line 105 and if I press dr, I’ll jump to the last word of line 116"/> <figcaption>
            Word jump example with hop.nvim<p>I invoqued <code>HopWord</code> from line 105 and if I press <code>dr</code>, I’ll jump to the last word of line 116</p>
        </figcaption>
</figure>

<p>Here is my configuration for this plugin:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;n&#39;</span>, <span style="color:#98c379">&#39;T&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopLineStart&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;v&#39;</span>, <span style="color:#98c379">&#39;T&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopLineStart&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;n&#39;</span>, <span style="color:#98c379">&#39;S&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopWord&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;v&#39;</span>, <span style="color:#98c379">&#39;S&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopWord&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;n&#39;</span>, <span style="color:#98c379">&#39;è&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopChar2&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;v&#39;</span>, <span style="color:#98c379">&#39;è&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopChar2&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;n&#39;</span>, <span style="color:#98c379">&#39;È&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopPattern&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">map</span>(<span style="color:#98c379">&#39;v&#39;</span>, <span style="color:#98c379">&#39;È&#39;</span>, <span style="color:#98c379">&#39;&lt;cmd&gt;HopPattern&lt;CR&gt;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#e06c75">require</span>(<span style="color:#98c379">&#39;hop&#39;</span>).<span style="color:#e06c75">setup</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#e06c75">keys</span> <span style="color:#56b6c2">=</span> <span style="color:#98c379">&#39;auietsrncbpovdljyxqghf&#39;</span>, <span style="color:#7f848e">-- Hint keys</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>It is heavily optimized for the the <a href="https://bepo.fr">BÉPO layout</a>, whose <a href="https://en.wikipedia.org/wiki/Touch_typing#Home_row">home row</a> contains the <code>auie</code> keys on the left hand and the <code>tsrn</code> keys on the right hand. Hence the choice to put most mappings on <code>T</code> and <code>S</code>, easily reachable with the right hand and to start the hint keys with <code>auie</code> on the left hand.</p>
<h2 id="plugins">Plugins</h2>
<p>These plugin are often mostly written in Lua, although vim script plugins can be more mature. The Lua-plugin ecosystem is moving really quickly, you may find that other plugins are more suitable in a couple months.</p>
<h3 id="plugins-i-use">Plugins I use</h3>
<h4 id="telescope">Telescope</h4>
<p>I use <a href="https://github.com/nvim-telescope/telescope.nvim">telescope.nvim</a> as a fuzzy finder. It can be slow at times compared to <a href="https://github.com/lotabout/skim.vim">skim</a> or <a href="https://github.com/junegunn/fzf.vim">fzf</a>. However, it is relatively easy to script in Lua, making it easy to tightly integrate with other functions.</p>
<h4 id="completion-nvim">Completion-nvim</h4>
<p>I use <a href="https://github.com/nvim-lua/completion-nvim">nvim-lua/completion-nvim</a> in particular for its chains of completion (several completion sources are chained and sources lower in the chain are used when upper sources don’t have any results). However, <a href="https://github.com/hrsh7th/nvim-compe">nvim-compe</a> may be a better choice if you start fresh.</p>
<h4 id="complete-list">Complete List</h4>
<p>This is a list of plugins I use, roughly ordered by frequency of use.</p>

<details>
  <summary>
    Click to show the list of plugins
  </summary>

<ul>
<li>
<p><a href="https://github.com/savq/paq-nvim">paq-nvim</a> a light package manager written in lua. It supports lazy loading, although it’s easier to do with <a href="https://github.com/wbthomason/packer.nvim">packer.nvim</a></p>
</li>
<li>
<p><a href="https://github.com/folke/which-key.nvim">folke/which-key.nvim</a> a great plugin to dispaly a popup with possible mappings. It also offer a register preview, a bit like <a href="https://github.com/tversteeg/registers.nvim">tversteeg/registers.nvim</a></p>
<ul>
<li><a href="https://github.com/kosayoda/nvim-lightbulb">kosayoda/nvim-lightbulb</a> displays a lightbulb when a code action is available</li>
</ul>
</li>
<li>
<p>Completions &amp; snippets:</p>
<ul>
<li><a href="https://github.com/neovim/nvim-lspconfig/">nvim-lspconfig</a> and <a href="https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md">the guide for LSP Configurations</a> to use with the native LSP client in neovim.</li>
<li><a href="https://github.com/nvim-lua/completion-nvim">nvim-lua/completion-nvim</a> with these additional completion sources.
<ul>
<li><a href="https://github.com/nvim-treesitter/completion-treesitter">nvim-treesitter/completion-treesitter</a></li>
<li><a href="https://github.com/steelsojka/completion-buffers">steelsojka/completion-buffers</a></li>
</ul>
</li>
<li><a href="https://github.com/SirVer/ultisnips">SirVer/ultisnips</a> a well known snippets engine, see also <a href="https://github.com/honza/vim-snippets">honza/vim-snippets</a></li>
</ul>
</li>
<li>
<p>Mostly used with Git:</p>
<ul>
<li><a href="https://github.com/tpope/vim-fugitive">tpope/vim-fugitive</a> the well known git plugin
<ul>
<li><a href="https://github.com/tpope/vim-rhubarb">tpope/vim-rhubarb</a> :GBrowse for github</li>
</ul>
</li>
<li><a href="https://github.com/airblade/vim-gitgutter">airblade/vim-gitgutter</a> to see and manage git changes</li>
<li><a href="https://github.com/rhysd/conflict-marker.vim">rhysd/conflict-marker.vim</a> adds shortcuts to solve merge conflicts</li>
<li><a href="https://github.com/rhysd/committia.vim">rhysd/committia.vim</a> improves editing of commit messages with diff and status</li>
<li><a href="https://github.com/airblade/vim-rooter">airblade/vim-rooter</a> change to a project’s root directory</li>
</ul>
</li>
<li>
<p>Navigation:</p>
<ul>
<li><a href="https://github.com/phaazon/hop.nvim">phaazon/hop.nvim</a> a wonderful plugin that highlights text with short keystrokes to jump around</li>
<li><a href="https://github.com/rhysd/clever-f.vim">rhysd/clever-f.vim</a> &ndash; Better movements, frees “,” and “;” for <a href="#leaders">leaders</a></li>
<li><a href="https://github.com/arp242/jumpy.vim">arp242/jumpy.vim</a> allows to make big and precise jumps for instance from function to function</li>
</ul>
</li>
<li>
<p>Deal with symbols like <code>(</code> <code>[</code> or <code>&lt;</code></p>
<ul>
<li><a href="https://github.com/tpope/vim-surround">tpope/vim-surround</a> the well known plugin to add, change or delete symbols around text.</li>
<li><a href="https://github.com/jiangmiao/auto-pairs">jiangmiao/auto-pairs</a> closes pairs of symbols</li>
</ul>
</li>
<li>
<p><a href="https://github.com/ojroques/nvim-hardline">ojroques/nvim-hardline</a> a light and fast status line</p>
</li>
<li>
<p><a href="https://github.com/nvim-treesitter/nvim-treesitter">nvim-treesitter/nvim-treesitter</a>, one of the new big features of NeoVim 0.5. This is still in an early phase but it can already improve highlighting, refactoring and completions, sometimes with companion plugins like:</p>
<ul>
<li><a href="https://github.com/nvim-treesitter/nvim-treesitter-textobjects">nvim-treesitter/nvim-treesitter-textobjects</a></li>
<li><a href="https://github.com/nvim-treesitter/nvim-treesitter-refactor">nvim-treesitter/nvim-treesitter-refactor</a></li>
<li><a href="https://github.com/nvim-treesitter/playground">nvim-treesitter/playground</a></li>
</ul>
</li>
<li>
<p>Other convenience plugins</p>
<ul>
<li><a href="https://github.com/glepnir/indent-guides.nvim">glepnir/indent-guides.nvim</a> displays indentation guides.</li>
<li><a href="https://github.com/ojroques/nvim-bufdel">ojroques/nvim-bufdel</a> improve the deletion of buffers</li>
<li><a href="https://github.com/ojroques/vim-oscyank">ojroques/vim-oscyank</a> a that works across terminals, even over SSH</li>
<li><a href="https://github.com/winston0410/commented.nvim">winston0410/commented.nvim</a> (un)comment lines. It is the only lua comment plugin I’ve found that supports using <code>3gcc</code> to comment 3 lines,.</li>
<li><a href="https://github.com/dstein64/vim-startuptime">dstein64/vim-startuptime</a> a better interface to vim startup time profiles</li>
<li><a href="https://github.com/norcalli/nvim-colorizer.lua">norcalli/nvim-colorizer.lua</a> a plugin to highlight color codes with the right colors</li>
</ul>
</li>
<li>
<p><a href="https://github.com/nvim-telescope/telescope.nvim">nvim-telescope/telescope.nvim</a> a fuzzy finder with preview. I also use these extensions:</p>
<ul>
<li><a href="https://github.com/nvim-telescope/telescope-symbols.nvim">nvim-telescope/telescope-symbols.nvim</a></li>
<li><a href="https://github.com/fhill2/telescope-ultisnips.nvim">fhill2/telescope-ultisnips.nvim</a></li>
<li><a href="https://github.com/nvim-telescope/telescope-github.nvim">nvim-telescope/telescope-github.nvim</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/cj-rs/vim-bepo">cj-rs/vim-bepo</a> a customized fork of a plugin to adapt mappings to the <a href="https://bepo.fr/wiki/Accueil">bepo layout</a></p>
</li>
<li>
<p>If you work with more exotic syntaxes:</p>
<ul>
<li><a href="https://github.com/sheerun/vim-polyglot">sheerun/vim-polyglot</a></li>
<li><a href="https://github.com/cstrahan/vim-capnp">cstrahan/vim-capnp</a>

</details>
</li>
</ul>
</li>
</ul>
<h3 id="plugins-i-load-lazily">Plugins I load lazily</h3>
<p>I lazy load less often used plugins, so that they are not loaded at startup by default.</p>
<ul>
<li><a href="https://github.com/romgrk/nvim-treesitter-context">romgrk/nvim-treesitter-context</a> is a bit slow and buggy, but useful sometimes to get the context piled up at the top</li>
<li><a href="https://github.com/mattn/emmet-vim">mattn/emmet-vim</a> CSS abbreviations to generate HTML and other</li>
<li><a href="https://github.com/jbyuki/instant.nvim">jbyuki/instant.nvim</a> for remote pair programming</li>
</ul>
<h3 id="plugins-on-my-radar-for-the-future">Plugins on my Radar for the Future</h3>
<p>Plugins I might use in the future to replace existing pieces or add features:</p>
<ul>
<li><a href="https://github.com/puremourning/vimspector">vimspector</a> a debugger based on the DAP protocol (like LSP, but for debugguers)</li>
<li><a href="https://github.com/glepnir/lspsaga.nvim">lspsaga.nvim</a> a UI for the native LSP client</li>
<li><a href="https://github.com/hrsh7th/nvim-compe">nvim-compe</a> a completion engine with more advanced support for LSP. I quite like the chains in completion-nvim, but maybe nvim-compe could be a better fit at some point</li>
<li><a href="https://github.com/lambdalisue/gina.vim">gina.vim</a> to replace fugitive. It offers faster startup time and asynchronous git operations</li>
</ul>
<h2 id="other-interesting-configurations">Other Interesting Configurations</h2>
<ul>
<li><a href="https://github.com/tjdevries/config_manager/tree/master/xdg_config/nvim">tjdevries</a></li>
<li><a href="https://github.com/ojroques/dotfiles/tree/master/nvim">ojroques</a></li>
</ul>
<h2 id="thanks">Thanks</h2>
<p>Thanks to <a href="https://moverest.xyz">moverest</a> and <a href="https://jguer.space/">J. Guereiro</a> for reviewing drafts of this post.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>That was my experience at least and that of <a href="https://news.ycombinator.com/item?id=27715513">others</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Some parts of the NeoVim Lua API are not mature and you end up running some VimScript. But this is mostly true for things like mappings, which are closer to settings toggle than scripts. Even if you really want to define some mappings by scripting, you can mix Lua and VimScript like in <a href="#buffer-jump">buffer jump</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>