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"
}
},