Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager

Hello everyone! In this article I will show you how to configure the neovim editor from scratch with lazy.vim.

💤 Lazy.nvim

A modern plugin manager for Neovim

Repo: folke/lazy.nvim

Outstanding features:

📦 Manage all your Neovim plugins …


This content originally appeared on DEV Community and was authored by Alejandro Londoño

Hello everyone! In this article I will show you how to configure the neovim editor from scratch with lazy.vim.

💤 Lazy.nvim

A modern plugin manager for Neovim

  • Repo: folke/lazy.nvim

  • Outstanding features:

    • 📦 Manage all your Neovim plugins with a powerful UI
    • 🚀 Fast startup times thanks to automatic caching and bytecode compilation of Lua modules
    • 🔌 Automatic lazy-loading of Lua modules and lazy-loading on events, commands, filetypes, and key mappings
    • ⏳ Automatically install missing plugins before starting up Neovim, allowing you to start using it right away
    • 🛠️ No need to manually compile plugins
    • 🧪 Correct sequencing of dependencies
    • 📁 Configurable in multiple files
    • 🔎 Automatically check for updates

📚 GitHub Repository

All the code is in my Github profile at slydragonn/nvim-lazy repo.

📹 Tutorial video

⚙ Requirements

✨ Features

📚 Project Structure

📂 nvim/
├── 📂 lua/📂 slydragonn/
│  └── 📂 plugins/
│        └── 📂 lsp/
│        └── ...pluginconfigfiles
│  └── 🌑 settings.lua
│  └── 🌑 maps.lua
│    └── 🌑 lazy.lua
└── 🌑 init.lua

If you don’t have some requirements

Saving Settings

The configuration files go to a particular place, so you should create the nvim/ folder in the following path depending on your operating system:

  • Windows: C:\Users\%YOUR_USERNAME%\AppData\Local\nvim

  • Linux: ~/.configs/nvim/

And in the nvim/ folder create the init.lua file
with the following code:

  • Note: slydragonn is my personal folder, but you can rename it whatever you want :)
-- ~/nvim/init.lua

require("slydragonn.settings")

Editor Settings

Then create a lua folder for our configuration and also for the plugins.

-- ~/nvim/lua/slydragonn/settings.lua

local global = vim.g
local o = vim.opt

-- Editor options

o.number = true -- Print the line number in front of each line
o.relativenumber = true -- Show the line number relative to the line with the cursor in front of each line.
o.clipboard = "unnamedplus" -- uses the clipboard register for all operations except yank.
o.syntax = "on" -- When this option is set, the syntax with this name is loaded.
o.autoindent = true -- Copy indent from current line when starting a new line.
o.cursorline = true -- Highlight the screen line of the cursor with CursorLine.
o.expandtab = true -- In Insert mode: Use the appropriate number of spaces to insert a <Tab>.
o.shiftwidth = 2 -- Number of spaces to use for each step of (auto)indent.
o.tabstop = 2 -- Number of spaces that a <Tab> in the file counts for.
o.encoding = "UTF-8" -- Sets the character encoding used inside Vim.
o.ruler = true -- Show the line and column number of the cursor position, separated by a comma.
o.mouse = "a" -- Enable the use of the mouse. "a" you can use on all modes
o.title = true -- When on, the title of the window will be set to the value of 'titlestring'
o.hidden = true -- When on a buffer becomes hidden when it is |abandon|ed
o.ttimeoutlen = 0 -- The time in milliseconds that is waited for a key code or mapped key sequence to complete.
o.wildmenu = true -- When 'wildmenu' is on, command-line completion operates in an enhanced mode.
o.showcmd = true -- Show (partial) command in the last line of the screen. Set this option off if your terminal is slow.
o.showmatch = true -- When a bracket is inserted, briefly jump to the matching one.
o.inccommand = "split" -- When nonempty, shows the effects of :substitute, :smagic, :snomagic and user commands with the :command-preview flag as you type.
o.splitright = true
o.splitbelow = true -- When on, splitting a window will put the new window below the current one
o.termguicolors = true

Add Lazy.vim

Installing Lazy is quite easy, you just have to copy this code from folke/lazy.nvim and paste it into ~/nvim/lua/slydragonn/lazy.lua

-- ~/nvim/lua/slydragonn/lazy.lua

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup("slydragonn.plugins")

Then in the init.lua file we import the lazy config:

-- ~/nvim/init.lua

require("slydragonn.settings")
require("slydragonn.lazy")

And create the plugins/ folder, where to add the plugin configuration files: ~/nvim/lua/plugins/

Lazy will read all the files in the plugins folder, because that's how we set it, and Lazy will install them all automatically, or we can use the command :Lazy to see the UI.

Lazy Commands

  • Open the UI: :Lazy
  • Install: shift + L
  • Sync: shift + S
  • Update: shift + U
  • Clear: shift + X
  • Check: shift + C
  • Log: shift + L
  • Restore: shift + R
  • Profile: shift + P
  • Debug: shift + D
  • Help: shift + ?

ℹ️ It is recommended to run :checkhealth lazy after installation.

Plugin Configs:

treesitter.lua

nvim-treesitter/nvim-treesitter: Nvim Treesitter configurations and abstraction layer.

--- ~/nvim/lua/slydragonn/plugins/treesiter.lua

return {
    "nvim-treesitter/nvim-treesitter",
    event = { "BufReadPre", "BufNewFile" },
    build = ":TSUpdate",
    dependencies = {
        "windwp/nvim-ts-autotag",
    },
    config = function()
        local treesitter = require("nvim-treesitter.configs")

        treesitter.setup({
            highlight = {
                enable = true,
                additional_vim_regex_highlighting = false,
            },
            indent = { enable = true },
            autotag = {
                enable = true,
            },
            ensure_installed = {
                "json",
                "javascript",
                "typescript",
                "tsx",
                "yaml",
                "html",
                "css",
                "markdown",
                "markdown_inline",
                "bash",
                "lua",
                "vim",
                "dockerfile",
                "gitignore",
                "c",
                "rust",
            },
            incremental_selection = {
                enable = true,
                keymaps = {
                    init_selection = "<C-space>",
                    node_incremental = "<C-space>",
                    scope_incremental = false,
                    node_decremental = "<bs>",
                },
            },
            rainbow = {
                enable = true,
                disable = { "html" },
                extended_mode = false,
                max_file_lines = nil,
            },
            context_commentstring = {
                enable = true,
                enable_autocmd = false,
            },
        })
    end,
}

colorscheme.lua

tiagovla/tokyodark.nvim: A clean dark theme written in lua for neovim.

-- ~/nvim/lua/slydragonn/plugins/colorscheme.lua

return {
    "tiagovla/tokyodark.nvim",
    lazy = false,
    priority = 1000,
    config = function()
        vim.cmd("colorscheme tokyodark")
    end,
}

autopairs.lua

windwp/nvim-autopairs: Autopairs for neovim written by lua.

-- ~/nvim/lua/slydragonn/plugins/autopairs.lua

return {
    "windwp/nvim-autopairs",
    event = "InsertEnter",
    config = function()
        require("nvim-autopairs").setup({
            disable_filetype = { "TelescopePrompt", "vim" },
        })
    end,
}

cmp.lua

hrsh7th/nvim-cmp: A completion plugin for neovim coded in Lua.

-- ~/nvim/lua/slydragonn/plugins/cmp.lua

return {
    "hrsh7th/nvim-cmp",
    event = "InsertEnter",
    dependencies = {
        "hrsh7th/cmp-buffer", -- source for text in buffer
        "hrsh7th/cmp-path", -- source for file system paths
        {
            "L3MON4D3/LuaSnip",
            version = "v2.*",
            -- install jsregexp (optional!).
            build = "make install_jsregexp",
        },
        "rafamadriz/friendly-snippets",
        "onsails/lspkind.nvim", -- vs-code like pictograms
    },
    config = function()
        local cmp = require("cmp")
        local lspkind = require("lspkind")
        local luasnip = require("luasnip")

        require("luasnip.loaders.from_vscode").lazy_load()

        cmp.setup({
            snippet = {
                expand = function(args)
                    luasnip.lsp_expand(args.body)
                end,
            },
            mapping = cmp.mapping.preset.insert({
                ["<C-d>"] = cmp.mapping.scroll_docs(-4),
                ["<C-f>"] = cmp.mapping.scroll_docs(4),
                ["<C-Space>"] = cmp.mapping.complete(),
                ["<C-e>"] = cmp.mapping.close(),
                ["<CR>"] = cmp.mapping.confirm({
                    behavior = cmp.ConfirmBehavior.Replace,
                    select = true,
                }),
            }),
            sources = cmp.config.sources({
                { name = "nvim_lsp" },
                { name = "luasnip" },
                { name = "buffer" },
                { name = "path" },
            }),
        })

        vim.cmd([[
      set completeopt=menuone,noinsert,noselect
      highlight! default link CmpItemKind CmpItemMenuDefault
    ]])
    end,
}

colorizer.lua

norcalli/nvim-colorizer.lua: Color highlighter.

-- ~/nvim/lua/slydragonn/plugins/colorizer.lua

return {
    "norcalli/nvim-colorizer.lua",
    config = function()
        require("colorizer").setup({ "*" })
    end,
}

lualine.lua

nvim-lualine/lualine.nvim: A blazing fast and easy to configure neovim statusline plugin written in pure lua.

-- ~/nvim/lua/slydragonn/plugins/lualine.lua

return {
    "nvim-lualine/lualine.nvim",
    dependencies = { "nvim-tree/nvim-web-devicons" },
    config = function()
        require("lualine").setup()
    end,
}

mason.lua

williamboman/mason.nvim: Portable package manager for Neovim that runs everywhere Neovim runs.

-- ~/nvim/lua/slydragonn/plugins/mason.lua

return {
    "williamboman/mason.nvim",
    dependencies = {
        "williamboman/mason-lspconfig.nvim",
        "WhoIsSethDaniel/mason-tool-installer.nvim",
    },
    config = function()
        require("mason").setup()

        require("mason-lspconfig").setup({
            automatic_installation = true,
            ensure_installed = {
                "cssls",
                "eslint",
                "html",
                "jsonls",
                "tsserver",
                "pyright",
                "tailwindcss",
            },
        })

        require("mason-tool-installer").setup({
            ensure_installed = {
                "prettier",
                "stylua", -- lua formatter
                "isort", -- python formatter
                "black", -- python formatter
                "pylint",
                "eslint_d",
            },
        })
    end,
}

lspconfig.lua

williamboman/mason-lspconfig.nvim: Extension to mason.nvim that makes it easier to use lspconfig with mason.nvim.

-- ~/nvim/lua/slydragonn/plugins/lspconfig.lua

return {
    "neovim/nvim-lspconfig",
    event = { "BufReadPre", "BufNewFile" },
    dependencies = {
        "hrsh7th/cmp-nvim-lsp",
        { "folke/neodev.nvim", opts = {} },
    },
    config = function()
        local nvim_lsp = require("lspconfig")
        local mason_lspconfig = require("mason-lspconfig")

        local protocol = require("vim.lsp.protocol")

        local on_attach = function(client, bufnr)
            -- format on save
            if client.server_capabilities.documentFormattingProvider then
                vim.api.nvim_create_autocmd("BufWritePre", {
                    group = vim.api.nvim_create_augroup("Format", { clear = true }),
                    buffer = bufnr,
                    callback = function()
                        vim.lsp.buf.format()
                    end,
                })
            end
        end

        local capabilities = require("cmp_nvim_lsp").default_capabilities()

        mason_lspconfig.setup_handlers({
            function(server)
                nvim_lsp[server].setup({
                    capabilities = capabilities,
                })
            end,
            ["tsserver"] = function()
                nvim_lsp["tsserver"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["cssls"] = function()
                nvim_lsp["cssls"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["tailwindcss"] = function()
                nvim_lsp["tailwindcss"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["html"] = function()
                nvim_lsp["html"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["jsonls"] = function()
                nvim_lsp["jsonls"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["eslint"] = function()
                nvim_lsp["eslint"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
            ["pyright"] = function()
                nvim_lsp["pyright"].setup({
                    on_attach = on_attach,
                    capabilities = capabilities,
                })
            end,
        })
    end,
}

formatter.lua

stevearc/conform.nvim: Lightweight yet powerful formatter plugin for Neovim.

-- ~/nvim/lua/slydragonn/plugins/formatter.lua

return {
    "stevearc/conform.nvim",
    event = { "BufReadPre", "BufNewFile" },
    config = function()
        local conform = require("conform")

        conform.setup({
            formatters_by_ft = {
                javascript = { "prettier" },
                typescript = { "prettier" },
                javascriptreact = { "prettier" },
                typescriptreact = { "prettier" },
                css = { "prettier" },
                html = { "prettier" },
                json = { "prettier" },
                yaml = { "prettier" },
                markdown = { "prettier" },
                lua = { "stylua" },
                python = { "isort", "black" },
            },
            format_on_save = {
                lsp_fallback = true,
                async = false,
                timeout_ms = 1000,
            },
        })

        vim.keymap.set({ "n", "v" }, "<leader>f", function()
            conform.format({
                lsp_fallback = true,
                async = false,
                timeout_ms = 1000,
            })
        end, { desc = "Format file or range (in visual mode)" })
    end,
}

gitsigns.lua

lewis6991/gitsigns.nvim: Git integration for buffers.

-- ~/nvim/lua/slydragonn/plugins/gitsigns.lua

return {
    "lewis6991/gitsigns.nvim",
    config = function()
        local gitsigns = require("gitsigns")
        gitsigns.setup({
            signs = {
                add = { text = "│" },
                change = { text = "│" },
                delete = { text = "_" },
                topdelete = { text = "‾" },
                changedelete = { text = "~" },
                untracked = { text = "┆" },
            },
            signcolumn = true, -- Toggle with `:Gitsigns toggle_signs`
            numhl = false, -- Toggle with `:Gitsigns toggle_numhl`
            linehl = false, -- Toggle with `:Gitsigns toggle_linehl`
            word_diff = false, -- Toggle with `:Gitsigns toggle_word_diff`
            watch_gitdir = {
                interval = 1000,
                follow_files = true,
            },
            attach_to_untracked = true,
            current_line_blame = false, -- Toggle with `:Gitsigns toggle_current_line_blame`
            current_line_blame_opts = {
                virt_text = true,
                virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align'
                delay = 1000,
                ignore_whitespace = false,
            },
            current_line_blame_formatter = "<author>, <author_time:%Y-%m-%d> - <summary>",
            sign_priority = 6,
            update_debounce = 100,
            status_formatter = nil, -- Use default
            max_file_length = 40000, -- Disable if file is longer than this (in lines)
            preview_config = {
                -- Options passed to nvim_open_win
                border = "single",
                style = "minimal",
                relative = "cursor",
                row = 0,
                col = 1,
            },
            yadm = {
                enable = false,
            },
        })
    end,
}

neotree.lua

nvim-neo-tree/neo-tree: Neovim plugin to manage the file system and other tree like structures.

-- ~/nvim/lua/slydragonn/plugins/neotree.lua

return {
    "nvim-neo-tree/neo-tree.nvim",
    branch = "v3.x",
    dependencies = {
        "nvim-lua/plenary.nvim",
        "nvim-tree/nvim-web-devicons",
        "MunifTanjim/nui.nvim",
        -- "3rd/image.nvim", -- Optional image support in preview window: See `# Preview Mode` for more information
    },
}

telescope.lua

nvim-telescope/telescope.nvim: Highly extendable fuzzy finder over lists.

-- ~/nvim/lua/slydragonn/plugins/telescope.lua

return {
    "nvim-telescope/telescope.nvim",
    tag = "0.1.6",
    dependencies = { "nvim-lua/plenary.nvim" },
    config = function()
        require("telescope").setup()

        -- set keymaps
        local keymap = vim.keymap

        keymap.set("n", "<leader>ff", "<cmd>Telescope find_files<cr>", { desc = "Fuzzy find files in cwd" })
        keymap.set("n", "<leader>fg", "<cmd>Telescope live_grep<cr>", { desc = "Fuzzy find recent files" })
        keymap.set("n", "<leader>fb", "<cmd>Telescope buffers<cr>", { desc = "Find string in cwd" })
        keymap.set("n", "<leader>fs", "<cmd>Telescope git_status<cr>", { desc = "Find string under cursor in cwd" })
        keymap.set("n", "<leader>fc", "<cmd>Telescope git commits<cr>", { desc = "Find todos" })
    end,
}

toggleterm.lua

akinsho/toggleterm.nvim: A neovim lua plugin to help easily manage multiple terminal windows.

-- ~/nvim/lua/slydragonn/plugins/toggleterm.lua

return {
  'akinsho/toggleterm.nvim',
  version = "*",
  config = function()
    require("toggleterm").setup({
        size = 10,
        open_mapping = [[<F7>]],
        shading_factor = 2,
        direction = "float",
        float_opts = {
            border = "curved",
            highlights = {
                border = "Normal",
                background = "Normal",
            },
        },
    }) 

  end,
}

When all plugins are added, we write the command :Lazy and we press shift + L to Install or shift + S to sync.

Editor Key bindings

Inside of init.lua requires the maps file.

-- ~/nvim/init.lua
require("slydragonn.settings")
require("slydragonn.lazy")
require("slydragonn.maps") -- key bindings

maps.lua

-- ~/nvim/lua/slydragonn/maps.lua

vim.g.mapleader = " "

local function map(mode, lhs, rhs)
    vim.keymap.set(mode, lhs, rhs, { silent = true })
end


-- Save
map("n", "<leader>w", "<CMD>update<CR>")

-- Quit
map("n", "<leader>q", "<CMD>q<CR>")

-- Exit insert mode
map("i", "jk", "<ESC>")

-- NeoTree
map("n", "<leader>e", "<CMD>Neotree toggle<CR>")
map("n", "<leader>r", "<CMD>Neotree focus<CR>")

-- New Windows
map("n", "<leader>o", "<CMD>vsplit<CR>")
map("n", "<leader>p", "<CMD>split<CR>")

-- Window Navigation
map("n", "<C-h>", "<C-w>h")
map("n", "<C-l>", "<C-w>l")
map("n", "<C-k>", "<C-w>k")
map("n", "<C-j>", "<C-w>j")

-- Resize Windows
map("n", "<C-Left>", "<C-w><")
map("n", "<C-Right>", "<C-w>>")
map("n", "<C-Up>", "<C-w>+")
map("n", "<C-Down>", "<C-w>-")

And that's it, with this setup you should have an amazing neovim editor.

📚 Resources

Thanks for reading and see you later!


This content originally appeared on DEV Community and was authored by Alejandro Londoño


Print Share Comment Cite Upload Translate Updates
APA

Alejandro Londoño | Sciencx (2024-06-25T00:54:33+00:00) Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager. Retrieved from https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/

MLA
" » Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager." Alejandro Londoño | Sciencx - Tuesday June 25, 2024, https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/
HARVARD
Alejandro Londoño | Sciencx Tuesday June 25, 2024 » Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager., viewed ,<https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/>
VANCOUVER
Alejandro Londoño | Sciencx - » Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/
CHICAGO
" » Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager." Alejandro Londoño | Sciencx - Accessed . https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/
IEEE
" » Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager." Alejandro Londoño | Sciencx [Online]. Available: https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/. [Accessed: ]
rf:citation
» Ultimate Neovim Setup Guide: lazy.nvim Plugin Manager | Alejandro Londoño | Sciencx | https://www.scien.cx/2024/06/25/ultimate-neovim-setup-guide-lazy-nvim-plugin-manager/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.