While working on my pet project LeavingStone, I noticed that my Go files weren’t following the indentation style I preferred — they were using spaces instead of tabs. To fix this, I decided to make changes to my Neovim configuration in the init.lua
script.
Upon inspecting my existing setup, I realized that I had already configured the indentation settings, but they were specifically for JavaScript and global for all fileypes. The task now was to have different configurations for different programming languages.
After a quick online search, I discovered a helpful feature called autocmd
, particularly the “FileType” event. This allowed me to dynamically adjust Neovim settings based on the type of file being edited. The trick was to use the vim.bo.filetype
variable, which holds the current buffer’s file type.
So here’s simple function named set_language_config
to handle the dynamic adjustment of Neovim options based on the file type. For example, Python needs a different indentation style compared to JavaScript.
local function set_language_config()
local filetype = vim.bo.filetype
if filetype == "python" then
-- Python-specific configuration
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.softtabstop = 4
vim.opt.expandtab = true
elseif filetype == "javascript" or filetype == "typescript" then
-- JavaScript and TypeScript configuration
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
-- ...
With the function ready, the final step was to implement it using vim.api.nvim_create_autocmd
, a tool that helps manage events in Neovim. Initially, there was a small confusion, but looking at another part of my configuration (the ‘LspAttach’ example), I managed to write a simple and effective piece of code:
vim.api.nvim_create_autocmd({"FileType"}, {
pattern = {"*"},
callback = function()
set_language_config()
end
})
Testing it with /tmp/hello.js
and /tmp/hello.py
confirmed that the configurations worked as intended — 2 spaces for JavaScript and 4 spaces for Python.
All that remains is to configure this specifically for Go. Here’s actual config values:
-- width of tab is 4 cells
vim.opt.tabstop=4
-- when autoindent - 4 spaces
vim.opt.shiftwidth=4
-- when Tab key pressed - inserts 4 spaces
vim.opt.softtabstop=4
-- 4 spaces are treated as tabs, so tabs are saved to disk
vim.opt.noexpandtab=true
Of course while searching for those simple but essential pieces of information I came accross different solutions that other might consider useful. Things like setups of triggering gofmt
on certain actions and especially, full-fledged plugins:
- https://github.com/ray-x/go.nvim - modern go neovim plugin based on treesitter, nvim-lsp and dap debugger
- https://github.com/fatih/vim-go - plugin for vim that adds Go language support
Although, I am in the process of constructing my own setup from the ground up, aiming to develop a deeper understanding and knowledge in the process.
In the realm of Neovim configurations, this journey taught me that sometimes a straightforward touch of Lua magic is all you need to make your code dance to the right rhythm.