Setting up Neovim for Astro development
/ 3 min read
Table of Contents
TLDR
- Astro is a web framework that ships zero JavaScript to the client by default.
- The
astrolanguage server can be installed with mason and set up through the nvim-lsp-config plugin. - For syntax highlighting of
.astrofiles, the tree-sitter-astro grammar is available through the nvim-treesitter plugin. - Use the Lua filetype module to detect the
.mdxfiletype. Otherwise use the jxnblk/vim-mdx-js plugin for syntax highlighting of.mdxfiles. (neovim 0.8.2) - Make sure the prettierd built in formatting source (via null-ls) attaches to
astrobuffers. Otherwise you can format using the Astro Language Server. Sample code. - Look into the
wrapandsidescrolloptions to control how you want to work with lines that trail off the screen. Useful for Markdown editing.
Basics
To get started we need LSP support and syntax highlighting for .astro files. Neovim supports this through the nvim-lsp-config and nvim-treesitter plugins.
MDX Syntax Highlighting
I noticed .mdx files were not being highlighted at all, because the markdown.mdx file type was not being detected by neovim. The neovim version as of writing is 0.8.2.
I couldn’t find a tree-sitter grammar for .mdx files, but I have the tree-sitter grammar for markdown installed. So I leveraged the Lua filetype module to set the file type to markdown.mdx when I enter a new buffer:
vim.filetype.add({ extension = { mdx = "markdown.mdx", }, filename = {}, pattern = {},})Call this method during neovim initialization. I have a file named ft-add.lua which I require in my root init.lua file.
I’m happy with this solution. It provides syntax highlighting of frontmatter which is in .yaml format. And it correctly highlights code blocks for all the programming languages I write about.
We only need to match the .mdx extension, but the linked documentation describes the other options available for filetype detection.
There is a Vim plugin that could achieve this as well: jxnblk/vim-mdx-js.
Formatting
Consistent and fast formatting is non-negotiable for me. Luckily, many of the community astro themes have prettier and eslint already configured. Great!
However, the formatter was not working for me in Neovim. Running the :LspInfo nvim command revealed that the null-ls server was not attached to the buffer.
Looking at the prettierd default arguments, the .astro filetype was not included. So I added it as an extra_filetype:
local null_ls = require("null-ls")local formatting = null_ls.builtins.formatting
local sources = { formatting.prettierd.with({ extra_filetypes = { "astro" }, }),}Now I was able to get the null-ls server attached to the astro buffer.
If you prefer instead to have the Astro Language Server do the formatting, you can update your LSP formatting handler like so:
local lsp_formatting = function(bufnr) vim.lsp.buf.format({ filter = function(client) local name = client.name return name == "null-ls" or name == "astro" end, bufnr = bufnr, })endEditing Markdown in Neovim
Markdown files usually contain long lines that will trail off the screen if you don’t enable text wrapping. If you want to keep text wrapping off, you can modify the sidescroll option. It controls the minimum number of columns to scroll horizontally when the wrap option is off and the cursor moves off the screen.
The default value is 1 column. You can try setting it to 5 which will move the cursor back by 5 columns as you write. Setting the option to 0 will move the cursor to the middle column of the screen which you may prefer instead:
vim.opt.wrap = falsevim.opt.sidescroll = 0 | 1 | 5