No description
Find a file
2025-06-09 17:17:48 +00:00
README.md Update README.md 2025-06-09 17:17:48 +00:00

NeoVim: Lazy vs. Mason - Getting Started with Plugins

Lazy vs. Mason - The Confusion

When you open the command line in NvChad (and most other NeoVim distributions) you have two different ways to deal with packages and with what is sometimes called a package, sometimes a plugin and sometimes a module.

You can type in :Lazy and you can type in :Mason and then you get two different menus that look roughly the same and without knowing how NeoVim works, it can quickly get a bit confusing when you want to extend Neovim with new packages, plugins or modules.

How CLI integration in NeoVim works

Besides it's text editing and navigating features, what makes NeoVim so great is the seamless integration into the system shell.

Through lua and the command line you can run anything in NeoVim what you would run in your terminal in as well.

Running from the Command Line

We can run commands in the command line by simply writing a : when in normal mode, like :Lazy, :Mason, :make, :!dotnet build et cetera.

Running from Lua

Lua is the integration layer that that enables us to pass information from NeoVim as parameter into console applications and display the result back in NeoVim.

We can run commands with :lua like so: :lua print(vim.fn.system("your_command")).

We use print() / vim.notiy() in the command line so we can see the output of your_command.

An according mapping would look somewhat like this:

-- mappings.lua

vim.keymap.set("n", "<leader>a", function()
  local output = vim.fn.system("your_command 2>&1")
  vim.notify(output, vim.log.levels.INFO, { title = "Command Output" })
end, { desc = "Run your_command and show output" })

Example Plugin: pass selection to CLI and display output in floating window

selection > cli tool:output > floating window

The CLI Tool

Our "cli tool" is a very simple bash script that takes one input parameter and echoes it into the console:

echo_input.sh

#!/bin/bash

# Join all arguments into a single string
input="$*"

echo "User input was: $input"

The Plugin

lua/custom-plugins/showcase.lua

-- lua/custom-plugins/showcase.lua
-- ...

local function get_visual_selection()
  -- Yank the visual selection into register 'v'
  vim.cmd('silent! normal! "vy"')

  -- Get the contents of register 'v'
  local selected_text = vim.fn.getreg('v')

  -- Clear the register just in case
  vim.fn.setreg('v', {})

  -- Trim and normalize to single line
  return selected_text:gsub("\n", " "):gsub("^%s+", ""):gsub("%s+$", "")
end

local function shell_escape(str)
  return "'" .. str:gsub("'", [["'"']]) .. "'"
end

local function run_script_on_selection()
  local selection = get_visual_selection()

  if selection == "" then
    vim.notify("No selection found", vim.log.levels.WARN)
    return
  end

  local escaped_selection = shell_escape(selection)
  local script_path = "/home/ramboe/ramboe_dotfiles/echo_input.sh"
  local cmd = script_path .. " " .. escaped_selection
  local output = vim.fn.system(cmd)

  local buf = vim.api.nvim_create_buf(false, true)
  vim.api.nvim_buf_set_lines(buf, 0, -1, false, vim.split(output, "\n"))

  -- set window dimensions
  local width = math.floor(vim.o.columns * 0.8)
  local height = math.floor(vim.o.lines * 0.5)

  -- center window on the screen
  local row = math.floor((vim.o.lines - height) / 2)
  local col = math.floor((vim.o.columns - width) / 2)

  vim.api.nvim_open_win(buf, true, {
    relative = 'editor',
    width = width,
    height = height,
    row = row,
    col = col,
    style = 'minimal',
    border = 'rounded',
  })
end

vim.keymap.set("v", "<leader>e", run_script_on_selection, { noremap = true, silent = true })

init.lua

-- init.lua
-- ...

require("custom-plugins.showcase")

Diffusing Lazy and Mason

lazy.nvim

  • is a plugin manager that manages your neovim plugins

  • There are also other managers like packer.nvim (already depricated) but lazy seems to be the most popular and is used by NvChad, Lunar, ...

  • Lazy loads .lua code from a git repository (doesn't have to be github) that in most cases is meant to run a cli tool or script

mason.nvim

  • "Portable package manager for Neovim that runs everywhere Neovim runs"
  • Mason loads the cli tool that is meant to be somehow used / run by the .lua plugin loaded via lazy.nvim

Summary

  • Through lua and the command line you can run anything in NeoVim what you would run in your terminal in as well.

  • Lua is the integration layer that that enables us to pass information from NeoVim as parameter into console applications and display the result back in NeoVim

  • Lazy loads .lua code from a git repository (doesn't have to be github) that in most cases is meant to run a cli tool or script

  • Mason loads the cli tool that is meant to be somehow used / run by the .lua plugin loaded via QQy9_XOog