dotfiles/nvim/lua/plugin_specs.lua
2026-06-02 08:20:14 +02:00

842 lines
22 KiB
Lua

local utils = require("utils")
local plugin_dir = vim.fs.joinpath(vim.fn.stdpath("data"), "lazy")
local lazypath = vim.fs.joinpath(plugin_dir, "lazy.nvim")
if not vim.uv.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)
-- check if firenvim is active
local firenvim_not_active = function()
return not vim.g.started_by_firenvim
end
local plugin_specs = {
-- auto-completion engine
{ "hrsh7th/cmp-nvim-lsp", lazy = true },
{ "hrsh7th/cmp-path", lazy = true },
{ "hrsh7th/cmp-buffer", lazy = true },
{ "hrsh7th/cmp-omni", lazy = true },
{ "hrsh7th/cmp-cmdline", lazy = true },
{ "quangnguyen30192/cmp-nvim-ultisnips", lazy = true },
{
"hrsh7th/nvim-cmp",
name = "nvim-cmp",
event = "VeryLazy",
config = function()
require("config.nvim-cmp")
end,
},
-- {
-- "saghen/blink.cmp",
-- -- optional: provides snippets for the snippet source
-- dependencies = {
-- "rafamadriz/friendly-snippets",
-- "archie-judd/blink-cmp-words",
-- },
-- -- use a release tag to download pre-built binaries
-- version = "1.*",
-- config = function()
-- require("config.blink-cmp")
-- end,
-- opts_extend = { "sources.default" },
-- },
{
"neovim/nvim-lspconfig",
},
{
"dnlhc/glance.nvim",
config = function()
require("config.glance")
end,
event = "VeryLazy",
},
{
"nvim-treesitter/nvim-treesitter",
lazy = false,
build = ":TSUpdate",
branch = "main",
config = function()
require("config.treesitter")
end,
},
{
"nvim-treesitter/nvim-treesitter-textobjects",
event = "VeryLazy",
branch = "main",
init = function()
-- Disable entire built-in ftplugin mappings to avoid conflicts.
-- See https://github.com/neovim/neovim/tree/master/runtime/ftplugin for built-in ftplugins.
vim.g.no_plugin_maps = true
-- Or, disable per filetype (add as you like)
-- vim.g.no_python_maps = true
-- vim.g.no_ruby_maps = true
-- vim.g.no_rust_maps = true
-- vim.g.no_go_maps = true
end,
config = function()
require("config.treesitter-textobjects")
end,
},
{
"mizlan/iswap.nvim",
event = "VeryLazy",
config = function()
require("config.iswap")
end,
},
-- Super fast buffer jump
{
"smoka7/hop.nvim",
keys = { "f" },
config = function()
require("config.nvim_hop")
end,
},
-- Show match number and index for searching
{
"kevinhwang91/nvim-hlslens",
branch = "main",
keys = { "*", "#", "n", "N" },
config = function()
require("config.hlslens")
end,
},
{
"nvim-telescope/telescope.nvim",
cmd = "Telescope",
dependencies = {
"nvim-telescope/telescope-symbols.nvim",
},
},
{
"ibhagwan/fzf-lua",
config = function()
require("config.fzf-lua")
end,
event = "VeryLazy",
},
{
"MeanderingProgrammer/render-markdown.nvim",
main = "render-markdown",
opts = {},
ft = { "markdown" },
},
-- A list of colorscheme plugin you may want to try. Find what suits you.
{ "navarasu/onedark.nvim", lazy = true },
{ "sainnhe/edge", lazy = true },
{ "sainnhe/sonokai", lazy = true },
{ "sainnhe/gruvbox-material", lazy = true },
{
"sainnhe/everforest",
lazy = false,
priority = 1000,
name = "everforest",
config = function()
vim.g.everforest_enable_italic = true
vim.g.everforest_background = "hard"
vim.cmd("colorscheme everforest")
end,
},
{ "EdenEast/nightfox.nvim", lazy = true },
{ "catppuccin/nvim", name = "catppuccin", lazy = true },
{ "olimorris/onedarkpro.nvim", lazy = true },
{ "marko-cerovac/material.nvim", lazy = true },
{
"rockyzhang24/arctic.nvim",
dependencies = { "rktjmp/lush.nvim" },
name = "arctic",
branch = "v2",
},
{ "rebelot/kanagawa.nvim", lazy = true },
{ "miikanissi/modus-themes.nvim", priority = 1000 },
{ "wtfox/jellybeans.nvim", priority = 1000 },
{ "projekt0n/github-nvim-theme", name = "github-theme" },
{ "ficcdaf/ashen.nvim", priority = 1000 },
{ "savq/melange-nvim", priority = 1000 },
{ "Skardyy/makurai-nvim", priority = 1000 },
{ "vague2k/vague.nvim", priority = 1000 },
{ "webhooked/kanso.nvim", priority = 1000 },
{ "zootedb0t/citruszest.nvim", priority = 1000 },
{ "nyoom-engineering/oxocarbon.nvim", priority = 1000 },
{ "ember-theme/nvim", name = "ember", priority = 1000 },
{ "yonatanperel/lake-dweller.nvim", priority = 1000 },
{ "dchinmay2/alabaster.nvim", priority = 1000 },
{ "jpwol/thorn.nvim", priority = 1000 },
-- plugins to provide nerdfont icons
{
"nvim-mini/mini.icons",
version = false,
config = function()
-- this is the compatibility fix for plugins that only support nvim-web-devicons
require("mini.icons").mock_nvim_web_devicons()
require("mini.icons").tweak_lsp_kind()
end,
lazy = true,
},
{
"nvim-lualine/lualine.nvim",
event = "BufRead",
cond = firenvim_not_active,
config = function()
require("config.lualine")
end,
},
{
"akinsho/bufferline.nvim",
event = { "BufEnter" },
cond = firenvim_not_active,
config = function()
require("config.bufferline")
end,
},
{
"nvim-mini/mini.indentscope",
version = false,
config = function()
local mini_indent = require("mini.indentscope")
mini_indent.setup {
draw = {
animation = mini_indent.gen_animation.none(),
},
symbol = "",
}
end,
},
{
"luukvbaal/statuscol.nvim",
opts = {},
config = function()
require("config.nvim-statuscol")
end,
},
{
"kevinhwang91/nvim-ufo",
dependencies = "kevinhwang91/promise-async",
event = "VeryLazy",
opts = {},
init = function()
vim.o.foldcolumn = "1" -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true
end,
config = function()
require("config.nvim_ufo")
end,
},
-- Highlight URLs inside vim
{ "itchyny/vim-highlighturl", event = "BufReadPost" },
-- notification plugin
{
"rcarriga/nvim-notify",
event = "VeryLazy",
config = function()
require("config.nvim-notify")
end,
},
{ "nvim-lua/plenary.nvim", lazy = true },
-- For Windows and Mac, we can open an URL in the browser. For Linux, it may
-- not be possible since we maybe in a server which disables GUI.
{
"chrishrb/gx.nvim",
keys = { { "gx", "<cmd>Browse<cr>", mode = { "n", "x" } } },
cmd = { "Browse" },
init = function()
vim.g.netrw_nogx = 1 -- disable netrw gx
end,
enabled = function()
return vim.g.is_win or vim.g.is_mac
end,
config = function()
require("config.gx")
end,
submodules = false, -- not needed, submodules are required only for tests
},
-- Only install these plugins if ctags are installed on the system
-- show file tags in vim window
{
"liuchengxu/vista.vim",
init = function()
vim.cmd([[
let g:vista#renderer#icons = {
\ 'member': '',
\ }
" Do not echo message on command line
let g:vista_echo_cursor = 0
" Stay in current window when vista window is opened
let g:vista_stay_on_open = 0
nnoremap <silent> <Space>t :<C-U>Vista!!<CR>
]])
end,
enabled = function()
return utils.executable("ctags")
end,
cmd = "Vista",
},
-- Snippet engine and snippet template
{
"SirVer/ultisnips",
init = function()
vim.cmd([[
" Trigger configuration. Do not use <tab> if you use YouCompleteMe
let g:UltiSnipsExpandTrigger='<c-j>'
" Do not look for SnipMate snippets
let g:UltiSnipsEnableSnipMate = 0
" Shortcut to jump forward and backward in tabstop positions
let g:UltiSnipsJumpForwardTrigger='<c-j>'
let g:UltiSnipsJumpBackwardTrigger='<c-k>'
" Configuration for custom snippets directory, see
" https://jdhao.github.io/2019/04/17/neovim_snippet_s1/ for details.
let g:UltiSnipsSnippetDirectories=['UltiSnips', 'my_snippets']
]])
end,
event = "VeryLazy",
},
-- Automatic insertion and deletion of a pair of characters
{
"windwp/nvim-autopairs",
event = "InsertEnter",
config = true,
},
-- Comment plugin
{
"tpope/vim-commentary",
keys = {
{ "gc", mode = "n" },
{ "gc", mode = "v" },
},
},
-- Multiple cursor plugin like Sublime Text?
-- 'mg979/vim-visual-multi'
-- Manage your yank history
{
"gbprod/yanky.nvim",
config = function()
require("config.yanky")
end,
cmd = "YankyRingHistory",
},
-- Handy unix command inside Vim (Rename, Move etc.)
{ "tpope/vim-eunuch", cmd = { "Rename", "Delete" } },
-- Repeat vim motions
{ "tpope/vim-repeat", event = "VeryLazy" },
{
"nvim-zh/better-escape.vim",
init = function()
vim.cmd([[
let g:better_escape_interval = 200
]])
end,
event = { "InsertEnter" },
},
{
"lyokha/vim-xkbswitch",
init = function()
vim.cmd([[
let g:XkbSwitchEnabled = 1
]])
end,
enabled = function()
return vim.g.is_mac and utils.executable("xkbswitch")
end,
event = { "InsertEnter" },
},
{
"Neur1n/neuims",
enabled = function()
return vim.g.is_win
end,
event = { "InsertEnter" },
},
-- Git command inside vim
{
"tpope/vim-fugitive",
event = "User InGitRepo",
config = function()
require("config.fugitive")
end,
},
{
"NeogitOrg/neogit",
dependencies = {
"nvim-lua/plenary.nvim", -- required
"sindrets/diffview.nvim", -- optional - Diff integration
-- Only one of these is needed.
"ibhagwan/fzf-lua", -- optional
},
event = "User InGitRepo",
},
-- Better git log display
{ "rbong/vim-flog", cmd = { "Flog" } },
{
"ruifm/gitlinker.nvim",
event = "User InGitRepo",
config = function()
require("config.git-linker")
end,
},
-- Show git change (change, delete, add) signs in vim sign column
{
"lewis6991/gitsigns.nvim",
config = function()
require("config.gitsigns")
end,
event = "BufRead",
version = "*",
},
{
"sindrets/diffview.nvim",
cmd = { "DiffviewOpen" },
config = function()
require("config.diffview")
end,
},
{
"barrettruth/diffs.nvim",
init = function()
vim.g.diffs = {
integrations = {
fugitive = true,
neogit = true,
gitsigns = true,
},
}
end,
},
{
"esmuellert/codediff.nvim",
cmd = "CodeDiff",
},
{
"kevinhwang91/nvim-bqf",
ft = "qf",
config = function()
require("config.bqf")
end,
},
-- Faster footnote generation
{ "vim-pandoc/vim-markdownfootnotes", ft = { "markdown" } },
-- Vim tabular plugin for manipulate tabular, required by markdown plugins
{ "godlygeek/tabular", ft = { "markdown" } },
{
"chrisbra/unicode.vim",
init = function()
vim.cmd([[
nmap ga <Plug>(UnicodeGA)
]])
end,
event = "VeryLazy",
},
-- Additional powerful text object for vim, this plugin should be studied
-- carefully to use its full power
{ "wellle/targets.vim", event = "VeryLazy" },
-- Plugin to manipulate character pairs quickly
{
"machakann/vim-sandwich",
init = function()
vim.cmd([[
" Map s to nop since s in used by vim-sandwich. Use cl instead of s.
nmap s <Nop>
omap s <Nop>
]])
end,
event = "VeryLazy",
},
-- Only use these plugin on Windows and Mac and when LaTeX is installed
{
"lervag/vimtex",
init = function()
vim.cmd([[
if executable('latex')
" Hacks for inverse search to work semi-automatically,
" see https://jdhao.github.io/2021/02/20/inverse_search_setup_neovim_vimtex/.
function! s:write_server_name() abort
let nvim_server_file = (has('win32') ? $TEMP : '/tmp') . '/vimtexserver.txt'
call writefile([v:servername], nvim_server_file)
endfunction
augroup vimtex_common
autocmd!
autocmd FileType tex call s:write_server_name()
autocmd FileType tex nmap <buffer> <F9> <plug>(vimtex-compile)
augroup END
let g:vimtex_compiler_latexmk = {
\ 'build_dir' : 'build',
\ }
" TOC settings
let g:vimtex_toc_config = {
\ 'name' : 'TOC',
\ 'layers' : ['content', 'todo', 'include'],
\ 'resize' : 1,
\ 'split_width' : 30,
\ 'todo_sorted' : 0,
\ 'show_help' : 1,
\ 'show_numbers' : 1,
\ 'mode' : 2,
\ }
" Viewer settings for different platforms
if g:is_win
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_view_general_options = '-reuse-instance -forward-search @tex @line @pdf'
endif
if g:is_mac
" let g:vimtex_view_method = "skim"
let g:vimtex_view_general_viewer = '/Applications/Skim.app/Contents/SharedSupport/displayline'
let g:vimtex_view_general_options = '-r @line @pdf @tex'
augroup vimtex_mac
autocmd!
autocmd User VimtexEventCompileSuccess call UpdateSkim()
augroup END
" The following code is adapted from https://gist.github.com/skulumani/7ea00478c63193a832a6d3f2e661a536.
function! UpdateSkim() abort
let l:out = b:vimtex.out()
let l:src_file_path = expand('%:p')
let l:cmd = [g:vimtex_view_general_viewer, '-r']
if !empty(system('pgrep Skim'))
call extend(l:cmd, ['-g'])
endif
call jobstart(l:cmd + [line('.'), l:out, l:src_file_path])
endfunction
endif
endif
]])
end,
enabled = function()
return utils.executable("latex")
end,
ft = { "tex" },
},
-- Since tmux is only available on Linux and Mac, we only enable these plugins
-- for Linux and Mac
-- .tmux.conf syntax highlighting and setting check
{
"tmux-plugins/vim-tmux",
enabled = function()
return utils.executable("tmux")
end,
ft = { "tmux" },
},
-- Modern matchit implementation
{
"andymass/vim-matchup",
init = function()
vim.cmd([[
" Improve performance
let g:matchup_matchparen_deferred = 1
let g:matchup_matchparen_timeout = 100
let g:matchup_matchparen_insert_timeout = 30
" Enhanced matching with matchup plugin
let g:matchup_override_vimtex = 1
" Whether to enable matching inside comment or string
let g:matchup_delim_noskips = 0
" Show offscreen match pair in popup window
let g:matchup_matchparen_offscreen = {'method': 'popup'}
]])
end,
event = "BufRead",
},
{ "tpope/vim-scriptease", cmd = { "Scriptnames", "Messages", "Verbose" } },
-- Asynchronous command execution
{
"skywind3000/asyncrun.vim",
init = function()
vim.cmd([[
" Automatically open quickfix window of 6 line tall after asyncrun starts
let g:asyncrun_open = 6
if g:is_win
" Command output encoding for Windows
let g:asyncrun_encs = 'gbk'
endif
]])
end,
cmd = { "AsyncRun" },
},
{ "cespare/vim-toml", ft = { "toml" }, branch = "main" },
-- Edit text area in browser using nvim
{
"glacambre/firenvim",
init = function()
vim.cmd([[
""""""""""""""""""""""""""""""firenvim settings""""""""""""""""""""""""""""""
if exists('g:started_by_firenvim') && g:started_by_firenvim
if g:is_mac
set guifont=Iosevka\ Nerd\ Font:h18
else
set guifont=Consolas
endif
" general config for firenvim
let g:firenvim_config = {
\ 'globalSettings': {
\ 'alt': 'all',
\ },
\ 'localSettings': {
\ '.*': {
\ 'cmdline': 'neovim',
\ 'priority': 0,
\ 'selector': 'textarea',
\ 'takeover': 'never',
\ },
\ }
\ }
function s:setup_firenvim() abort
set signcolumn=no
set noruler
set noshowcmd
set laststatus=0
set showtabline=0
endfunction
augroup firenvim
autocmd!
autocmd BufEnter * call s:setup_firenvim()
autocmd BufEnter sqlzoo*.txt set filetype=sql
autocmd BufEnter github.com_*.txt set filetype=markdown
autocmd BufEnter stackoverflow.com_*.txt set filetype=markdown
augroup END
endif
]])
end,
enabled = function()
return vim.g.is_win or vim.g.is_mac
end,
-- it seems that we can only call the firenvim function directly.
-- Using vim.fn or vim.cmd to call this function will fail.
build = function()
local firenvim_path = vim.fs.joinpath(plugin_dir, "firenvim")
vim.opt.runtimepath:append(firenvim_path)
vim.cmd("runtime! firenvim.vim")
-- macOS will reset the PATH when firenvim starts a nvim process, causing the PATH variable to change unexpectedly.
-- Here we are trying to get the correct PATH and use it for firenvim.
-- See also https://github.com/glacambre/firenvim/blob/master/TROUBLESHOOTING.md#make-sure-firenvims-path-is-the-same-as-neovims
local path_env = vim.env.PATH
local prologue = string.format('export PATH="%s"', path_env)
-- local prologue = "echo"
local cmd_str = string.format(":call firenvim#install(0, '%s')", prologue)
vim.cmd(cmd_str)
end,
},
-- Session management plugin
{ "tpope/vim-obsession", cmd = "Obsession" },
{
"ojroques/vim-oscyank",
enabled = function()
return vim.g.is_linux
end,
cmd = { "OSCYank", "OSCYankReg" },
},
-- showing keybindings
{
"folke/which-key.nvim",
event = "VeryLazy",
config = function()
require("config.which-key")
end,
},
{
"folke/snacks.nvim",
priority = 1000,
lazy = false,
opts = {},
config = function()
require("config.snacks")
end,
},
-- show and trim trailing whitespaces
{ "nvim-zh/whitespace.nvim", event = "VeryLazy" },
-- file explorer
{
"nvim-tree/nvim-tree.lua",
keys = { "<space>s" },
config = function()
require("config.nvim-tree")
end,
},
{
"j-hui/fidget.nvim",
event = "BufRead",
config = function()
require("config.fidget-nvim")
end,
},
{
"folke/lazydev.nvim",
ft = "lua", -- only load on lua files
opts = {
library = {
-- See the configuration section for more details
-- Load luvit types when the `vim.uv` word is found
{ path = "${3rd}/luv/library", words = { "vim%.uv" } },
{ path = "nvim-lspconfig", words = { "lspconfig" } },
},
},
},
{
"smjonas/live-command.nvim",
-- live-command supports semantic versioning via Git tags
-- tag = "2.*",
event = "VeryLazy",
config = function()
require("config.live-command")
end,
},
{
-- show hint for code actions, the user can also implement code actions themselves,
-- see discussion here: https://github.com/neovim/neovim/issues/14869
"kosayoda/nvim-lightbulb",
config = function()
require("config.lightbulb")
end,
event = "LspAttach",
},
{
"Bekaboo/dropbar.nvim",
event = "VeryLazy",
},
{
"catgoose/nvim-colorizer.lua",
event = "BufReadPre",
opts = { -- set to setup table
},
},
{
"stevearc/quicker.nvim",
event = "FileType qf",
---@module "quicker"
---@type quicker.SetupOptions
opts = {
max_filename_width = function()
return math.floor(math.min(40, vim.o.columns / 2))
end,
},
},
{
"nickjvandyke/opencode.nvim",
config = function()
---@module "opencode"
---@type opencode.Opts
vim.g.opencode_opts = {
-- Your configuration, if any — see `lua/opencode/config.lua`, or "goto definition" on the type or field.
}
-- Required for `opts.events.reload`.
vim.o.autoread = true
end,
},
{
"RRethy/vim-illuminate",
event = "VeryLazy",
config = function()
require("illuminate").configure {
filetypes_denylist = {},
filetypes_allowlist = {
"lua",
"python",
"sh",
"yaml",
"json",
"toml",
},
min_count_to_highlight = 2,
}
end,
},
{
"mfussenegger/nvim-lint",
config = function()
require("config.nvim-lint")
end,
},
}
require("lazy").setup {
spec = plugin_specs,
ui = {
border = "rounded",
title = "Plugin Manager",
title_pos = "center",
},
rocks = {
enabled = false,
hererocks = false,
},
}
-- Use short names for common plugin manager commands to simplify typing.
-- To use these shortcuts: first activate command line with `:`, then input the
-- short alias, e.g., `pi`, then press <space>, the alias will be expanded to
-- the full command automatically.
vim.fn["utils#Cabbrev"]("pi", "Lazy install")
vim.fn["utils#Cabbrev"]("pud", "Lazy update")
vim.fn["utils#Cabbrev"]("pc", "Lazy clean")
vim.fn["utils#Cabbrev"]("ps", "Lazy sync")