Extra Plugins
Every plugin that works with Neovim works with LunarVim, here are some examples to get you started.
Navigation pluginsโ
hopโ
neovim motions on speed!
{
"phaazon/hop.nvim",
event = "BufRead",
config = function()
require("hop").setup()
vim.api.nvim_set_keymap("n", "s", ":HopChar2<cr>", { silent = true })
vim.api.nvim_set_keymap("n", "S", ":HopWord<cr>", { silent = true })
end,
},
lightspeedโ
jetpack codebase navigation
{
"ggandor/lightspeed.nvim",
event = "BufRead",
},
mini.mapโ
blazing fast minimap/scrollbar in Lua
{
"echasnovski/mini.map",
branch = "stable",
config = function()
require('mini.map').setup()
local map = require('mini.map')
map.setup({
integrations = {
map.gen_integration.builtin_search(),
map.gen_integration.diagnostic({
error = 'DiagnosticFloatingError',
warn = 'DiagnosticFloatingWarn',
info = 'DiagnosticFloatingInfo',
hint = 'DiagnosticFloatingHint',
}),
},
symbols = {
encode = map.gen_encode_symbols.dot('4x2'),
},
window = {
side = 'right',
width = 20, -- set to 1 for a pure scrollbar :)
winblend = 15,
show_integration_count = false,
},
})
end
},
automatically open mini.map and exclude buffers, filetypesโ
mini.map doesn't automatically open, by design. The following makes sure to fix that and excludes buffers/filetypes you don't want it to open:
lvim.autocommands = {
{
{"BufEnter", "Filetype"},
{
desc = "Open mini.map and exclude some filetypes",
pattern = { "*" },
callback = function()
local exclude_ft = {
"qf",
"NvimTree",
"toggleterm",
"TelescopePrompt",
"alpha",
"netrw",
}
local map = require('mini.map')
if vim.tbl_contains(exclude_ft, vim.o.filetype) then
vim.b.minimap_disable = true
map.close()
elseif vim.o.buftype == "" then
map.open()
end
end,
},
},
}
numbโ
jump to the line
{
"nacro90/numb.nvim",
event = "BufRead",
config = function()
require("numb").setup {
show_numbers = true, -- Enable 'number' for the window while peeking
show_cursorline = true, -- Enable 'cursorline' for the window while peeking
}
end,
},
nvim-bqfโ
better quickfix window
{
"kevinhwang91/nvim-bqf",
event = { "BufRead", "BufNew" },
config = function()
require("bqf").setup({
auto_enable = true,
preview = {
win_height = 12,
win_vheight = 12,
delay_syntax = 80,
border_chars = { "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ" },
},
func_map = {
vsplit = "",
ptogglemode = "z,",
stoggleup = "",
},
filter = {
fzf = {
action_for = { ["ctrl-s"] = "split" },
extra_opts = { "--bind", "ctrl-o:toggle-all", "--prompt", "> " },
},
},
})
end,
},
nvim-spectreโ
search and replace
{
"windwp/nvim-spectre",
event = "BufRead",
config = function()
require("spectre").setup()
end,
},
neo-treeโ
neo-tree is a plugin to manage the file system and other tree like structures
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v2.x",
requires = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
},
config = function()
require("neo-tree").setup({
close_if_last_window = true,
window = {
width = 30,
},
buffers = {
follow_current_file = true,
},
filesystem = {
follow_current_file = true,
filtered_items = {
hide_dotfiles = false,
hide_gitignored = false,
hide_by_name = {
"node_modules"
},
never_show = {
".DS_Store",
"thumbs.db"
},
},
},
})
end
},
After installing ensure to disable nvim-tree
it in your config.lua
using:
...
lvim.builtin.nvimtree.active = false -- NOTE: using neo-tree
...
rnvimrโ
ranger file explorer window
{
"kevinhwang91/rnvimr",
cmd = "RnvimrToggle",
config = function()
vim.g.rnvimr_draw_border = 1
vim.g.rnvimr_pick_enable = 1
vim.g.rnvimr_bw_enable = 1
end,
},
snapโ
fast finder system
{
"camspiers/snap",
rocks = "fzy",
config = function()
local snap = require "snap"
local layout = snap.get("layout").bottom
local file = snap.config.file:with { consumer = "fzy", layout = layout }
local vimgrep = snap.config.vimgrep:with { layout = layout }
snap.register.command("find_files", file { producer = "ripgrep.file" })
snap.register.command("buffers", file { producer = "vim.buffer" })
snap.register.command("oldfiles", file { producer = "vim.oldfile" })
snap.register.command("live_grep", vimgrep {})
end,
},
vim-matchupโ
navigate and highlight matching words
{
"andymass/vim-matchup",
event = "CursorMoved",
config = function()
vim.g.matchup_matchparen_offscreen = { method = "popup" }
end,
},
nvim-window-pickerโ
jump to any window using a selector like the one nvim-tree uses
{
"s1n7ax/nvim-window-picker",
tag = "1.*",
config = function()
require("window-picker").setup({
autoselect_one = true,
include_current = false,
filter_rules = {
-- filter using buffer options
bo = {
-- if the file type is one of following, the window will be ignored
filetype = { "neo-tree", "neo-tree-popup", "notify", "quickfix" },
-- if the buffer type is one of following, the window will be ignored
buftype = { "terminal" },
},
},
other_win_hl_color = "#e35e4f",
})
end,
}
-- example mappings you can place in some other place
-- An awesome method to jump to windows
local picker = require('window-picker')
vim.keymap.set("n", ",w", function()
local picked_window_id = picker.pick_window({
include_current_win = true
}) or vim.api.nvim_get_current_win()
vim.api.nvim_set_current_win(picked_window_id)
end, { desc = "Pick a window" })
-- Swap two windows using the awesome window picker
local function swap_windows()
local window = picker.pick_window({
include_current_win = false
})
local target_buffer = vim.fn.winbufnr(window)
-- Set the target window to contain current buffer
vim.api.nvim_win_set_buf(window, 0)
-- Set current window to contain target buffer
vim.api.nvim_win_set_buf(0, target_buffer)
end
vim.keymap.set('n', ',W', swap_windows, { desc = 'Swap windows' })
Gitโ
diffviewโ
git diff in a single tabpage
{
"sindrets/diffview.nvim",
event = "BufRead",
},
git-blameโ
show git blame
{
"f-person/git-blame.nvim",
event = "BufRead",
config = function()
vim.cmd "highlight default link gitblame SpecialComment"
vim.g.gitblame_enabled = 0
end,
},
gitlinkerโ
generate shareable file permalinks for several git web frontend hosts
{
"ruifm/gitlinker.nvim",
event = "BufRead",
config = function()
require("gitlinker").setup {
opts = {
-- remote = 'github', -- force the use of a specific remote
-- adds current line nr in the url for normal mode
add_current_line_on_normal_mode = true,
-- callback for what to do with the url
action_callback = require("gitlinker.actions").open_in_browser,
-- print the url after performing the action
print_url = false,
-- mapping to call url generation
mappings = "<leader>gy",
},
}
end,
requires = "nvim-lua/plenary.nvim",
},
octoโ
edit and review GitHub issues and pull requests
{
"pwntester/octo.nvim",
requires = {
'nvim-lua/plenary.nvim',
'nvim-telescope/telescope.nvim',
'kyazdani42/nvim-web-devicons',
},
config = function()
require("octo").setup()
end,
},
vim-fugitiveโ
git wrapper
{
"tpope/vim-fugitive",
cmd = {
"G",
"Git",
"Gdiffsplit",
"Gread",
"Gwrite",
"Ggrep",
"GMove",
"GDelete",
"GBrowse",
"GRemove",
"GRename",
"Glgrep",
"Gedit"
},
ft = {"fugitive"}
},
vim-gistโ
create/edit Github gists
{
"mattn/vim-gist",
event = "BufRead",
requires = "mattn/webapi-vim",
},
Treesitterโ
nvim-ts-autotagโ
autoclose and autorename html tag
{
"windwp/nvim-ts-autotag",
config = function()
require("nvim-ts-autotag").setup()
end,
},
nvim-ts-context-commentstringโ
commentstring option based on the cursor location
{
"JoosepAlviste/nvim-ts-context-commentstring",
event = "BufRead",
},
nvim-ts-rainbowโ
rainbow parentheses
{
"mrjones2014/nvim-ts-rainbow",
},
After installing ensure to enable it in your config.lua
using:
...
lvim.builtin.treesitter.rainbow.enable = true
...
playgroundโ
view treesitter information
{
"nvim-treesitter/playground",
event = "BufRead",
},
nvim-treesitter-contextโ
Show current function at the top of the screen when function does not fit in screen
{
"romgrk/nvim-treesitter-context",
config = function()
require("treesitter-context").setup{
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
throttle = true, -- Throttles plugin updates (may improve performance)
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
patterns = { -- Match patterns for TS nodes. These get wrapped to match at word boundaries.
-- For all filetypes
-- Note that setting an entry here replaces all other patterns for this entry.
-- By setting the 'default' entry below, you can control which nodes you want to
-- appear in the context window.
default = {
'class',
'function',
'method',
},
},
}
end
},
Telescope Extensionsโ
How to install telescope extensionsโ
First add your telescope extension to the list of plugins as usual (lvim.plugins = { ... }
) following the extension instructions.
There are several ways to register extensions within telescope, but the safer is using the on_config_done
callback for telescope.
Create the callback function anywhere in your config.lua
. This function will be called when telescope has finished loading and will get telescope as its only parameter.
Finally, within the on_config_done
callback register your extension :
lvim.builtin.telescope.on_config_done = function(telescope)
pcall(telescope.load_extension, "frecency")
pcall(telescope.load_extension, "neoclip")
-- any other extensions loading
end
telescope-fzy-native.nvimโ
fzy style sorter that is compiled
{
"nvim-telescope/telescope-fzy-native.nvim",
run = "make",
event = "BufRead",
},
telescope-projectโ
switch between projects
{
"nvim-telescope/telescope-project.nvim",
event = "BufWinEnter",
setup = function()
vim.cmd [[packadd telescope.nvim]]
end,
},
Colorschemesโ
lsp-colorsโ
lsp diagnostics highlight groups for non lsp colorschemes
{
"folke/lsp-colors.nvim",
event = "BufRead",
},
lush.nvimโ
colorscheme creation aid
{
"rktjmp/lush.nvim",
},
nvim-colorizerโ
color highlighter
{
"norcalli/nvim-colorizer.lua",
config = function()
require("colorizer").setup({ "css", "scss", "html", "javascript" }, {
RGB = true, -- #RGB hex codes
RRGGBB = true, -- #RRGGBB hex codes
RRGGBBAA = true, -- #RRGGBBAA hex codes
rgb_fn = true, -- CSS rgb() and rgba() functions
hsl_fn = true, -- CSS hsl() and hsla() functions
css = true, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB
css_fn = true, -- Enable all CSS *functions*: rgb_fn, hsl_fn
})
end,
},
LSP Enhancementโ
cmp-tabnineโ
TabNine completion engine for hrsh7th/nvim-cmp
{
"tzachar/cmp-tabnine",
run = "./install.sh",
requires = "hrsh7th/nvim-cmp",
event = "InsertEnter",
},
goto-previewโ
previewing goto definition calls
{
"rmagatti/goto-preview",
config = function()
require('goto-preview').setup {
width = 120; -- Width of the floating window
height = 25; -- Height of the floating window
default_mappings = false; -- Bind default mappings
debug = false; -- Print debug information
opacity = nil; -- 0-100 opacity level of the floating window where 100 is fully transparent.
post_open_hook = nil -- A function taking two arguments, a buffer and a window to be ran as a hook.
-- You can use "default_mappings = true" setup option
-- Or explicitly set keybindings
-- vim.cmd("nnoremap gpd <cmd>lua require('goto-preview').goto_preview_definition()<CR>")
-- vim.cmd("nnoremap gpi <cmd>lua require('goto-preview').goto_preview_implementation()<CR>")
-- vim.cmd("nnoremap gP <cmd>lua require('goto-preview').close_all_win()<CR>")
}
end
},
lsp-rooterโ
cwd to the project's root directory
{
"ahmedkhalf/lsp-rooter.nvim",
event = "BufRead",
config = function()
require("lsp-rooter").setup()
end,
},
lsp_signature.nvimโ
hint when you type
{
"ray-x/lsp_signature.nvim",
event = "BufRead",
config = function() require"lsp_signature".on_attach() end,
},
symbols-outline.nvimโ
a tree like view for symbols
{
"simrat39/symbols-outline.nvim",
config = function()
require('symbols-outline').setup()
end
},
trouble.nvimโ
diagnostics, references, telescope results, quickfix and location lists
{
"folke/trouble.nvim",
cmd = "TroubleToggle",
},
Also define keybindings in config.lua
lvim.builtin.which_key.mappings["t"] = {
name = "Diagnostics",
t = { "<cmd>TroubleToggle<cr>", "trouble" },
w = { "<cmd>TroubleToggle workspace_diagnostics<cr>", "workspace" },
d = { "<cmd>TroubleToggle document_diagnostics<cr>", "document" },
q = { "<cmd>TroubleToggle quickfix<cr>", "quickfix" },
l = { "<cmd>TroubleToggle loclist<cr>", "loclist" },
r = { "<cmd>TroubleToggle lsp_references<cr>", "references" },
},
Generalโ
auto-saveโ
automatically saving your work whenever you make changes to it
{
"Pocco81/auto-save.nvim",
config = function()
require("auto-save").setup()
end,
},
codi.vimโ
interactive scratchpad for hackers
{
"metakirby5/codi.vim",
cmd = "Codi",
},
copilot.lua and copilot-cmpโ
let a computer write code for you
You need to authenticate according to the instructions.
lvim.plugins = {
{ "zbirenbaum/copilot.lua",
event = { "VimEnter" },
config = function()
vim.defer_fn(function()
require("copilot").setup {
plugin_manager_path = get_runtime_dir() .. "/site/pack/packer",
}
end, 100)
end,
},
{ "zbirenbaum/copilot-cmp",
after = { "copilot.lua", "nvim-cmp" },
},
...
}
-- Can not be placed into the config method of the plugins.
lvim.builtin.cmp.formatting.source_names["copilot"] = "(Copilot)"
table.insert(lvim.builtin.cmp.sources, 1, { name = "copilot" })
dial.nvimโ
extended incrementing/decrementing
{
"monaqa/dial.nvim",
event = "BufRead",
config = function()
local dial = require "dial"
vim.cmd [[
nmap <C-a> <Plug>(dial-increment)
nmap <C-x> <Plug>(dial-decrement)
vmap <C-a> <Plug>(dial-increment)
vmap <C-x> <Plug>(dial-decrement)
vmap g<C-a> <Plug>(dial-increment-additional)
vmap g<C-x> <Plug>(dial-decrement-additional)
]]
dial.augends["custom#boolean"] = dial.common.enum_cyclic {
name = "boolean",
strlist = { "true", "false" },
}
table.insert(dial.config.searchlist.normal, "custom#boolean")
-- For Languages which prefer True/False, e.g. python.
dial.augends["custom#Boolean"] = dial.common.enum_cyclic {
name = "Boolean",
strlist = { "True", "False" },
}
table.insert(dial.config.searchlist.normal, "custom#Boolean")
end,
},
glow.nvimโ
preview markdown in neovim
-- You must install glow globally
-- https://github.com/charmbracelet/glow
-- yay -S glow
{
"npxbr/glow.nvim",
ft = {"markdown"}
-- run = "yay -S glow"
},
markdown-preview.nvimโ
preview markdown in the browser
{
"iamcco/markdown-preview.nvim",
build = "cd app && npm install",
ft = "markdown",
config = function()
vim.g.mkdp_auto_start = 1
end,
},
neoscrollโ
smooth scrolling
{
"karb94/neoscroll.nvim",
event = "WinScrolled",
config = function()
require('neoscroll').setup({
-- All these keys will be mapped to their corresponding default scrolling animation
mappings = {'<C-u>', '<C-d>', '<C-b>', '<C-f>',
'<C-y>', '<C-e>', 'zt', 'zz', 'zb'},
hide_cursor = true, -- Hide cursor while scrolling
stop_eof = true, -- Stop at <EOF> when scrolling downwards
use_local_scrolloff = false, -- Use the local scope of scrolloff instead of the global scope
respect_scrolloff = false, -- Stop scrolling when the cursor reaches the scrolloff margin of the file
cursor_scrolls_alone = true, -- The cursor will keep on scrolling even if the window cannot scroll further
easing_function = nil, -- Default easing function
pre_hook = nil, -- Function to run before the scrolling animation starts
post_hook = nil, -- Function to run after the scrolling animation ends
})
end
},
neuronโ
next generation note-taking
{"oberblastmeister/neuron.nvim"},
nvim-lastplaceโ
pick up where you left off
{
"ethanholz/nvim-lastplace",
event = "BufRead",
config = function()
require("nvim-lastplace").setup({
lastplace_ignore_buftype = { "quickfix", "nofile", "help" },
lastplace_ignore_filetype = {
"gitcommit", "gitrebase", "svn", "hgcommit",
},
lastplace_open_folds = true,
})
end,
},
persistenceโ
simple session management
{
"folke/persistence.nvim",
event = "BufReadPre", -- this will only start session saving when an actual file was opened
module = "persistence",
config = function()
require("persistence").setup {
dir = vim.fn.expand(vim.fn.stdpath "config" .. "/session/"),
options = { "buffers", "curdir", "tabpages", "winsize" },
}
end,
},
Also define keybindings in your config.lua
lvim.builtin.which_key.mappings["S"]= {
name = "Session",
c = { "<cmd>lua require('persistence').load()<cr>", "Restore last session for current dir" },
l = { "<cmd>lua require('persistence').load({ last = true })<cr>", "Restore last session" },
Q = { "<cmd>lua require('persistence').stop()<cr>", "Quit without saving session" },
}
todo-comments.nvimโ
highlight and search for todo comments
{
"folke/todo-comments.nvim",
event = "BufRead",
config = function()
require("todo-comments").setup()
end,
},
vim-cursorwordโ
underlines the word under the cursor
{
"itchyny/vim-cursorword",
event = {"BufEnter", "BufNewFile"},
config = function()
vim.api.nvim_command("augroup user_plugin_cursorword")
vim.api.nvim_command("autocmd!")
vim.api.nvim_command("autocmd FileType NvimTree,lspsagafinder,dashboard,vista let b:cursorword = 0")
vim.api.nvim_command("autocmd WinEnter * if &diff || &pvw | let b:cursorword = 0 | endif")
vim.api.nvim_command("autocmd InsertEnter * let b:cursorword = 0")
vim.api.nvim_command("autocmd InsertLeave * let b:cursorword = 1")
vim.api.nvim_command("augroup END")
end
},
vim-repeatโ
enable repeating supported plugin maps with "."
{ "tpope/vim-repeat" },
vim-sanegxโ
open url with gx
{
"felipec/vim-sanegx",
event = "BufRead",
},
vim-surroundโ
mappings to delete, change and add surroundings
{
"tpope/vim-surround",
-- make sure to change the value of `timeoutlen` if it's not triggering correctly, see https://github.com/tpope/vim-surround/issues/117
-- setup = function()
-- vim.o.timeoutlen = 500
-- end
},
vim-wakatimeโ
metrics, insights, and time tracking automatically generated from your programming activity
{
"wakatime/vim-wakatime"
}
Once installed and synced, add your WakaTime API Key via :WakaTimeApiKey
command
Language specificโ
braceyโ
live edit html, css, and javascript
{
"turbio/bracey.vim",
cmd = {"Bracey", "BracyStop", "BraceyReload", "BraceyEval"},
run = "npm install --prefix server",
},
vim-bundlerโ
lightweight support for ruby's bundler
{
"tpope/vim-bundler",
cmd = {"Bundler", "Bopen", "Bsplit", "Btabedit"}
},
vim-railsโ
edit ruby on rails applications
{
"tpope/vim-rails",
cmd = {
"Eview",
"Econtroller",
"Emodel",
"Smodel",
"Sview",
"Scontroller",
"Vmodel",
"Vview",
"Vcontroller",
"Tmodel",
"Tview",
"Tcontroller",
"Rails",
"Generate",
"Runner",
"Extract"
}
},