I’ve been using vim and neovim for my entire time as a university student, two years now. At first, I focused on learning the default configuration. As time went on, I started customizing it to better fit my needs. But, in the end, I started leaving it in place and just trying to ignore things that were uncomfortable or frustrating.
The end result was an enormous amount of technical debt in the way things were set up and significant friction keeping me from my writing and coding projects. So, this week, I wiped my configuration and restarted from scratch, with a special focus on easing my writing.
first things first: the code
My new configuration is published in my dotfiles repository on Codeberg so you can follow along. I won’t cover everything in this article, but the code itself has comments that should explain everything. If not, my email address is below this article, you can contact me with questions.
the foundation
Since moving to neovim, I’ve enjoyed writing my config in Lua. There’s not much behind that decision, but I do like the syntax of the language and it feels smoother and better-designed than vimscript.
My first task was to set up lazy.nvim as my package manager; previously, I used Packer, but it’s now unmaintained.
To my delight, it was remarkably easy to set up, once I had a supported version of neovim installed (the packaged version on Debian stable is… old). The README provides code to install Lazy if it’s not present when you first open Neovim:
-- init.lua
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
The next step would be to activate Lazy, but apparently you’re required to set your leader key first. I like using the spacebar, since it’s right there and easy to hit.
-- init.lua
-- ...
-- Set leader
vim.g.mapleader = ' '
require("lazy").setup("plugins")
That line tells Lazy to read my plugin configuration from the plugins module, which I’ve placed at ~/.config/nvim/lua/plugins/init.lua.
Finally, I want to include one final module, options, which contains all my non-plugin configuration.
-- init.lua
-- ...
require 'options'
The file this includes is located at ~/.config/nvim/lua/options/init.lua.
a brief overview of the options module
I won’t cover every single option I’ve changed, but I do want to show you briefly how I’ve organized this module. Here is the init.lua:
-- lua/options/init.lua
require 'options.colorscheme'
require 'options.remap'
require 'options.behavior'
require 'options.vimwiki'
require 'options.autocmd'
require 'options.display'
Essentially what I’ve done is break the options module up into even smaller modules for each thing I’m configuring.
options.colorscheme- this is where I select my color scheme, Gruvbox Light with the “hard” contrast leveloptions.remap- this is where I do keyboard mappings; I’ll cover a few of these mappings lateroptions.behavior- a bit of an umbrella category, this is where I configure things that affect the editing experience on a fundamental leveloptions.vimwiki- I use Vimwiki to take notes for my classes and projects, and it needs a bit of configuring, so I gave it a file of its ownoptions.autocmd-autocmdis a powerful feature invimandneovimthat lets you set up custom configuration based on file type. Here are myautocmds:FileType markdown- When editing markdown files, I enable spellcheck, turn off automatic folding of indented lines, and activate the Pencil plugin for some writing-related tweaksFileType mail- I write my emails usingneovimwith the aerc email client, and these are a few tweaks to make that experience better.BufEnter /tmp/tut*- I write my Fediverse toots in the terminal, buttut, my client, doesn’t add a.mdfile extension to the draft, so I use thisautocmdto label my drafts of toots as MarkdownCmdlineLeave- It drives me nuts how the last command you run constantly shows up at the bottom of the window, so I wrote thisautocmdto clear it.
options.display- aesthetic tweaks toneovim, as well as configuration for my status line
Now that we’ve got a summary of my configuration out of the way, let’s look at some of the plugins I use.
plugins
Someday, I’d like to figure out modularizing the plugins module as well, but for now it’s one big module.
I won’t walk you through every plugin, since they’re all in the code I linked at the beginning of the article, but here are some of the ones important to my new writing workflow.
lualine.nvim- I find myself very disappointed with neovim status line plugins, honestly. Lualine was the only one that worked out of the box with my color scheme, and none of them had a word count module, so I put code of my own inoptions.displayto show the word count of Markdown filesleap.nvim- A game changer for navigation, I have to say. Give it a trytelescope.nvim- This is a new one to me, but it was very handy already in jumping between files in my modularized configuration. I expect theripgrepintegration to come in very handy in long-form writing to help me figure out where exactly I talked about such and such a concept.vim-gitgutterisn’t quite a writing plugin, but if you’re a writer like me who likes to usegitas version control for your writing, it’s a must-havemkdxis the final word when it comes to Markdown editing. So many useful shortcuts.zen-mode.nvim- narrows the page to a column for easier focus; I activate this andtwilight.nvimwith a<leader>fshortcut as a focus mode for my writing.twilight.nvim- dims lines you’re not currently working on to help you focus (I setcontext = 1to make only the current paragraph full-contrast). Integrates well withzen-mode.nvim. (Special thanks to Hyde for pointing this one out to me—I had been usinglimelight.vim.)vimwiki, as mentioned above, is my tool of choice for managing my notes. I use its Markdown format, so it’s mostly a tool for easily linking between notes and tweaking the formatting of lists for easier outlinesvim-fountain- haven’t tried it yet, but this adds support for Fountain, a Markdown-like syntax for screenwriting.vim-pencil- Loads of behind-the-scenes tweaks to make the writing experience better. I love it.
conclusion
I think that’s everything. As I’ve mentioned, I’ve published my configuration with copious comments so it should be easy to adopt yourself. If you have questions or recommendations, I’d love to hear them, my contact info is below this article.
Happy writing!
testimonials
Amin—really getting to appreciate your nvim config. It’s the cleanest and easiest to understand that I’ve seen, I keep referencing it over other materials when I’m working on mine. Good work.
– CJ