Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Custom File Type Syntax Highlighting with Neovim

custom-file-type-syntax-highlighting-with-neovim.jpg

There may come a time where you want to set a few different types of files to a specific file type for better editor support.

Quick Jump:

Here’s a couple of use cases I had:

  • Syntax highlight an .env.example file differently than .env so I had a visual cue between the example file and the real file
  • Syntax highlight requirements-lock.txt the same as requirements.txt
  • Syntax highlight a bunch of variant files like .aliases.local or .zprofile.local the same as a regular shell script

Even if you have different use cases you’ll be able to see how to apply it back to your set up. We’ll also go over how to split out LSP support and syntax highlighting with Treesitter.

Here’s a few examples from my .config/nvim/filetype.lua file in my dotfiles. The comments should help you get going here, I found :help vim.filetype.add to be quite helpful too:

-- Set .aliases or any variant as "bash".
vim.filetype.add({ pattern = { ["%.*aliases.*"] = "bash" } })

-- Set .zprofile or any variant as "bash".
vim.filetype.add({ pattern = { ["%.*zprofile.*"] = "bash" } })

-- Set .env or any variant as "dotenv" except we want .env.example files to be
-- treated differently so it's easier to know we are editing an example file.
-- This has less syntax highlighting and comes up with a different explorer
-- icon so it's easier to know it's not the "real" env file.
vim.filetype.add({
  pattern = {
    ["%.env.*"] = "dotenv",
    ["%.env.*.example"] = { "conf", { priority = 1 } },
  },
})

-- Ensure all .env files and variants are syntax highlighted as shell scripts.
-- This goes along with the filetype addition above. We do this to avoid using
-- bash or sh so the BashLSP linter and formatter doesn't affect env files
-- since that can create a lot of unwanted false positives and side effects.
vim.treesitter.language.register("bash", "dotenv")

-- Set git config variarts as "git_config".
vim.filetype.add({ pattern = { [".*/git/config.*"] = "git_config" } })

-- Set requirements-lock.txt or any variant as "requirements".
vim.filetype.add({ pattern = { ["requirements.*.txt"] = "requirements" } })

The video below demos and covers what’s listed above.

# Demo Video

Timestamps

  • 0:09 – Example env file vs real one
  • 1:24 – Handling file variants
  • 2:22 – Using Vim’s filetype add in Lua script
  • 4:06 – Multiple patterns with a priority
  • 5:04 – Registering file types with Treesitter
  • 6:03 – Customize things for your use cases
  • 6:14 – Neovim’s help for filetype was really helpful

When was the last time you did something similar? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments