Files
dotfiles/config/nvim/lua/plugins/ide.lua
T

1283 lines
60 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
return {
{
"folke/snacks.nvim",
priority = 1000,
lazy = false,
---@type snacks.Config
opts = {
animate = {
enabled = false,
duration = { step = 1, total = 1 },
easing = "linear",
},
bigfile = { enabled = true },
dashboard = { enabled = false },
explorer = { enabled = false },
image = {
enabled = true,
inline = false,
scale = 3, -- nil | 1 (default) | 2 | 3 | ...
doc = {
inline = true,
enabled = true,
max_width = nil,
max_height = nil,
conceal = true,
},
math = {
enabled = true,
}
},
terminal = {
bo = {
filetype = "snacks_terminal",
},
win = { style = "terminal" },
wo = {},
keys = {
q = "hide",
gf = function(self)
local f = vim.fn.findfile(vim.fn.expand("<cfile>"), "**")
if f == "" then
Snacks.notify.warn("No file under cursor")
else
self:hide()
vim.schedule(function()
vim.cmd("e " .. f)
end)
end
end,
term_normal = {
"<esc><esc>",
function(self)
self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer()
if self.esc_timer:is_active() then
self.esc_timer:stop()
vim.cmd("stopinsert")
else
self.esc_timer:start(250, 0, function() end)
return "<esc>"
end
end,
mode = "t",
expr = true,
desc = "Double escape to normal mode",
},
},
},
indent = { enabled = false },
notifier = {
enabled = true,
timeout = 1000,
},
picker = {
enabled = true,
layout = { preset = "ivy", layout = { position = "bottom" } },
frecency = true,
history_bonus = true,
projects = {
dev = { "~/Projects", },
},
win = {
input = {
keys = {
['<c-e>'] = { 'layout_right', mode = { 'i', 'n' } },
},
},
},
sources = {
files = {
-- add a custom action
actions = {
create_if_missing = function(picker, item)
-- When typing in the input, item may be nil.
-- We'll use the input text as the intended file path.
local input = picker.input and picker.input:get() or ""
if input == "" then return end
-- Make it relative to picker cwd if it’s not absolute
local cwd = picker.opts.cwd or vim.loop.cwd()
local path = input
if not path:match("^/") and not path:match("^%a:[/\\]") then
path = cwd .. "/" .. path
end
-- Normalize path (optional)
path = vim.fn.fnamemodify(path, ":p")
-- If file exists, just open it
if vim.loop.fs_stat(path) then
picker:close()
vim.cmd.edit(path)
return
end
-- Ensure parent dirs exist (optional but nice)
vim.fn.mkdir(vim.fn.fnamemodify(path, ":h"), "p")
-- Open a new buffer at that path (creates buffer even if file missing)
picker:close()
vim.cmd.edit(path)
-- At this point buffer is new + unnamed-on-disk until you :w
end,
},
-- bind the action to a key in the picker UI
win = {
input = {
keys = {
["<M-n>"] = { "create_if_missing", mode = { "i", "n" }, desc = "Create file from input" },
},
},
list = {
keys = {
["<M-n>"] = { "create_if_missing", mode = { "n" }, desc = "Create file from input" },
},
},
},
},
},
},
scope = { enabled = false },
scratch = {
ft = "markdown",
},
statuscolumn = { enabled = true },
styles = {
notification = {
-- wo = { wrap = true } -- Wrap notifications
}
}
},
keys = {
-- Org Search
{ "<leader>o/", function() Snacks.picker.grep({dirs = { os.getenv("HOME") .. "/Documents/notes" }}) end, desc = "Search Org Files" },
-- { "<leader>o/", function() Snacks.picker.files({ cwd = os.getenv("HOME") .. "/Documents/notes" }) end, desc = "Find Document" },
-- Top Pickers & Explorer
{ "<leader><Space>", function() Snacks.picker.smart() end, desc = "Smart Find Files" },
{ "<leader>j", function() Snacks.picker.files({args = { "--no-require-git" }}) end, desc = "Find Files" },
{ "<leader>,", function() Snacks.picker.buffers() end, desc = "Buffers" },
{ "<leader>/", function() Snacks.picker.grep() end, desc = "Grep" },
{ "<leader>:", function() Snacks.picker.command_history() end, desc = "Command History" },
{ "<leader>n", function() Snacks.picker.notifications() end, desc = "Notification History" },
{ "<leader>i", function() Snacks.picker.lsp_symbols() end, desc = "Symbols" },
{ "<leader>I", function() Snacks.picker.lsp_workspace_symbols() end, desc = "LSP Workspace Symbols" },
-- { "<leader>e", function() Snacks.explorer() end, desc = "File Explorer" },
-- find
{ "<leader>fb", function() Snacks.picker.buffers() end, desc = "Buffers" },
{ "<leader>fc", function() Snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, desc = "Find Config File" },
{ "<leader>ff", function() Snacks.picker.files() end, desc = "Find Files" },
{ "<leader>fg", function() Snacks.picker.git_files() end, desc = "Find Git Files" },
{ "<leader>fp", function() Snacks.picker.projects() end, desc = "Projects" },
{ "<leader>fr", function() Snacks.picker.recent() end, desc = "Recent" },
-- git
{ "<leader>gb", function() Snacks.picker.git_branches() end, desc = "Git Branches" },
{ "<leader>gl", function() Snacks.picker.git_log() end, desc = "Git Log" },
{ "<leader>gL", function() Snacks.picker.git_log_line() end, desc = "Git Log Line" },
{ "<leader>gs", function() Snacks.picker.git_status() end, desc = "Git Status" },
{ "<leader>gS", function() Snacks.picker.git_stash() end, desc = "Git Stash" },
{ "<leader>gd", function() Snacks.picker.git_diff() end, desc = "Git Diff (Hunks)" },
{ "<leader>gf", function() Snacks.picker.git_log_file() end, desc = "Git Log File" },
-- Grep
{ "<leader>sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" },
{ "<leader>sB", function() Snacks.picker.grep_buffers() end, desc = "Grep Open Buffers" },
{ "<leader>sg", function() Snacks.picker.grep() end, desc = "Grep" },
{ "<leader>sw", function() Snacks.picker.grep_word() end, desc = "Visual selection or word", mode = { "n", "x" } },
-- search
{ '<leader>s"', function() Snacks.picker.registers() end, desc = "Registers" },
{ '<leader>s/', function() Snacks.picker.search_history() end, desc = "Search History" },
{ "<leader>sa", function() Snacks.picker.autocmds() end, desc = "Autocmds" },
{ "<leader>sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" },
{ "<leader>sc", function() Snacks.picker.command_history() end, desc = "Command History" },
{ "<leader>sC", function() Snacks.picker.commands() end, desc = "Commands" },
{ "<leader>sd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" },
{ "<leader>sD", function() Snacks.picker.diagnostics_buffer() end, desc = "Buffer Diagnostics" },
{ "<leader>sh", function() Snacks.picker.help() end, desc = "Help Pages" },
{ "<leader>sH", function() Snacks.picker.highlights() end, desc = "Highlights" },
{ "<leader>si", function() Snacks.picker.icons() end, desc = "Icons" },
{ "<leader>sj", function() Snacks.picker.jumps() end, desc = "Jumps" },
{ "<leader>sk", function() Snacks.picker.keymaps() end, desc = "Keymaps" },
{ "<leader>sl", function() Snacks.picker.loclist() end, desc = "Location List" },
{ "<leader>sm", function() Snacks.picker.marks() end, desc = "Marks" },
{ "<leader>sM", function() Snacks.picker.man() end, desc = "Man Pages" },
{ "<leader>sp", function() Snacks.picker.lazy() end, desc = "Search for Plugin Spec" },
{ "<leader>sq", function() Snacks.picker.qflist() end, desc = "Quickfix List" },
{ "<leader>sR", function() Snacks.picker.resume() end, desc = "Resume" },
{ "<leader>su", function() Snacks.picker.undo() end, desc = "Undo History" },
{ "<leader>sz", function() Snacks.picker.zoxide() end, desc = "Zoxide" },
{ "<leader>uC", function() Snacks.picker.colorschemes() end, desc = "Colorschemes" },
-- LSP
{ "gd", function() Snacks.picker.lsp_definitions() end, desc = "Goto Definition" },
{ "gD", function() Snacks.picker.lsp_declarations() end, desc = "Goto Declaration" },
{ "grr", function() Snacks.picker.lsp_references() end, nowait = true, desc = "References" },
{ "gri", function() Snacks.picker.lsp_implementations() end, desc = "Goto Implementation" },
{ "gy", function() Snacks.picker.lsp_type_definitions() end, desc = "Goto T[y]pe Definition" },
{ "<leader>ss", function() Snacks.picker.lsp_symbols() end, desc = "LSP Symbols" },
{ "<leader>sS", function() Snacks.picker.lsp_workspace_symbols() end, desc = "LSP Workspace Symbols" },
-- Other
{ "<leader>Z", function() Snacks.zen() end, desc = "Toggle Zen Mode" },
{ "<leader>z", function() Snacks.zen.zoom() end, desc = "Toggle Zoom" },
{ "<leader>.", function() Snacks.scratch() end, desc = "Toggle Scratch Buffer" },
{ "<leader>S", function() Snacks.scratch.select() end, desc = "Select Scratch Buffer" },
-- { "<leader>n", function() Snacks.notifier.show_history() end, desc = "Notification History" },
{ "<leader>bd", function() Snacks.bufdelete() end, desc = "Delete Buffer" },
{ "<leader>bR", function() Snacks.rename.rename_file() end, desc = "Rename File" },
{ "<leader>gB", function() Snacks.gitbrowse() end, desc = "Git Browse", mode = { "n", "v" } },
{ "<leader>gg", function() Snacks.lazygit() end, desc = "Lazygit" },
{ "<leader>un", function() Snacks.notifier.hide() end, desc = "Dismiss All Notifications" },
{ "<c-_>", function() Snacks.terminal.toggle() end, desc = "Toggle Terminal", mode = { "n", "t" } },
-- { "<Esc>", "<C-\\><C-n>", desc = "Exit Terminal Mode", mode = { "t" } },
{ "]]", function() Snacks.words.jump(vim.v.count1) end, desc = "Next Reference", mode = { "n", "t" } },
{ "[[", function() Snacks.words.jump(-vim.v.count1) end, desc = "Prev Reference", mode = { "n", "t" } },
{
"<leader>xN",
desc = "Neovim News",
function()
Snacks.win({
file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1],
width = 0.6,
height = 0.6,
wo = {
spell = false,
wrap = false,
signcolumn = "yes",
statuscolumn = " ",
conceallevel = 3,
},
})
end,
}
},
init = function()
vim.api.nvim_create_autocmd("User", {
pattern = "VeryLazy",
callback = function()
-- Setup some globals for debugging (lazy-loaded)
_G.dd = function(...)
Snacks.debug.inspect(...)
end
_G.bt = function()
Snacks.debug.backtrace()
end
vim.print = _G.dd -- Override print to use snacks for `:=` command
-- Create some toggle mappings
Snacks.toggle.option("spell", { name = "Spelling" }):map("<leader>us")
Snacks.toggle.option("wrap", { name = "Wrap" }):map("<leader>uw")
Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("<leader>uL")
Snacks.toggle.diagnostics():map("<leader>ud")
Snacks.toggle.line_number():map("<leader>ul")
Snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }):map("<leader>uc")
Snacks.toggle.treesitter():map("<leader>uT")
Snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map("<leader>ub")
Snacks.toggle.inlay_hints():map("<leader>uh")
Snacks.toggle.indent():map("<leader>ug")
Snacks.toggle.dim():map("<leader>uD")
end,
})
end,
},
{
"folke/todo-comments.nvim",
lazy = true,
keys = {
{ "<leader>st", function() Snacks.picker.todo_comments() end, desc = "Todo" },
{ "<leader>sT", function() Snacks.picker.todo_comments({ keywords = { "TODO", "FIX", "FIXME", "NOTE" } }) end, desc = "Todo/Fix/Fixme/Note" },
},
opts = {},
},
{
'L3MON4D3/LuaSnip',
dependencies = {
'rafamadriz/friendly-snippets',
},
version = "v2.*",
build = "make install_jsregexp",
config = function()
require('luasnip.loaders.from_vscode').lazy_load()
require('luasnip.loaders.from_vscode').lazy_load({ paths = "./json_snippets" })
local luasnip = require("luasnip")
luasnip.add_snippets("zig", require("snippets.zig"))
end,
},
{
'saghen/blink.cmp',
lazy = false, -- lazy loading handled internally
-- optional: provides snippets for the snippet source
dependencies = {
'L3MON4D3/LuaSnip',
'moyiz/blink-emoji.nvim',
'MeanderingProgrammer/render-markdown.nvim',
'fang2hou/blink-copilot',
--'giuxtaposition/blink-cmp-copilot',
},
version = '1.*',
config = function()
-- NOTE: Specify the trigger character(s) used for luasnip
-- local trigger_text = ";"
require('blink.cmp').setup({
enabled = function()
local filetype = vim.bo[0].filetype
if filetype == "TelescopePrompt" or filetype == "minifiles" or filetype == "snacks_picker_input" then
return false
end
return true
end,
snippets = { preset = 'luasnip' },
completion = {
-- keyword = {
-- -- 'prefix' will fuzzy match on the text before the cursor
-- -- 'full' will fuzzy match on the text before *and* after the cursor
-- -- example: 'foo_|_bar' will match 'foo_' for 'prefix' and 'foo__bar' for 'full'
-- range = "full",
-- },
menu = {
draw = {
treesitter = { 'lsp' }
}
-- border = "single",
},
list = {
selection = {
preselect = false,
auto_insert = false,
}
},
documentation = {
auto_show = true,
auto_show_delay_ms = 500,
-- window = {
-- border = "single",
-- },
},
ghost_text = { enabled = false },
},
cmdline = {
enabled = true,
},
signature = { enabled = true },
sources = {
per_filetype = {
org = {'orgmode'}
},
default = { 'orgmode', 'lsp', 'copilot', 'snippets', 'path', 'omni', 'buffer', 'codecompanion', 'markdown' },
providers = {
codecompanion = {
name = "CodeCompanion" ,
module = "codecompanion.providers.completion.blink",
enabled = true,
},
orgmode = {
name = 'Orgmode',
module = 'orgmode.org.autocompletion.blink',
fallbacks = { 'buffer' },
},
copilot = {
name = 'copilot',
module = 'blink-copilot',
score_offset = 100,
async = true,
},
markdown = {
name = 'RenderMarkdown',
module = 'render-markdown.integ.blink',
score_offset = 80,
},
lsp = {
name = 'lsp', -- IMPORTANT: use the same name as you would for nvim-cmp
enabled = true,
module = 'blink.cmp.sources.lsp',
-- fallbacks = { 'snippets', 'buffer', 'path' },
score_offset = 100,
},
path = {
name = 'path', -- IMPORTANT: use the same name as you would for nvim-cmp
module = 'blink.cmp.sources.path',
score_offset = 50,
fallbacks = { 'snippets', 'buffer' },
opts = {
trailing_slash = false,
label_trailing_slash = true,
get_cwd = function(context)
return vim.fn.expand(("#%d:p:h"):format(context.bufnr))
end,
show_hidden_files_by_default = true,
},
},
buffer = {
name = "Buffer",
enabled = true,
max_items = 3,
module = "blink.cmp.sources.buffer",
min_keyword_length = 4,
score_offset = 15, -- the higher the number, the higher the priority
},
snippets = {
name = "snippets",
enabled = true,
max_items = 15,
min_keyword_length = 2,
module = "blink.cmp.sources.snippets",
score_offset = 90, -- the higher the number, the higher the priority
},
emoji = {
module = "blink-emoji",
name = "Emoji",
score_offset = 0, -- the higher the number, the higher the priority
opts = { insert = true }, -- Insert emoji (default) or complete its name
},
},
},
appearance = {
-- Blink does not expose its default kind icons so you must copy them all (or set your custom ones) and add Copilot
kind_icons = {
Copilot = "",
Text = '󰉿',
Method = '󰊕',
Function = '󰊕',
Constructor = '󰒓',
Field = '󰜢',
Variable = '󰆦',
Property = '󰖷',
Class = '󱡠',
Interface = '󱡠',
Struct = '󱡠',
Module = '󰅩',
Unit = '󰪚',
Value = '󰦨',
Enum = '󰦨',
EnumMember = '󰦨',
Keyword = '󰻾',
Constant = '󰏿',
Snippet = '󱄽',
Color = '󰏘',
File = '󰈔',
Reference = '󰬲',
Folder = '󰉋',
Event = '󱐋',
Operator = '󰪚',
TypeParameter = '󰬛',
},
},
})
end
},
{
'stevearc/conform.nvim',
event = { 'BufWritePre' },
cmd = { 'ConformInfo' },
keys = {
{
'<leader>bf',
function()
require('conform').format { async = true, lsp_format = 'fallback' }
end,
mode = { 'n', 'v' },
desc = 'Format buffer',
},
},
opts = {
notify_on_error = false,
-- format_on_save = function(bufnr)
-- -- Disable "format_on_save lsp_fallback" for languages that don't
-- -- have a well standardized coding style. You can add additional
-- -- languages here or re-enable it for the disabled ones.
-- local disable_filetypes = { c = true, cpp = true }
-- local lsp_format_opt
-- if disable_filetypes[vim.bo[bufnr].filetype] then
-- lsp_format_opt = 'never'
-- else
-- lsp_format_opt = 'fallback'
-- end
-- return {
-- timeout_ms = 500,
-- lsp_format = lsp_format_opt,
-- }
-- end,
formatters = {
shfmt = {
prepend_args = { "-i", "2", "-ci" },
},
dprint = {
condition = function(ctx)
return vim.fs.find({ "dprint.json" }, { path = ctx.filename, upward = true })[1]
end,
},
},
formatters_by_ft = {
c = { "clang_format" },
cpp = { "clang_format" },
lua = { 'stylua' },
go = { "goimports", "gofmt" },
rust = { "dprint", "rustfmt", lsp_format = "fallback" },
python = { "isort", "black", stop_after_first = true },
javascript = { "dprint", "prettier", stop_after_first = true },
markdown = { "dprint", "prettier", stop_after_first = true },
javascriptreact = { "dprint", "prettier", stop_after_first = true },
typescript = { "dprint", "prettier", stop_after_first = true },
typescriptreact = { "dprint", "prettier", stop_after_first = true },
svelte = { "dprint", "prettier", stop_after_first = true },
html = { "dprint", "prettier", stop_after_first = true },
},
},
},
{
'lewis6991/gitsigns.nvim',
event = "VimEnter",
keys = {
{ '<leader>uG', "Gitsigns toggle_signs", mode = { 'n' }, desc = 'Gitsigns toggle', },
},
opts = {
auto_attach = true,
signs_staged_enable = true,
signcolumn = true,
current_line_blame_opts = {
delay = 50
},
on_attach = function(bufnr)
local gitsigns = require('gitsigns')
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
-- Actions
-- visual mode
map('v', '<leader>vs', function()
gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'stage git hunk' })
map('v', '<leader>vr', function()
gitsigns.reset_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'reset git hunk' })
-- normal mode
map('n', '[v', function() gitsigns.nav_hunk 'prev' end, { desc = 'git previous hunk' })
map('n', ']v', function() gitsigns.nav_hunk 'next' end, { desc = 'git next hunk' })
map('n', '<leader>vs', gitsigns.stage_hunk, { desc = 'git stage hunk' })
map('n', '<leader>vr', gitsigns.reset_hunk, { desc = 'git reset hunk' })
map('n', '<leader>vS', gitsigns.stage_buffer, { desc = 'git stage buffer' })
map('n', '<leader>vu', gitsigns.undo_stage_hunk, { desc = 'git undo stage hunk' })
map('n', '<leader>vR', gitsigns.reset_buffer, { desc = 'git reset buffer' })
map('n', '<leader>vP', gitsigns.preview_hunk, { desc = 'git preview hunk' })
map('n', '<leader>vb', gitsigns.blame_line, { desc = 'git blame line' })
map('n', '<leader>vP', gitsigns.diffthis, { desc = 'git diff against index' })
map('n', '<leader>vD', function()
gitsigns.diffthis '@'
end, { desc = 'git [D]iff against last commit' })
-- Toggles
map('n', '<leader>uvb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' })
map('n', '<leader>uvd', gitsigns.toggle_deleted, { desc = '[T]oggle git show [D]eleted' })
end,
}
},
{
"sindrets/diffview.nvim",
},
{
"NicolasGB/jj.nvim",
version = "*", -- Use latest stable release
-- Or from the main branch (uncomment the branch line and comment the version line)
-- branch = "main",
keys = function()
local cmd = require("jj.cmd")
local annotate = require("jj.annotate")
vim.keymap.set("n", "<leader>va", annotate.file, { desc = "JJ annotate file" })
vim.keymap.set("n", "<leader>vA", annotate.line, { desc = "JJ annotate line" })
vim.keymap.set("n", "<leader>vbc", cmd.bookmark_create, { desc = "JJ bookmark create" })
vim.keymap.set("n", "<leader>vbd", cmd.bookmark_delete, { desc = "JJ bookmark delete" })
vim.keymap.set("n", "<leader>vbm", cmd.bookmark_move, { desc = "JJ bookmark move" })
vim.keymap.set("n", "<leader>vd", cmd.describe, { desc = "JJ describe" })
vim.keymap.set("n", "<leader>vl", cmd.log, { desc = "JJ log" })
vim.keymap.set("n", "<leader>ve", cmd.edit, { desc = "JJ edit" })
vim.keymap.set("n", "<leader>vn", cmd.new, { desc = "JJ new" })
vim.keymap.set("n", "<leader>vs", cmd.status, { desc = "JJ status" })
vim.keymap.set("n", "<leader>vS", cmd.squash, { desc = "JJ squash" })
vim.keymap.set("n", "<leader>vju", cmd.undo, { desc = "JJ undo" })
vim.keymap.set("n", "<leader>vjr", cmd.redo, { desc = "JJ redo" })
vim.keymap.set("n", "<leader>vr", cmd.rebase, { desc = "JJ rebase" })
vim.keymap.set("n", "<leader>vf", cmd.fetch, { desc = "JJ fetch" })
vim.keymap.set("n", "<leader>vx", cmd.abandon, { desc = "JJ abandon" })
vim.keymap.set("n", "<leader>vp", cmd.push, { desc = "JJ push" })
vim.keymap.set("n", "<leader>vpr", cmd.open_pr, { desc = "JJ open PR from bookmark in current revision or parent" })
vim.keymap.set("n", "<leader>vpl", function()
cmd.open_pr { list_bookmarks = true }
end, { desc = "JJ open PR listing available bookmarks" })
-- Diff commands
local diff = require("jj.diff")
vim.keymap.set("n", "<leader>vjd", function() diff.open_vdiff() end, { desc = "JJ diff current buffer" })
vim.keymap.set("n", "<leader>vjD", function() diff.open_hsplit() end, { desc = "JJ hdiff current buffer" })
-- Pickers
local picker = require("jj.picker")
vim.keymap.set("n", "<leader>vjs", function() picker.status() end, { desc = "JJ Picker status" })
vim.keymap.set("n", "<leader>vjh", function() picker.file_history() end, { desc = "JJ Picker history" })
-- Some functions like `log` can take parameters
vim.keymap.set("n", "<leader>vL", function()
cmd.log {
revisions = "all()", -- equivalent to jj log -r ::
}
end, { desc = "JJ log all" })
-- This is an alias i use for moving bookmarks its so good
vim.keymap.set("n", "<leader>vt", function()
cmd.j "tug"
cmd.log {}
end, { desc = "JJ tug" })
end,
config = function()
require("jj").setup({
diff = {
backend = "native",
},
cmd = {
describe = {
editor = {
type = "buffer",
}
}
},
describe = {
editor = {
type = "buffer",
}
}
})
end,
},
{
"julienvincent/hunk.nvim",
cmd = { "DiffEditor" },
config = function()
require("hunk").setup()
end,
},
{
-- "PrayagS/jj-diffconflicts",
-- branch = 'fix-for-jj-v0_37_0',
"rafikdraoui/jj-diffconflicts"
},
{
'Glhou/jjsigns.nvim',
branch = 'fix/skip-extra-lines',
config = function()
require('jjsigns').setup({
enabled = true,
attach = {
auto = false,
}
})
end,
},
{ 'williamboman/mason.nvim', lazy = true, opts = {} },
{ 'williamboman/mason-lspconfig.nvim', lazy = true },
{ 'WhoIsSethDaniel/mason-tool-installer.nvim', lazy = true },
{
'neovim/nvim-lspconfig',
dependencies = {
{ 'SmiteshP/nvim-navic', lazy = true },
},
keys = function()
vim.keymap.set("i", "<C-.>", function()
if not vim.lsp.inline_completion.get() then
return "<C-.>"
end
end, { expr = true, desc = "Accept the current inline completion" })
end,
config = function()
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }),
callback = function(event)
local function client_supports_method(client, method, bufnr)
if vim.fn.has 'nvim-0.11' == 1 then
return client:supports_method(method, bufnr)
else
return client.supports_method(method, { bufnr = bufnr })
end
end
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_completion, event.buf) then
vim.lsp.completion.enable(true, client.id, event.buf, { autotrigger = true })
end
end,
})
-- Diagnostic Config
-- See :help vim.diagnostic.Opts
vim.diagnostic.config({
severity_sort = true,
float = { border = 'rounded', source = 'if_many' },
underline = { severity = vim.diagnostic.severity.ERROR },
signs = vim.g.have_nerd_font and {
text = {
[vim.diagnostic.severity.ERROR] = '󰅚 ',
[vim.diagnostic.severity.WARN] = '󰀪 ',
[vim.diagnostic.severity.INFO] = '󰋽 ',
[vim.diagnostic.severity.HINT] = '󰌶 ',
},
} or {},
virtual_text = {
source = 'if_many',
spacing = 2,
format = function(diagnostic)
local diagnostic_message = {
[vim.diagnostic.severity.ERROR] = diagnostic.message,
[vim.diagnostic.severity.WARN] = diagnostic.message,
[vim.diagnostic.severity.INFO] = diagnostic.message,
[vim.diagnostic.severity.HINT] = diagnostic.message,
}
return diagnostic_message[diagnostic.severity]
end,
},
})
local servers = {
lua_ls = {
settings = {
Lua = {
runtime = {
version = 'LuaJIT',
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
completion = {
callSnippet = "Replace",
},
diagnostics = {
disable = { 'missing-fields' },
globals = { 'vim', 'require' },
},
},
}
},
gopls = {
settings = {
gopls = {
experimentalPostfixCompletions = true,
analyses = {
unusedparams = true,
shadow = true,
},
staticcheck = true,
hints = {
enabled = true,
rangeVariableTypes = true,
prameterNames = true,
functionTypeParameters = true,
constantValues = true,
compositeLiteralTypes = true,
compositeLiteralFields = true,
assignVariableTypes = true,
},
},
},
},
harper_ls = {
settings = {
["harper-ls"] = {
linters = {
SentenceCapitalization = true,
SpellCheck = true
},
dialect = "Canadian"
}
}
},
-- csharp_ls = {},
zls= {},
clangd= {
settings = {
["clang"] = {
cmd = { "clangd", "--background-index", "--compile-commands-dir=" .. vim.loop.cwd() .. "/build" },
}
}
},
rust_analyzer={},
ts_ls= {},
html= {},
eslint= {},
jsonls= {},
jdtls= {},
-- copilot = {
-- cmd = { "copilot-language-server", "--stdio" },
-- init_options = {
-- name = "Neovim",
-- version = tostring(vim.version()),
-- },
-- editorPluginInfo = {
-- name = "Neovim",
-- version = tostring(vim.version()),
-- },
-- },
}
local ensure_installed = vim.tbl_keys(servers or {})
require('mason-tool-installer').setup ({ ensure_installed = ensure_installed })
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = vim.tbl_deep_extend('force', capabilities, require('blink.cmp').get_lsp_capabilities({}, false))
capabilities = vim.tbl_deep_extend('force', capabilities, {
general = {
-- dynamicRegistration = false,
positionEncodings = { "utf-16" },
},
textDocument = {
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true
}
}
})
for server, cfg in pairs(servers) do
cfg.capabilities = vim.tbl_deep_extend('force', {}, capabilities, cfg.capabilities or {})
vim.lsp.config(server, cfg)
vim.lsp.enable(server)
end
-- vim.lsp.inline_completion.enable();
vim.lsp.enable("rust-analyzer", false)
end
},
{
"rcarriga/nvim-dap-ui",
dependencies = {
"mfussenegger/nvim-dap",
"nvim-neotest/nvim-nio"
},
config = function()
local dapui = require("dapui")
local dap = require("dap")
dapui.setup()
vim.fn.sign_define("DapBreakpoint", { text = "🐞" })
dap.listeners.before.attach.dapui_config = function()
dapui.open()
end
dap.listeners.before.launch.dapui_config = function()
dapui.open()
end
dap.listeners.before.event_terminated.dapui_config = function()
dapui.close()
end
dap.listeners.before.event_exited.dapui_config = function()
dapui.close()
end
end
},
{
"jay-babu/mason-nvim-dap.nvim",
config = function()
require ('mason-nvim-dap').setup({
handlers = {
function(config)
-- all sources with no handler get passed here
-- Keep original functionality
require('mason-nvim-dap').default_setup(config)
end,
},
})
end,
},
{
"Saecki/crates.nvim",
lazy = true,
keys = function()
local crates = require("crates")
local opts = { silent = true }
vim.keymap.set("n", "<leader>cct", crates.toggle, { desc = 'toggle' })
vim.keymap.set("n", "<leader>ccr", crates.reload, { desc = 'reload' })
vim.keymap.set("n", "<leader>ccv", crates.show_versions_popup, { desc = 'show versions' })
vim.keymap.set("n", "<leader>ccf", crates.show_features_popup, { desc = 'show features' })
vim.keymap.set("n", "<leader>ccd", crates.show_dependencies_popup, { desc = 'show dependencies' })
vim.keymap.set("n", "<leader>ccu", crates.update_crate, { desc = 'update' })
vim.keymap.set("v", "<leader>ccu", crates.update_crates, { desc = 'update' })
vim.keymap.set("n", "<leader>cca", crates.update_all_crates, { desc = 'update all' })
vim.keymap.set("n", "<leader>ccU", crates.upgrade_crate, { desc = 'upgrade' })
vim.keymap.set("v", "<leader>ccU", crates.upgrade_crates, { desc = 'upgrade' })
vim.keymap.set("n", "<leader>ccA", crates.upgrade_all_crates, { desc = 'upgrade all' })
vim.keymap.set("n", "<leader>ccx", crates.expand_plain_crate_to_inline_table, { desc = 'expand' })
vim.keymap.set("n", "<leader>ccX", crates.extract_crate_into_table, { desc = 'extract' })
vim.keymap.set("n", "<leader>ccH", crates.open_homepage, { desc = 'open homepage' })
vim.keymap.set("n", "<leader>ccR", crates.open_repository, { desc = 'open repository' })
vim.keymap.set("n", "<leader>ccD", crates.open_documentation, { desc = 'open documents' })
vim.keymap.set("n", "<leader>ccC", crates.open_crates_io, { desc = 'open crates.io' })
vim.keymap.set("n", "<leader>ccL", crates.open_lib_rs, { desc = 'open lib.rs' })
end,
opts = {
completion = {
crates = {
enabled = true,
},
},
lsp = {
enabled = true,
actions = true,
completion = true,
hover = true,
},
},
},
{
'mrcjkb/rustaceanvim',
-- version = '^6', -- Recommended
lazy = true,
ft = {'rust'},
opts = {
server = {
default_settings = {
cargo = {
allFeatures = false,
loadOutDirsFromCheck = true,
buildScripts = { enable = true },
},
},
on_attach = function(_, bufnr)
vim.keymap.set("n", "<leader>lr", function()
vim.cmd.RustLsp("codeAction")
end, { desc = "Code Action", buffer = bufnr })
vim.keymap.set("n", "<leader>ld", function()
vim.cmd.RustLsp("debuggables")
end, { desc = "Rust Debuggables", buffer = bufnr })
vim.keymap.set("n", "<leader>lD", function()
vim.cmd.RustLsp("openDocs")
end, { desc = "Open Documents", buffer = bufnr })
vim.keymap.set("n", "<leader>lc", function()
vim.cmd.RustLsp("openCargo")
end, { desc = "Open Documents", buffer = bufnr })
end,
},
},
config = function(_, opts)
vim.g.rustaceanvim = vim.tbl_deep_extend("keep", vim.g.rustaceanvim or {}, opts or {})
end,
},
{
-- Highlight, edit, and navigate code
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
dependencies = {
'nvim-treesitter/nvim-treesitter-textobjects',
-- 'p00f/nvim-ts-rainbow',
},
config = function()
require('nvim-treesitter.configs').setup({
-- Add languages to be installed here that you want installed for treesitter
ensure_installed = {
'c',
"lua",
"markdown",
"markdown_inline",
"vim",
"vimdoc",
"query",
"html",
"go",
"bash",
"zig",
"typescript",
"javascript",
"dockerfile",
"xml",
"regex",
"rust"
},
ignore_install = { 'org' },
auto_install = true,
-- disable = function(lang, buf)
-- local max_filesize = 100 * 1024
-- local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buff_get_name(buf))
-- if ok and stats and stats.size > max_filesize then
-- return true
-- end
-- end,
highlight = { enable = true, },
indent = { enable = true },
})
end,
},
{
'JoosepAlviste/nvim-ts-context-commentstring',
lazy = true,
opts = {
enable_autocmd = false,
}
},
{
'nvim-treesitter/nvim-treesitter-context',
enabled = true,
opts = { mode = "cursor", max_lines = 3 },
},
{
"mbbill/undotree",
lazy = true,
keys = {
{ '<leader>uu', vim.cmd.UndotreeToggle, desc = 'Format buffer' }
},
},
{
'Civitasv/cmake-tools.nvim',
lazy = true,
config = function ()
local osys = require("cmake-tools.osys")
require("cmake-tools").setup {
cmake_command = "cmake", -- this is used to specify cmake command path
ctest_command = "ctest", -- this is used to specify ctest command path
cmake_use_preset = true,
cmake_regenerate_on_save = true, -- auto generate when save CMakeLists.txt
cmake_generate_options = { "-DCMAKE_EXPORT_COMPILE_COMMANDS=1" }, -- this will be passed when invoke `CMakeGenerate`
cmake_build_options = {}, -- this will be passed when invoke `CMakeBuild`
-- support macro expansion:
-- ${kit}
-- ${kitGenerator}
-- ${variant:xx}
cmake_build_directory = function()
if osys.iswin32 then
return "out\\${variant:buildType}"
end
return "out/${variant:buildType}"
end, -- this is used to specify generate directory for cmake, allows macro expansion, can be a string or a function returning the string, relative to cwd.
cmake_soft_link_compile_commands = true, -- this will automatically make a soft link from compile commands file to project root dir
cmake_compile_commands_from_lsp = false, -- this will automatically set compile commands file location using lsp, to use it, please set `cmake_soft_link_compile_commands` to false
cmake_kits_path = nil, -- this is used to specify global cmake kits path, see CMakeKits for detailed usage
cmake_variants_message = {
short = { show = true }, -- whether to show short message
long = { show = true, max_length = 40 }, -- whether to show long message
},
cmake_dap_configuration = { -- debug settings for cmake
name = "cpp",
type = "codelldb",
request = "launch",
stopOnEntry = false,
runInTerminal = true,
console = "integratedTerminal",
},
cmake_executor = { -- executor to use
name = "quickfix", -- name of the executor
opts = {}, -- the options the executor will get, possible values depend on the executor type. See `default_opts` for possible values.
default_opts = { -- a list of default and possible values for executors
quickfix = {
show = "always", -- "always", "only_on_error"
position = "belowright", -- "vertical", "horizontal", "leftabove", "aboveleft", "rightbelow", "belowright", "topleft", "botright", use `:h vertical` for example to see help on them
size = 10,
encoding = "utf-8", -- if encoding is not "utf-8", it will be converted to "utf-8" using `vim.fn.iconv`
auto_close_when_success = true, -- typically, you can use it with the "always" option; it will auto-close the quickfix buffer if the execution is successful.
},
toggleterm = {
direction = "float", -- 'vertical' | 'horizontal' | 'tab' | 'float'
close_on_exit = false, -- whether close the terminal when exit
auto_scroll = true, -- whether auto scroll to the bottom
singleton = true, -- single instance, autocloses the opened one, if present
},
overseer = {
new_task_opts = {
strategy = {
"toggleterm",
direction = "horizontal",
autos_croll = true,
quit_on_exit = "success"
}
}, -- options to pass into the `overseer.new_task` command
on_new_task = function(task)
require("overseer").open(
{ enter = false, direction = "right" }
)
end, -- a function that gets overseer.Task when it is created, before calling `task:start`
},
terminal = {
name = "Main Terminal",
prefix_name = "[CMakeTools]: ", -- This must be included and must be unique, otherwise the terminals will not work. Do not use a simple spacebar " ", or any generic name
split_direction = "horizontal", -- "horizontal", "vertical"
split_size = 11,
-- Window handling
single_terminal_per_instance = true, -- Single viewport, multiple windows
single_terminal_per_tab = true, -- Single viewport per tab
keep_terminal_static_location = true, -- Static location of the viewport if avialable
auto_resize = true, -- Resize the terminal if it already exists
-- Running Tasks
start_insert = false, -- If you want to enter terminal with :startinsert upon using :CMakeRun
focus = false, -- Focus on terminal when cmake task is launched.
do_not_add_newline = false, -- Do not hit enter on the command inserted when using :CMakeRun, allowing a chance to review or modify the command before hitting enter.
}, -- terminal executor uses the values in cmake_terminal
},
},
cmake_runner = { -- runner to use
name = "terminal", -- name of the runner
opts = {}, -- the options the runner will get, possible values depend on the runner type. See `default_opts` for possible values.
default_opts = { -- a list of default and possible values for runners
quickfix = {
show = "always", -- "always", "only_on_error"
position = "belowright", -- "bottom", "top"
size = 10,
encoding = "utf-8",
auto_close_when_success = true, -- typically, you can use it with the "always" option; it will auto-close the quickfix buffer if the execution is successful.
},
toggleterm = {
direction = "float", -- 'vertical' | 'horizontal' | 'tab' | 'float'
close_on_exit = false, -- whether close the terminal when exit
auto_scroll = true, -- whether auto scroll to the bottom
singleton = true, -- single instance, autocloses the opened one, if present
},
overseer = {
new_task_opts = {
strategy = {
"toggleterm",
direction = "horizontal",
autos_croll = true,
quit_on_exit = "success"
}
}, -- options to pass into the `overseer.new_task` command
on_new_task = function(task)
end, -- a function that gets overseer.Task when it is created, before calling `task:start`
},
terminal = {
name = "Main Terminal",
prefix_name = "[CMakeTools]: ", -- This must be included and must be unique, otherwise the terminals will not work. Do not use a simple spacebar " ", or any generic name
split_direction = "horizontal", -- "horizontal", "vertical"
split_size = 11,
-- Window handling
single_terminal_per_instance = true, -- Single viewport, multiple windows
single_terminal_per_tab = true, -- Single viewport per tab
keep_terminal_static_location = true, -- Static location of the viewport if avialable
auto_resize = true, -- Resize the terminal if it already exists
-- Running Tasks
start_insert = false, -- If you want to enter terminal with :startinsert upon using :CMakeRun
focus = false, -- Focus on terminal when cmake task is launched.
do_not_add_newline = false, -- Do not hit enter on the command inserted when using :CMakeRun, allowing a chance to review or modify the command before hitting enter.
},
},
},
cmake_notifications = {
runner = { enabled = true },
executor = { enabled = true },
spinner = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }, -- icons used for progress display
refresh_rate_ms = 100, -- how often to iterate icons
},
cmake_virtual_text_support = true, -- Show the target related to current file using virtual text (at right corner)
}
end,
},
{
"folke/persistence.nvim",
event = "BufReadPre",
opts = { options = { "buffers", "curdir", "tabpages", "winsize", "help", "globals", "skiprtp" } },
-- stylua: ignore
keys = {
{ "<leader>xr", function() require("persistence").load() end, desc = "Restore Session" },
{ "<leader>xs", function() require("persistence").save() end, desc = "Save Session" },
{ "<leader>xl", function() require("persistence").load({ last = true }) end, desc = "Restore Last Session" },
{ "<leader>xd", function() require("persistence").stop() end, desc = "Don't Save Current Session" },
},
},
{
"otavioschwanck/arrow.nvim",
dependencies = {
{
"nvim-tree/nvim-web-devicons"
},
-- or if using `mini.icons`
-- { "echasnovski/mini.icons" },
},
opts = {
show_icons = true,
leader_key = ';', -- Recommended to be a single key
buffer_leader_key = '<leader>;', -- Per Buffer Mappings
}
},
{
"nvim-pack/nvim-spectre",
lazy = true,
cmd = { "Spectre" },
keys = {
{ "<leader>sr", function() require("spectre").open() end, desc = "Replace in files (Spectre)" },
},
opts = {
open_cmd = "noswapfile vnew",
highlight = {
search = "SpectreSearch",
replace = "SpectreReplace",
},
mapping = {
["send_to_qf"] = {
map = "<C-q>",
cmd = "<cmd>lua require('spectre.actions').send_to_qf()<CR>",
desc = "send all items to quickfix",
},
},
}
},
{
'stevearc/overseer.nvim',
keys = {
{ "<leader>xo", "<cmd>OverseerOpen<CR>", desc = "Open Overseer" },
{ "<leader>to", "<cmd>OverseerToggle<CR>", desc = "Overseer Toggle" },
{ "<F5>", "<cmd>OverseerRun<CR>", desc = "Run Overseer" },
{ "<F6>", "<cmd>OverseerToggle<CR>", desc = "Overseer Toggle" },
},
config = function()
require("overseer").setup({
templates = { "builtin", "user" },
component_aliases = {
default = {
{ 'display_duration', detail_level = 2 },
'on_output_summarize',
'on_exit_set_status',
'on_result_diagnostics_quickfix',
'on_complete_notify',
{ "on_complete_dispose", require_view = { "SUCCESS", "FAILURE" } },
},
default_vscode = {
'default',
'on_result_diagnostics',
'on_result_diagnostics_quickfix',
'on_complete_notify',
},
}
})
-- local pm = require("overseer.template.vscode.problem_matcher")
-- pm.register_problem_matcher("$rustc", {
-- fileLocation = { "autoDetect", "${cwd}" },
-- pattern = {
-- --regexp = "^(.*?)-->\\s+(.*?):(\\d+):(\\d+)$",
-- -- vim_regexp = "\\v^(.*?)-->\\s+(.*?):(\\d+):(\\d+)$",
-- regexp = "^\\s+-->\\s*([^:]*):(\\d+):(\\d+)$",
-- vim_regexp = "\\v^\\s+-->\\s*([^:]*):(\\d+):(\\d+)$",
-- file = 1,
-- line = 2,
-- column = 3,
-- }
-- })
end,
},
}