sailorfe

2026 Feb 09 – My Neovim Markdown setup

I started doing academic and creative writing in vim during grad school after I enabled vim-style keybindings in Obsidian out of curiosity. I dug out my archived .vimrc from back then and confirmed I had a custom Markdown ftplugin even back in 2023.

:spell and ftplugin

Neo/vim file type plugins let you configure editor behavior and appearance for different file types. In the case of Markdown and Python, this means specifying settings that I left more permissive in my global .config/nvim/lua .

" ~/.config/vim/ftplugin/markdown.vim
setlocal spell spelllang=en_us
set colorcolumn =0
set wrap
set wrapmargin  =0

This prompted me to replace essentially the same file in my Neovim setup with a ftplugin/markdown.lua:

local spell_dir = vim.fn.stdpath('data') .. '/spell'

if vim.fn.isdirectory(spell_dir) == 0 then
    vim.fn.mkdir(spell_dir, 'p')
end

vim.opt_local.colorcolumn = "0"
vim.opt_local.spell = true
vim.opt_local.spelllang = "en"
vim.opt_local.spellcapcheck = ""

vim.opt_local.spellfile = spell_dir .. '/en.utf-8.add'

A spellfile is a plain text list of words you want Neovim to ignore while you're writing in a particular language. This can be helpful if you're multilingual or there's proper nouns like names or trademarks you'll type frequently. A surprisingly chunk of my spellfile is words like "Neovim" and "Neovim's". You can edit en.utf8.add directly, but it takes two commands:

:edit <file in 'spellfile'>
" (edit $LANG.utf8.add)
:mkspell! %
" (generates $LANG.utf8.add.spl)

This can be nice if you pre-empt foreign words that you anticipate using, but more often I use the keybind zg to add words on the fly. zG lets you temporarily ignore a word you don't see yourself needing in the long-term, or that might be a stylized misspelling you don't want to get used to.

parser, lsp, and plugins

This section is specific to Neovim as I haven't looked into expanding my .vimrc.

parser: treesitter

I use Lazy for plugin management, including nvim-streesitter and nvim-lspconfig. When I do a fresh Neovim installation, I run :TSUpdate to ensure every parser I've named in my treesitter config is installed, including markdown and markdown_inline. Manually, you can do:

:TSInstall markdown markdown_inline

Parsers do a number of things, but most immediate for Markdown is syntax highlighting.

lsp: Marksman

For no particular reason besides being in the nvim-lspconfig configs list, I use Marksman and manage it with mason.nvim.

You don't really reap the benefits of a Markdown LSP unless you're in a big docs/ folder or working with a file that's several thousand lines long, so I don't think they're strictly necessary if you just want to try Neovim for writing. Marksman really shines paired with telescope.nvim and the :Telescope lsp_document_symbols command, but I probably use it most in my notes vault for the Wiki-style link completion.

markdown-specific plugins

why bother

Looking at all this, I realize this is accumulated from a good two years of vim and then Neovim use, and I can honestly say that vim with the above markdown.vim was perfectly fine. I handled CSS/Sass, HTML, shell scripts, and YAML in vim. I wrote 50k words of fiction in vim in 2024 and 70k of fiction in Neovim last year. I write more prose than code. I am more of a writer than programmer and always will be.

The best thing about vim and Neovim for me is text configuration. I carry the same environment across devices and Linux and installation. I even use Neovim in Termux, although any mobile writing I do tends to happen in Obsidian because I haven't lost it entirely. Dotfiles shouldn't only be the domain of programmers!

Recent posts

archive