Exploring .nvim.lua

Sept. 12, 2024 • 2 minute read
PythonLuaNeoVimVSCode

Having used VSCode before switching to NeoVim the project .vscode configuration folder is one the things I have been missing. Finding out about .nvim.lua filled this void in my tool set and when comparing to the VSCode configuration this is even more extendable, as its fully compatible with Lua making any type of logic easily accessible.

This opens up a load of functionality, since creating custom processing functions on a per project basis is widely accessible. Similar to direnv files this can enable extensible functionality and local variables/functions within your editor.

Some examples include setting up your debugging configuration with the nvim-debug-adapter which actually uses the same adapter for python as in VSCode.

table.insert(require('dap').configurations.python, {
    type = 'python',
    request = 'launch',
    name = 'debug file',
    program = '${file}',
})

vim.keymap.set("n", "<F6>", function()
    require("dap").run({
        type = "python",
        request = "launch",
        name = "Launch Application",
        program = vim.fn.getcwd() .. "/src",
        cwd = vim.fn.getcwd(),
    })
end)

Another could be project specific LSP, linter or formatter configuration separate from the default config. Most of these can be triggered by file type, but having an option to configure on a per project basis makes it much more flexible.

-- Installing a specific LSP...
require("mason-lspconfig").setup({ensure_installed = {"ruff_lsp"}})
...
lspconfig.ruff_lsp.setup({
...
)}
...
-- Setting up linter & formatter...
local nls = require("null-ls")
nls.setup({
    sources = {
        nls.builtins.diagnostics.mypy,
        nls.builtins.fomatting.black,
    }
})

Or a function for a random line you need to insert at some point such as a repeated function signature or comment.

function hello()
  local pos = vim.api.nvim_win_get_cursor(0)[2]
  local line = vim.api.nvim_get_current_line()
  local nline = line:sub(0, pos) .. 'inserted text' .. line:sub(pos + 1)
  vim.api.nvim_set_current_line(nline)
end

You would call this in command mode with :lua hello(). This example is very simple, but this could be configured to be much more expansive and allow for creating meta functionality. This could also be configured to use remote execution of other languages with the usage of remote plugins.

I have only recently found this configuration file, so there are many options to be explored over time and I will most likely create a follow up for this in the future.