nix-wrapper-modules port. Basic modules.nix, gotta port the lua still.

This commit is contained in:
Gabe Venberg 2026-03-08 23:01:58 +01:00
parent 0499b13274
commit 7c9d33f7bb
20 changed files with 1375 additions and 1730 deletions

37
lua/keys.lua Normal file
View file

@ -0,0 +1,37 @@
-- [[ Basic Keymaps ]]
-- Keymaps for better default experience
-- See `:help vim.keymap.set()`
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv", { desc = 'Moves Line Down' })
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv", { desc = 'Moves Line Up' })
vim.keymap.set("n", "<C-d>", "<C-d>zz", { desc = 'Scroll Down' })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = 'Scroll Up' })
vim.keymap.set("n", "n", "nzzzv", { desc = 'Next Search Result' })
vim.keymap.set("n", "N", "Nzzzv", { desc = 'Previous Search Result' })
-- Remap for dealing with word wrap
vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
-- Diagnostic keymaps
vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' })
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostics list' })
vim.keymap.set('n', '[d', function() vim.diagnostic.jump({ count = -1, float = true }) end,
{ desc = 'Go to previous diagnostic' })
vim.keymap.set('n', ']d', function() vim.diagnostic.jump({ count = 1, float = true }) end,
{ desc = 'Go to next diagnostic' })
-- moving between splits
vim.keymap.set('n', '<C-h>', '<C-w>h', { desc = 'move to right split' })
vim.keymap.set('n', '<C-j>', '<C-w>j', { desc = 'move to below split' })
vim.keymap.set('n', '<C-k>', '<C-w>k', { desc = 'move to above split' })
vim.keymap.set('n', '<C-l>', '<C-w>l', { desc = 'move to left split' })
-- You should instead use these keybindings so that they are still easy to use, but dont conflict
vim.keymap.set({ "v", "x", "n" }, '<leader>y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' })
vim.keymap.set({ "n", "v", "x" }, '<leader>Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' })
vim.keymap.set({ 'n', 'v', 'x' }, '<leader>p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' })
vim.keymap.set('i', '<C-p>', '<C-r><C-p>+',
{ noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' })
vim.keymap.set("x", "<leader>P", '"_dP',
{ noremap = true, silent = true, desc = 'Paste over selection without erasing unnamed register' })

View file

@ -1,261 +0,0 @@
local catUtils = require('nixCatsUtils')
if (catUtils.isNixCats and nixCats('lspDebugMode')) then
vim.lsp.set_log_level("debug")
end
local Snacks = require("snacks")
vim.keymap.set("n", "<leader>lI", Snacks.picker.lsp_implementations, { desc = "Goto [I]mplementation" })
vim.keymap.set("n", "<leader>lR", Snacks.picker.lsp_references, { desc = "Goto [R]eferences" })
vim.keymap.set("n", "<leader>li", Snacks.picker.diagnostics, { desc = "D[i]agnostics" })
vim.keymap.set("n", "<leader>ls", Snacks.picker.lsp_symbols, { desc = "Document [S]ymbols" })
vim.keymap.set("n", "<leader>lws", Snacks.picker.lsp_workspace_symbols, { desc = "[W]orkspace [S]ymbols" })
vim.keymap.set("n", "<leader>lD", vim.lsp.buf.declaration, { desc = "Goto [D]eclaration" })
vim.keymap.set("n", "<leader>lt", vim.lsp.buf.type_definition, { desc = "Type [D]efinition" })
vim.keymap.set({"n", "v",}, "<leader>la", vim.lsp.buf.code_action, { desc = "[C]ode Action" })
vim.keymap.set("n", "<leader>ld", vim.lsp.buf.definition, { desc = "Goto [D]efinition" })
vim.keymap.set("n", "<leader>lf", vim.lsp.buf.format, { desc = "Format buffer" })
vim.keymap.set("n", "<leader>lh", vim.lsp.buf.hover, { desc = "Hover Documentation" })
vim.keymap.set("n", "<leader>lr", vim.lsp.buf.rename, { desc = "[R]ename" })
vim.keymap.set("n", "<leader>ls", vim.lsp.buf.signature_help, { desc = "Signature Documentation" })
vim.keymap.set("n", "<leader>lwa", vim.lsp.buf.add_workspace_folder, { desc = "[W]orkspace [A]dd Folder" })
vim.keymap.set("n", "<leader>lwl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end,
{ desc = "[W]orkspace [L]ist Folders" })
vim.keymap.set("n", "<leader>lwr", vim.lsp.buf.remove_workspace_folder, { desc = "[W]orkspace [R]emove Folder" })
-- setup lsp progress notifications
local progress = vim.defaulttable()
vim.api.nvim_create_autocmd("LspProgress", {
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
local value = ev.data.params
.value --[[@as {percentage?: number, title?: string, message?: string, kind: "begin" | "report" | "end"}]]
if not client or type(value) ~= "table" then
return
end
local p = progress[client.id]
for i = 1, #p + 1 do
if i == #p + 1 or p[i].token == ev.data.params.token then
p[i] = {
token = ev.data.params.token,
msg = ("[%3d%%] %s%s"):format(
value.kind == "end" and 100 or value.percentage or 100,
value.title or "",
value.message and (" **%s**"):format(value.message) or ""
),
done = value.kind == "end",
}
break
end
end
local msg = {} ---@type string[]
progress[client.id] = vim.tbl_filter(function(v)
return table.insert(msg, v.msg) or not v.done
end, p)
local spinner = { "", "", "", "", "", "", "", "", "", "" }
vim.notify(table.concat(msg, "\n"), "info", {
id = "lsp_progress",
title = client.name,
opts = function(notif)
notif.icon = #progress[client.id] == 0 and ""
or spinner[math.floor(vim.uv.hrtime() / (1e6 * 80)) % #spinner + 1]
end,
})
end,
})
-- NOTE: This file uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler
-- This is a slightly more performant fallback function
-- for when you don't provide a filetype to trigger on yourself.
-- nixCats gives us the paths, which is faster than searching the rtp!
local old_ft_fallback = require('lze').h.lsp.get_ft_fallback()
require('lze').h.lsp.set_ft_fallback(function(name)
local lspcfg = nixCats.pawsible({ "allPlugins", "opt", "nvim-lspconfig" }) or
nixCats.pawsible({ "allPlugins", "start", "nvim-lspconfig" })
if lspcfg then
local ok, cfg = pcall(dofile, lspcfg .. "/lsp/" .. name .. ".lua")
if not ok then
ok, cfg = pcall(dofile, lspcfg .. "/lua/lspconfig/configs/" .. name .. ".lua")
end
return (ok and cfg or {}).filetypes or {}
else
return old_ft_fallback(name)
end
end)
require('lze').load {
{
"nvim-lspconfig",
for_cat = "lsp",
on_require = { "lspconfig" },
-- rustaceanvim and zk-nvim dont require("lspconfig")
ft = { "markdown", "rust" },
-- NOTE: define a function for lsp,
-- and it will run for all specs with type(plugin.lsp) == table
-- when their filetype trigger loads them
lsp = function(plugin)
vim.lsp.config(plugin.name, plugin.lsp or {})
vim.lsp.enable(plugin.name)
end,
},
{
"mason.nvim",
-- only run it when not on nix
enabled = not catUtils.isNixCats,
on_plugin = { "nvim-lspconfig" },
load = function(name)
vim.cmd.packadd(name)
vim.cmd.packadd("mason-lspconfig.nvim")
require('mason').setup()
-- auto install will make it install servers when lspconfig is called on them.
require('mason-lspconfig').setup { automatic_installation = true, }
end,
},
{
-- lazydev makes your lsp way better in your config without needing extra lsp configuration.
"lazydev.nvim",
for_cat = "lsp.lua",
cmd = { "LazyDev" },
ft = "lua",
after = function(_)
require('lazydev').setup({
library = {
{ words = { "nixCats" }, path = (nixCats.nixCatsPath or "") .. '/lua' },
},
})
end,
},
{
-- name of the lsp
"lua_ls",
enabled = nixCats('lsp.lua'),
-- provide a table containing filetypes,
-- and then whatever your functions defined in the function type specs expect.
-- in our case, it just expects the normal lspconfig setup options,
-- but with a default on_attach and capabilities
lsp = {
-- if you provide the filetypes it doesn't ask lspconfig for the filetypes
filetypes = { 'lua' },
settings = {
Lua = {
runtime = { version = 'LuaJIT' },
formatters = {
ignoreComments = true,
},
signatureHelp = { enabled = true },
diagnostics = {
globals = { "nixCats", "vim", },
disable = { 'missing-fields' },
},
telemetry = { enabled = false },
},
},
},
-- also these are regular specs and you can use before and after and all the other normal fields
},
{
"basedpyright",
enabled = nixCats("lsp.python"),
lsp = {},
},
{
"bashls",
enabled = nixCats("lsp.bash"),
lsp = {},
},
{
"clangd",
enabled = nixCats("lsp.c"),
lsp = {},
},
{
"ruff",
enabled = nixCats("lsp.python"),
lsp = {},
},
{
"tinymist",
enabled = nixCats("lsp.tinymist"),
lsp = {
filetypes = { "typst" },
settings = {
formatterMode = "typstyle",
},
},
},
{
"nixd",
enabled = catUtils.isNixCats and nixCats('lsp.nix'),
lsp = {
filetypes = { "nix" },
settings = {
nixd = {
-- nixd requires some configuration.
-- luckily, the nixCats plugin is here to pass whatever we need!
-- we passed this in via the `extra` table in our packageDefinitions
-- for additional configuration options, refer to:
-- https://github.com/nix-community/nixd/blob/main/nixd/docs/configuration.md
nixpkgs = {
-- in the extras set of your package definition:
-- nixdExtras.nixpkgs = ''import ${pkgs.path} {}''
expr = nixCats.extra("nixdExtras.nixpkgs")
},
options = {
-- If you integrated with your system flake,
-- you should use inputs.self as the path to your system flake
-- that way it will ALWAYS work, regardless
-- of where your config actually was.
nixos = {
-- nixdExtras.nixos_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").nixosConfigurations.configname.options''
expr = nixCats.extra("nixdExtras.nixos_options")
},
-- If you have your config as a separate flake, inputs.self would be referring to the wrong flake.
-- You can override the correct one into your package definition on import in your main configuration,
-- or just put an absolute path to where it usually is and accept the impurity.
["home-manager"] = {
-- nixdExtras.home_manager_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").homeConfigurations.configname.options''
expr = nixCats.extra("nixdExtras.home_manager_options")
}
},
formatting = {
command = { "alejandra" }
},
diagnostic = {
suppress = {
"sema-escaping-with"
}
}
}
},
},
},
{
"rustaceanvim",
for_cat = "lsp.rust",
},
{
"zk-nvim",
for_cat = "lsp.zk",
ft = "markdown",
after = function()
require("zk").setup({ picker = "snacks_picker" })
vim.api.nvim_set_keymap("n", "<leader>zb", "<Cmd>ZkBackLinks<CR>", { desc = "Show [B]acklinkgs" })
vim.api.nvim_set_keymap("n", "<leader>zl", "<Cmd>ZkLinks<CR>", { desc = "Show [L]inks" })
vim.api.nvim_set_keymap("n", "<leader>zi", ":'<,'>ZkInsertLink<CR>", { desc = "[I]nsert link" })
vim.api.nvim_set_keymap("n", "<leader>zn", "<Cmd>ZkNew { title = vim.fn.input('Title: ') }<CR>",
{ desc = "[N]ew note" })
vim.api.nvim_set_keymap("n", "<leader>zo", "<Cmd>ZkNotes { sort = { 'modified' } }<CR>", { desc = "[O]pen notes" })
vim.api.nvim_set_keymap("n", "<leader>zt", "<Cmd>ZkTags<CR>", { desc = "Search [T]ags" })
vim.api.nvim_set_keymap("v", "<leader>zf", ":'<,'>ZkMatch<CR>", { desc = "[F]ind note from selection" })
vim.api.nvim_set_keymap("v", "<leader>zn", ":'<,'>ZkNewFromTitleSelection<CR>", {
desc =
"[N]ew note from selection"
})
end
},
}

View file

@ -1,20 +0,0 @@
-- TODO: split up the plugins a bit.
-- NOTE: various, non-plugin config
require('myLuaConf.opts_and_keys')
-- NOTE: register an extra lze handler with the spec_field 'for_cat'
-- that makes enabling an lze spec for a category slightly nicer
require("lze").register_handlers(require('nixCatsUtils.lzUtils').for_cat)
-- NOTE: Register another one from lzextras. This one makes it so that
-- you can set up lsps within lze specs,
-- and trigger lspconfig setup hooks only on the correct filetypes
require('lze').register_handlers(require('lzextras').lsp)
-- demonstrated in ./LSPs/init.lua
-- NOTE: general plugins
require("myLuaConf.plugins")
-- NOTE: obviously, more plugins, but more organized by what they do below
require("myLuaConf.LSPs")

View file

@ -1,92 +0,0 @@
-- TODO: completley out of date
-- load the plugins via paq-nvim when not on nix
-- YOU are in charge of putting the plugin
-- urls and build steps in here, which will only be used when not on nix.
-- and you should keep any setup functions OUT of this file
-- again, you dont need this file if you only use nix to load the config,
-- this is a fallback only, and is optional.
require('nixCatsUtils.catPacker').setup({
--[[ ------------------------------------------ ]]
--[[ The way to think of this is, its very ]]
--[[ similar to the main nix file for nixCats ]]
--[[ ]]
--[[ It can be used to download your plugins, ]]
--[[ and it has an opt for optional plugins. ]]
--[[ ]]
--[[ We dont want to handle anything about ]]
--[[ loading those plugins here, so that we can ]]
--[[ use the same loading code that we use for ]]
--[[ our normal nix-loaded config. ]]
--[[ we will do all our loading and configuring ]]
--[[ elsewhere in our configuration, so that ]]
--[[ we dont have to write it twice. ]]
--[[ ------------------------------------------ ]]
{ "BirdeeHub/lze", },
{ "BirdeeHub/lzextras", },
{ "stevearc/oil.nvim", },
{ 'ellisonleao/gruvbox.nvim', },
{ 'nvim-tree/nvim-web-devicons', },
{ 'nvim-lua/plenary.nvim', },
{ 'tpope/vim-repeat', },
{ 'rcarriga/nvim-notify', },
{ 'nvim-treesitter/nvim-treesitter-textobjects', opt = true, },
{ 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', opt = true, },
{ 'nvim-telescope/telescope-fzf-native.nvim', build = ':!which make && make', opt = true, },
{ 'nvim-telescope/telescope-ui-select.nvim', opt = true, },
{'nvim-telescope/telescope.nvim', opt = true, },
-- lsp
{ 'williamboman/mason.nvim', opt = true, },
{ 'williamboman/mason-lspconfig.nvim', opt = true, },
{ 'j-hui/fidget.nvim', opt = true, },
{ 'neovim/nvim-lspconfig', opt = true, },
-- NOTE: we take care of lazy loading elsewhere in an autocommand
-- so that we can use the same code on and off nix.
-- so here we just tell it not to auto load it
{ 'folke/lazydev.nvim', opt = true, },
-- completion
{ 'L3MON4D3/LuaSnip', opt = true, as = "luasnip", },
{ 'hrsh7th/cmp-cmdline', opt = true, },
{ 'Saghen/blink.cmp', opt = true, },
{ 'Saghen/blink.compat', opt = true, },
{ 'xzbdmw/colorful-menu.nvim', opt = true, },
-- lint and format
{ 'mfussenegger/nvim-lint', opt = true, },
{ 'stevearc/conform.nvim', opt = true, },
-- dap
{ 'nvim-neotest/nvim-nio', opt = true, },
{ 'rcarriga/nvim-dap-ui', opt = true, },
{ 'theHamsta/nvim-dap-virtual-text', opt = true, },
{ 'jay-babu/mason-nvim-dap.nvim', opt = true, },
{ 'mfussenegger/nvim-dap', opt = true, },
-- { 'm-demare/hlargs.nvim', },
{ 'mbbill/undotree', opt = true, },
{ 'tpope/vim-fugitive', opt = true, },
{ 'tpope/vim-rhubarb', opt = true, },
{ 'tpope/vim-sleuth', opt = true, },
{ 'folke/which-key.nvim', opt = true, },
{ 'lewis6991/gitsigns.nvim', opt = true, },
{ 'nvim-lualine/lualine.nvim', opt = true, },
{ 'lukas-reineke/indent-blankline.nvim', opt = true, },
{ 'numToStr/Comment.nvim', opt = true, as = "comment.nvim", },
{ 'kylechui/nvim-surround', opt = true, },
{
"iamcco/markdown-preview.nvim",
build = ":call mkdp#util#install()",
opt = true,
},
-- all the rest of the setup will be done using the normal setup functions later,
-- thus working regardless of what method loads the plugins.
-- only stuff pertaining to downloading should be added to paq.
})
-- OK, again, that isnt needed if you load this setup via nix, but it is an option.

View file

@ -1,156 +0,0 @@
local load_w_after = function(name)
vim.cmd.packadd(name)
vim.cmd.packadd(name .. '/after')
end
return {
{
"cmp-cmdline",
for_cat = "completion",
on_plugin = { "blink.cmp" },
load = load_w_after,
},
{
"blink.compat",
for_cat = "completion",
dep_of = { "cmp-cmdline" },
},
{
"luasnip",
for_cat = "completion",
dep_of = { "blink.cmp" },
after = function(_)
vim.cmd.packadd("friendly-snippets")
local luasnip = require 'luasnip'
require('luasnip.loaders.from_vscode').lazy_load()
luasnip.config.setup {}
local ls = require('luasnip')
vim.keymap.set({ "i", "s" }, "<M-n>", function()
if ls.choice_active() then
ls.change_choice(1)
end
end)
end,
},
{
"colorful-menu.nvim",
for_cat = "completion",
on_plugin = { "blink.cmp" },
},
{
"blink-emoji.nvim",
for_cat = "completion",
on_plugin = { "blink.cmp" },
},
{
"blink.cmp",
for_cat = "completion",
event = "DeferredUIEnter",
after = function(_)
require("blink.cmp").setup({
-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
-- See :h blink-cmp-config-keymap for configuring keymaps
keymap = { preset = "enter", },
cmdline = {
enabled = true,
completion = {
menu = {
auto_show = true,
},
},
sources = function()
local type = vim.fn.getcmdtype()
-- Search forward and backward
if type == '/' or type == '?' then return { 'buffer' } end
-- Commands
if type == ':' or type == '@' then return { 'cmdline', 'cmp_cmdline' } end
return {}
end,
},
fuzzy = {
sorts = {
'exact',
-- defaults
'score',
'sort_text',
},
},
signature = {
enabled = true,
window = {
show_documentation = true,
},
},
completion = {
list = {
selection = {
preselect = false,
auto_insert = false,
},
},
menu = {
draw = {
treesitter = { 'lsp' },
components = {
label = {
text = function(ctx)
return require("colorful-menu").blink_components_text(ctx)
end,
highlight = function(ctx)
return require("colorful-menu").blink_components_highlight(ctx)
end,
},
},
},
},
documentation = {
auto_show = true,
},
},
snippets = {
preset = 'luasnip',
active = function(filter)
local snippet = require "luasnip"
local blink = require "blink.cmp"
if snippet.in_snippet() and not blink.is_visible() then
return true
else
if not snippet.in_snippet() and vim.fn.mode() == "n" then snippet.unlink_current() end
return false
end
end,
},
sources = {
default = { 'lsp', 'path', 'snippets', 'buffer', 'omni', 'emoji', },
providers = {
path = {
score_offset = 50,
},
lsp = {
score_offset = 40,
},
snippets = {
score_offset = 40,
},
emoji = {
module = "blink-emoji",
name = "Emoji",
score_offset = 15,
opts = { insert = true },
},
cmp_cmdline = {
name = 'cmp_cmdline',
module = 'blink.compat.source',
score_offset = -100,
opts = {
cmp_name = 'cmdline',
},
},
},
},
})
end,
},
}

View file

@ -1,84 +0,0 @@
return {
"gitsigns.nvim",
for_cat = 'git',
event = "DeferredUIEnter",
-- cmd = { "" },
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function()
require('gitsigns').setup({
-- See `:help gitsigns.txt`
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '~' },
},
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
-- Navigation
map({ 'n', 'v' }, ']c', function()
if vim.wo.diff then
return ']c'
end
vim.schedule(function()
gs.next_hunk()
end)
return '<Ignore>'
end, { expr = true, desc = 'Jump to next hunk' })
map({ 'n', 'v' }, '[c', function()
if vim.wo.diff then
return '[c'
end
vim.schedule(function()
gs.prev_hunk()
end)
return '<Ignore>'
end, { expr = true, desc = 'Jump to previous hunk' })
-- Actions
-- visual mode
map('v', '<leader>hs', function()
gs.stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'stage git hunk' })
map('v', '<leader>hr', function()
gs.reset_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'reset git hunk' })
-- normal mode
map('n', '<leader>gs', gs.stage_hunk, { desc = 'git stage hunk' })
map('n', '<leader>gr', gs.reset_hunk, { desc = 'git reset hunk' })
map('n', '<leader>gS', gs.stage_buffer, { desc = 'git Stage buffer' })
map('n', '<leader>gu', gs.undo_stage_hunk, { desc = 'undo stage hunk' })
map('n', '<leader>gR', gs.reset_buffer, { desc = 'git Reset buffer' })
map('n', '<leader>gp', gs.preview_hunk, { desc = 'preview git hunk' })
map('n', '<leader>gb', function()
gs.blame_line { full = false }
end, { desc = 'git blame line' })
map('n', '<leader>gd', gs.diffthis, { desc = 'git diff against index' })
map('n', '<leader>gD', function()
gs.diffthis '~'
end, { desc = 'git diff against last commit' })
-- Toggles
map('n', '<leader>gtb', gs.toggle_current_line_blame, { desc = 'toggle git blame line' })
map('n', '<leader>gtd', gs.toggle_deleted, { desc = 'toggle git show deleted' })
-- Text object
map({ 'o', 'x' }, 'ih', ':<C-U>Gitsigns select_hunk<CR>', { desc = 'select git hunk' })
end,
})
vim.cmd([[hi GitSignsAdd guifg=#04de21]])
vim.cmd([[hi GitSignsChange guifg=#83fce6]])
vim.cmd([[hi GitSignsDelete guifg=#fa2525]])
end,
}

View file

@ -1,279 +0,0 @@
local colorschemeName = nixCats('colorscheme')
if not require('nixCatsUtils').isNixCats then
colorschemeName = 'gruvbox'
end
-- Could I lazy load on colorscheme with lze?
-- sure. But I was going to call vim.cmd.colorscheme() during startup anyway
-- this is just an example, feel free to do a better job!
vim.cmd.colorscheme(colorschemeName)
local ok, notify = pcall(require, "notify")
if ok then
notify.setup({
on_open = function(win)
vim.api.nvim_win_set_config(win, { focusable = false })
end,
})
vim.notify = notify
vim.keymap.set("n", "<Esc>", function()
notify.dismiss({ silent = true, })
end, { desc = "dismiss notify popup and clear hlsearch" })
end
-- NOTE: you can check if you included the category with the thing wherever you want.
if nixCats('always') then
-- I didnt want to bother with lazy loading this.
-- I could put it in opt and put it in a spec anyway
-- and then not set any handlers and it would load at startup,
-- but why... I guess I could make it load
-- after the other lze definitions in the next call using priority value?
-- didnt seem necessary.
vim.g.loaded_netrwPlugin = 1
require("oil").setup({
default_file_explorer = false,
view_options = {
show_hidden = true
},
columns = {
"icon",
"permissions",
"size",
-- "mtime",
},
keymaps = {
["g?"] = "actions.show_help",
["<CR>"] = "actions.select",
["<C-s>"] = "actions.select_vsplit",
["<C-h>"] = "actions.select_split",
["<C-t>"] = "actions.select_tab",
["<C-p>"] = "actions.preview",
["<C-c>"] = "actions.close",
["<C-l>"] = "actions.refresh",
["-"] = "actions.parent",
["_"] = "actions.open_cwd",
["`"] = "actions.cd",
["~"] = "actions.tcd",
["gs"] = "actions.change_sort",
["gx"] = "actions.open_external",
["g."] = "actions.toggle_hidden",
["g\\"] = "actions.toggle_trash",
},
})
vim.keymap.set("n", "-", "<cmd>Oil<CR>", { noremap = true, desc = 'Open Parent Directory' })
vim.keymap.set("n", "<leader>-", "<cmd>Oil .<CR>", { noremap = true, desc = 'Open nvim root directory' })
end
if nixCats("always") then
-- Potentially checkout the lazygit module.
local Snacks = require("snacks")
local config = {
bufdelete = { enable = true },
dim = { enable = true },
git = { enable = true },
input = { enable = true },
notifier = { enable = true },
terminal = { enable = true },
toggle = { enable = true },
quickfile = { enable = true },
scope = { enable = true },
statuscolumn = { enable = true },
explorer = { replace_netrw = true },
picker = {
enabled = true,
ui_select = true,
matcher = {
fuzzy = true,
frecency = true,
},
previewers = {
diff = {
builtin = true, -- use Neovim for previewing diffs (true) or use an external tool (false)
cmd = { "delta" }, -- example to show a diff with delta
},
git = {
builtin = true, -- use Neovim for previewing git output (true) or use git (false)
},
},
},
indent = {
enabled = true,
animate = { enabled = false },
scope = { enabled = true },
chunk = { enabled = true },
},
image = { enabled = false, inline = false, float = false },
lazygit = { enabled = false, configure = false },
}
if nixCats("markdown") then
config.image.enable = true
end
if nixCats("git") then
config.lazygit.enable = true
end
Snacks.setup(config)
-- setup keybinds.
vim.keymap.set("n", "<leader>bd", Snacks.bufdelete.delete, { desc = "delete buffer" })
vim.keymap.set("n", "<leader>t", function() Snacks.explorer() end, { desc = "File [T]ree" })
vim.keymap.set("n", "<leader>i", Snacks.image.hover, { desc = "[I]mage preview" })
-- picker keybinds
vim.keymap.set("n", "<leader>fGb", Snacks.picker.grep_buffers, { desc = "[G]rep buffers" })
vim.keymap.set("n", "<leader>fGl", Snacks.picker.lines, { desc = "[L]ines in buffer" })
vim.keymap.set("n", "<leader>fb", Snacks.picker.buffers, { desc = "[B]uffers" })
vim.keymap.set("n", "<leader>ff", Snacks.picker.files, { desc = "[F]iles" })
vim.keymap.set("n", "<leader>fg", Snacks.picker.grep, { desc = "[G]rep all" })
vim.keymap.set("n", "<leader>fh", Snacks.picker.help, { desc = "[H]elp" })
vim.keymap.set("n", "<leader>fi", Snacks.picker.icons, { desc = "[I]cons" })
vim.keymap.set("n", "<leader>fm", Snacks.picker.marks, { desc = "[M]arks" })
vim.keymap.set("n", "<leader>fs", Snacks.picker.spelling, { desc = "[S]pelling" })
vim.keymap.set("n", "<leader>ft", Snacks.picker.treesitter, { desc = "[T]reesitter" })
vim.keymap.set("n", "<leader>fu", Snacks.picker.undo, { desc = "[U]ndo" })
vim.keymap.set("n", "<leader>fz", Snacks.picker.zoxide, { desc = "[Z]oxide" })
-- picker git keybinds
vim.keymap.set("n", "<leader>gB", Snacks.git.blame_line, { desc = "[G]it [B]lame" })
vim.keymap.set("n", "<leader>gb", Snacks.picker.git_branches, { desc = "[G]it [B]ranch" })
vim.keymap.set("n", "<leader>gl", Snacks.picker.git_log, { desc = "[G]it [L]og" })
vim.keymap.set("n", "<leader>gd", Snacks.picker.git_diff, { desc = "[G]it [D]iff" })
vim.keymap.set("n", "<leader>gt", Snacks.lazygit.open, { desc = "lazy[G]it [T]UI" })
-- setup toggles
Snacks.toggle.option("spell", { name = "spelling" }):map("<leader>cs")
Snacks.toggle.option("relativenumber", { name = "Relative Numbering" }):map("<leader>n")
Snacks.toggle.dim():map("<leader>d")
-- terminal keybinds
vim.keymap.set("n", "<leader>s", function()
Snacks.terminal.toggle(nil, { win = { position = "float" } })
end, { desc = "terminal" })
vim.keymap.set("t", "<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(200, 0, function() end)
return "<esc>"
end
end, { expr = true, desc = "Double tap to escape terminal" })
-- setup rename autocmds
local prev = { new_name = "", old_name = "" } -- Prevents duplicate events
vim.api.nvim_create_autocmd("User", {
pattern = "OilActionsPost",
callback = function(event)
if event.data.actions.type == "move" then
Snacks.rename.on_rename_file(event.data.actions.src_url, event.data.actions.dest_url)
end
end,
})
end
require('lze').load {
{ import = "myLuaConf.plugins.treesitter", },
{ import = "myLuaConf.plugins.completion", },
{ import = "myLuaConf.plugins.gitsigns", },
{ import = "myLuaConf.plugins.lualine", },
{ import = "myLuaConf.plugins.which-key", },
{
"markdown-preview.nvim",
-- NOTE: for_cat is a custom handler that just sets enabled value for us,
-- based on result of nixCats('cat.name') and allows us to set a different default if we wish
-- it is defined in luaUtils template in lua/nixCatsUtils/lzUtils.lua
-- you could replace this with enabled = nixCats('cat.name') == true
-- if you didnt care to set a different default for when not using nix than the default you already set
for_cat = 'markdown',
cmd = { "MarkdownPreview", "MarkdownPreviewStop", "MarkdownPreviewToggle", },
ft = "markdown",
keys = {
{ "<leader>pmp", "<cmd>MarkdownPreview <CR>", mode = { "n" }, noremap = true, desc = "markdown preview" },
{ "<leader>pms", "<cmd>MarkdownPreviewStop <CR>", mode = { "n" }, noremap = true, desc = "markdown preview stop" },
{ "<leader>pmt", "<cmd>MarkdownPreviewToggle <CR>", mode = { "n" }, noremap = true, desc = "markdown preview toggle" },
},
before = function()
vim.g.mkdp_auto_close = 0
end,
},
{
"typst-preview.nvim",
for_cat = "lsp.typst",
ft = "typst",
cmd = { "TypstPreview", "TypstPreviewStop", "TypstPreviewToggle", },
keys = {
{ "<leader>ptp", "<cmd>TypstPreview <CR>", mode = { "n" }, noremap = true, desc = "typst preview" },
{ "<leader>pts", "<cmd>TypstPreviewStop <CR>", mode = { "n" }, noremap = true, desc = "typst preview stop" },
{ "<leader>ptt", "<cmd>TypstPreviewToggle <CR>", mode = { "n" }, noremap = true, desc = "typst preview toggle" },
},
after = function()
require('typst-preview').setup {}
end
},
{
"leap.nvim",
for_cat = 'always',
event = "DeferredUIEnter",
keys = {
{ "s", "<Plug>(leap)", mode = { "n", "x", "o", "v" }, noremap = true, desc = "leap to char sequence" }
},
},
{
"nvim-surround",
for_cat = 'always',
event = "DeferredUIEnter",
after = function()
require('nvim-surround').setup()
end,
},
{
"marks.nvim",
for_cat = "always",
after = function()
require('marks').setup({})
end
},
{
"venn.nvim",
for_cat = "always",
keys = {
{ "<leader>v", function() Toggle_venn() end, desc = "toggle diagram drawing" }
},
before = function()
-- venn.nvim: enable or disable keymappings
function _G.Toggle_venn()
local venn_enabled = vim.inspect(vim.b.venn_enabled)
if venn_enabled == "nil" then
vim.b.venn_enabled = true
vim.o.virtualedit = "all"
-- draw a line on HJKL keystokes
vim.api.nvim_buf_set_keymap(0, "n", "J", "<C-v>j:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "K", "<C-v>k:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "L", "<C-v>l:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "H", "<C-v>h:VBox<CR>", { noremap = true })
-- draw a box by pressing "f" with visual selection
vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox<CR>", { noremap = true })
else
vim.o.virtualedit = ""
vim.api.nvim_buf_del_keymap(0, "n", "J")
vim.api.nvim_buf_del_keymap(0, "n", "K")
vim.api.nvim_buf_del_keymap(0, "n", "L")
vim.api.nvim_buf_del_keymap(0, "n", "H")
vim.api.nvim_buf_del_keymap(0, "v", "f")
vim.b.venn_enabled = nil
end
end
end
},
{
"vim-startuptime",
for_cat = 'extra',
cmd = { "StartupTime" },
before = function(_)
vim.g.startuptime_event_width = 0
vim.g.startuptime_tries = 10
vim.g.startuptime_exe_path = nixCats.packageBinPath
end,
}
}

View file

@ -1,43 +0,0 @@
return {
"lualine.nvim",
for_cat = 'always',
-- cmd = { "" },
event = "DeferredUIEnter",
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function()
require('lualine').setup({
options = {
alwaysDivideMiddle = true,
icons_enabled = true,
component_separators = { left = '', right = '' },
section_separators = { left = '', right = '' },
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { "filename" },
lualine_x = { "filetype" },
lualine_y = {},
lualine_z = {},
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_c = { { "filename", path = 1 } },
lualine_x = { "encoding", "fileformat", "filetype" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
tabline = {
lualine_a = { { "buffers", mode = 4 } },
lualine_b = {},
lualine_c = {},
lualine_x = {},
lualine_y = {},
lualine_z = { { "tabs", mode = 2 } }
},
})
end,
}

View file

@ -1,42 +0,0 @@
-- [[ Configure Treesitter ]]
-- See `:help nvim-treesitter`
return {
{
"nvim-treesitter",
for_cat = 'treesitter',
-- cmd = { "" },
event = "DeferredUIEnter",
-- ft = "",
-- keys = "",
-- colorscheme = "",
load = function(name)
vim.cmd.packadd(name)
vim.cmd.packadd("rainbow-delimiters.nvim")
end,
after = function(plugin)
-- [[ Configure Treesitter ]]
-- See `:help nvim-treesitter`
require('nvim-treesitter').setup {
highlight = { enable = true, },
indent = { enable = false, },
}
end,
},
{
"comment.nvim",
for_cat = 'treesitter',
after = function(plugin)
require('Comment').setup()
end,
},
{
"treesj",
for_cat = 'treesitter',
keys = { { "<leader>j", "<cmd>TSJToggle<CR>", mode = { "n" }, desc = "Treesitter join" }, },
after = function(_)
require("treesj").setup({
use_default_keymaps = false
})
end
},
}

View file

@ -1,21 +0,0 @@
return {
"which-key.nvim",
for_cat = 'always',
after = function()
require('which-key').setup({
})
require('which-key').add {
{ "<leader>g", group = "[g]it" },
{ "<leader>z", group = "[z]ettelkasten" },
{ "<leader>gt", group = "[t]oggle" },
{ "<leader>p", group = "[p]review" },
{ "<leader>pt", group = "[p]review [t]ypst" },
{ "<leader>pm", group = "[p]review [m]arkdown" },
{ "<leader>f", group = "[f]ind" },
{ "<leader>t", group = "[t]ree" },
{ "<leader>c", group = "[c]heck" },
{ "<leader>l", group = "[l]sp" },
{ "<leader>lw", group = "[l]sp [w]orkspace" },
}
end,
}

View file

@ -1,40 +0,0 @@
--[[
This directory is the luaUtils template.
You can choose what things from it that you would like to use.
And then delete the rest.
Everything in this directory is optional.
--]]
local M = {}
-- NOTE: This function is for defining a paq.nvim fallback method of downloading plugins
-- when nixCats was not used to install your config.
-- If you only ever load your config using nixCats, you don't need this file.
-- it literally just only runs it when not on nixCats
-- all neovim package managers that use the regular plugin loading scheme
-- can be used this way, just do whatever the plugin manager needs to put it in the
-- opt directory for lazy loading, and add the build steps so that when theres no nix the steps are ran
function M.setup(v)
if not vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] then
local function clone_paq()
local path = vim.fn.stdpath("data") .. "/site/pack/paqs/start/paq-nvim"
local is_installed = vim.fn.empty(vim.fn.glob(path)) == 0
if not is_installed then
vim.fn.system { "git", "clone", "--depth=1", "https://github.com/savq/paq-nvim.git", path }
return true
end
end
local function bootstrap_paq(packages)
local first_install = clone_paq()
vim.cmd.packadd("paq-nvim")
local paq = require("paq")
if first_install then
vim.notify("Installing plugins... If prompted, hit Enter to continue.")
end
paq(packages)
paq.install()
end
bootstrap_paq(vim.list_extend({"savq/paq-nvim"},v))
end
end
return M

View file

@ -1,129 +0,0 @@
--[[
This directory is the luaUtils template.
You can choose what things from it that you would like to use.
And then delete the rest.
Everything in this directory is optional.
--]]
local M = {}
--[[
This file is for making your config still work WITHOUT nixCats.
When you don't use nixCats to load your config,
you wont have the nixCats plugin.
The setup function defined here defines a mock nixCats plugin when nixCats wasnt used to load the config.
This will help avoid indexing errors when the nixCats plugin doesnt exist.
NOTE: If you only ever use nixCats to load your config, you don't need this file.
--]]
---@type boolean
M.isNixCats = vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil
---@class nixCatsSetupOpts
---@field non_nix_value boolean|nil
---This function will setup a mock nixCats plugin when not using nix
---It will help prevent you from running into indexing errors without a nixCats plugin from nix.
---If you loaded the config via nix, it does nothing
---non_nix_value defaults to true if not provided or is not a boolean.
---@param v nixCatsSetupOpts
function M.setup(v)
if not M.isNixCats then
local nixCats_default_value
if type(v) == "table" and type(v.non_nix_value) == "boolean" then
nixCats_default_value = v.non_nix_value
else
nixCats_default_value = true
end
local mk_with_meta = function (tbl)
return setmetatable(tbl, {
__call = function(_, attrpath)
local strtable = {}
if type(attrpath) == "table" then
strtable = attrpath
elseif type(attrpath) == "string" then
for key in attrpath:gmatch("([^%.]+)") do
table.insert(strtable, key)
end
else
print("function requires a table of strings or a dot separated string")
return
end
return vim.tbl_get(tbl, unpack(strtable));
end
})
end
package.preload['nixCats'] = function ()
local ncsub = {
get = function(_) return nixCats_default_value end,
cats = mk_with_meta({
nixCats_config_location = vim.fn.stdpath('config'),
wrapRc = false,
}),
settings = mk_with_meta({
nixCats_config_location = vim.fn.stdpath('config'),
configDirName = os.getenv("NVIM_APPNAME") or "nvim",
wrapRc = false,
}),
petShop = mk_with_meta({}),
extra = mk_with_meta({}),
pawsible = mk_with_meta({
allPlugins = {
start = {},
opt = {},
},
}),
configDir = vim.fn.stdpath('config'),
packageBinPath = os.getenv('NVIM_WRAPPER_PATH_NIX') or vim.v.progpath
}
return setmetatable(ncsub, {__call = function(_, cat) return ncsub.get(cat) end})
end
_G.nixCats = require('nixCats')
end
end
---allows you to guarantee a boolean is returned, and also declare a different
---default value than specified in setup when not using nix to load the config
---@overload fun(v: string|string[]): boolean
---@overload fun(v: string|string[], default: boolean): boolean
function M.enableForCategory(v, default)
if M.isNixCats or default == nil then
if nixCats(v) then
return true
else
return false
end
else
return default
end
end
---if nix, return value of nixCats(v) else return default
---Exists to specify a different non_nix_value than the one in setup()
---@param v string|string[]
---@param default any
---@return any
function M.getCatOrDefault(v, default)
if M.isNixCats then
return nixCats(v)
else
return default
end
end
---for conditionally disabling build steps on nix, as they are done via nix
---I should probably have named it dontAddIfCats or something.
---@overload fun(v: any): any|nil
---Will return the second value if nix, otherwise the first
---@overload fun(v: any, o: any): any
function M.lazyAdd(v, o)
if M.isNixCats then
return o
else
return v
end
end
return M

View file

@ -1,36 +0,0 @@
--[[
This directory is the luaUtils template.
You can choose what things from it that you would like to use.
And then delete the rest.
Everything in this directory is optional.
--]]
local M = {}
-- A nixCats specific lze handler that you can use to conditionally enable by category easier.
-- at the start of your config, register with
-- require('lze').register_handlers(require('nixCatsUtils.lzUtils').for_cat)
-- before any calls to require('lze').load using the handler have been made.
-- accepts:
-- for_cat = { "your" "cat" };
-- for_cat = { cat = { "your" "cat" }, default = bool }
-- for_cat = "your.cat";
-- for_cat = { cat = "your.cat", default = bool }
-- where default is an alternate value for when nixCats was NOT used to install the config
M.for_cat = {
spec_field = "for_cat",
set_lazy = false,
modify = function(plugin)
if type(plugin.for_cat) == "table" and plugin.for_cat.cat ~= nil then
if vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil then
plugin.enabled = nixCats(plugin.for_cat.cat) or false
else
plugin.enabled = plugin.for_cat.default
end
else
plugin.enabled = nixCats(plugin.for_cat) or false
end
return plugin
end,
}
return M

View file

@ -1,4 +1,4 @@
-- NOTE: These 2 need to be set up before any plugins are loaded.
-- NOTE: These 2 should be set up before any plugins with keybinds are loaded.
vim.g.mapleader = ';'
vim.g.maplocalleader = ';'
@ -6,9 +6,13 @@ vim.g.maplocalleader = ';'
-- See `:help vim.o`
-- NOTE: You can change these options as you wish!
-- allow .nvim.lua in current dir and parents (project config)
vim.o.exrc = false -- can be toggled off in that file to stop it from searching further
-- Sets how neovim will display certain whitespace characters in the editor.
-- See `:help 'list'`
-- and `:help 'listchars'`
-- and `:help 'showbreak'`
vim.opt.list = true
vim.opt.listchars = { eol = "", extends = "", nbsp = "", precedes = "", tab = ">-", trail = "" }
vim.opt.showbreak = "";
@ -29,6 +33,7 @@ vim.opt.scrolloff = 10
-- Make line numbers default
vim.opt.number = true
vim.opt.numberwidth = 3
-- Enable mouse mode
vim.opt.mouse = 'a'
@ -40,10 +45,6 @@ vim.opt.wrapmargin = 0
-- get nice visual guides for 80, 100, and 120 cols.
vim.opt.colorcolumn = { "90", "100", "120", }
-- add line numbers
vim.opt.number = true
vim.opt.numberwidth = 3
-- Indent
vim.opt.smarttab = true
vim.opt.expandtab = true
@ -95,22 +96,6 @@ vim.api.nvim_create_autocmd('TextYankPost', {
vim.g.netrw_liststyle = 0
vim.g.netrw_banner = 0
-- [[ Basic Keymaps ]]
-- make quick system clipboard opts easier
vim.keymap.set({ 'n', 'v', 'x' }, '<leader>p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' })
vim.keymap.set({ "v", "x", "n" }, '<leader>y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' })
vim.keymap.set({ "n", "v", "x" }, '<leader>Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' })
vim.keymap.set('i', '<C-p>', '<C-r><C-p>+',
{ noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' })
-- Diagnostic keymaps
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous diagnostic message' })
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next diagnostic message' })
vim.keymap.set('n', '<leader>d', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' })
-- moving between splits
vim.keymap.set('n', '<C-h>', '<C-w>h', { desc = 'move to right split' })
vim.keymap.set('n', '<C-j>', '<C-w>j', { desc = 'move to below split' })
vim.keymap.set('n', '<C-k>', '<C-w>k', { desc = 'move to above split' })
vim.keymap.set('n', '<C-l>', '<C-w>l', { desc = 'move to left split' })
vim.g.netrw_liststyle=0
vim.g.netrw_banner=0

743
lua/plugins.lua Normal file
View file

@ -0,0 +1,743 @@
-- NOTE: You will likely want to break this up into more files.
-- You can call this more than once.
-- You can also include other files from within the specs via an `import` spec.
-- see https://github.com/BirdeeHub/lze?tab=readme-ov-file#structuring-your-plugins
nixInfo.lze.load {
{
-- lze specs need a name
"trigger_colorscheme",
-- lazy loaded colorscheme.
-- This means you will need to add the colorscheme you want to lze sometime before VimEnter is done
event = "VimEnter",
-- Also, lze can load more than just plugins.
-- The default load field contains vim.cmd.packadd
-- Here we override it to schedule when our colorscheme is loaded
load = function(_name)
-- schedule so it runs after VimEnter
vim.schedule(function()
vim.cmd.colorscheme(nixInfo("onedark_dark", "settings", "colorscheme"))
vim.schedule(function()
-- I like this color. Use vim.schedule again to set it after the colorscheme is finished
vim.cmd([[hi LineNr guifg=#bb9af7]])
end)
end)
end
},
{
-- NOTE: view these names in the info plugin!
-- :lua nixInfo.lze.debug.display(nixInfo.plugins)
-- The display function is from lzextras
"onedarkpro.nvim",
auto_enable = true, -- <- auto enable is useful here
colorscheme = { "onedark", "onedark_dark", "onedark_vivid", "onelight" },
},
{
"vim-moonfly-colors",
auto_enable = true,
colorscheme = "moonfly",
},
{
"snacks.nvim",
auto_enable = true,
-- snacks makes a global, and then lazily loads itself
lazy = false,
-- priority only affects startup plugins
-- unless otherwise specified by a particular handler
priority = 1000,
after = function(plugin)
-- I also like this color
vim.api.nvim_set_hl(0, "MySnacksIndent", { fg = "#32a88f" })
require('snacks').setup({
explorer = { replace_netrw = true, },
picker = {
sources = {
explorer = {
auto_close = true,
},
},
},
git = {},
terminal = {},
scope = {},
indent = {
scope = {
hl = 'MySnacksIndent',
},
chunk = {
-- enabled = true,
hl = 'MySnacksIndent',
}
},
statuscolumn = {
left = { "mark", "git" }, -- priority of signs on the left (high to low)
right = { "sign", "fold" }, -- priority of signs on the right (high to low)
folds = {
open = false, -- show open fold icons
git_hl = false, -- use Git Signs hl for fold icons
},
git = {
-- patterns to match Git signs
patterns = { "GitSign", "MiniDiffSign" },
},
refresh = 50, -- refresh at most every 50ms
},
-- make sure lazygit always reopens the correct program
-- hopefully this can be removed one day
lazygit = {
config = {
os = {
editPreset = "nvim-remote",
edit = vim.v.progpath .. [=[ --server "$NVIM" --remote-send '<cmd>lua nixInfo.lazygit_fix({{filename}})<CR>']=],
editAtLine = vim.v.progpath .. [=[ --server "$NVIM" --remote-send '<cmd>lua nixInfo.lazygit_fix({{filename}}, {{line}})<CR>']=],
openDirInEditor = vim.v.progpath .. [=[ --server "$NVIM" --remote-send '<cmd>lua nixInfo.lazygit_fix({{dir}})<CR>']=],
-- this one isnt a remote command, make sure it gets our config regardless of if we name it nvim or not
editAtLineAndWait = nixInfo(vim.v.progpath, "progpath") .. " +{{line}} {{filename}}",
},
},
},
})
-- Handle the backend of those remote commands.
-- hopefully this can be removed one day
nixInfo.lazygit_fix = function(path, line)
local prev = vim.fn.bufnr("#")
local prev_win = vim.fn.bufwinid(prev)
vim.api.nvim_feedkeys("q", "n", false)
if line then
vim.api.nvim_buf_call(prev, function()
vim.cmd.edit(path)
local buf = vim.api.nvim_get_current_buf()
vim.schedule(function()
if buf then
vim.api.nvim_win_set_buf(prev_win, buf)
vim.api.nvim_win_set_cursor(0, { line or 0, 0})
end
end)
end)
else
vim.api.nvim_buf_call(prev, function()
vim.cmd.edit(path)
local buf = vim.api.nvim_get_current_buf()
vim.schedule(function()
if buf then
vim.api.nvim_win_set_buf(prev_win, buf)
end
end)
end)
end
end
-- NOTE: we aren't loading this lazily, and the keybinds already are so it is fine to just set these here
vim.keymap.set("n", "-", function() Snacks.explorer.open() end, { desc = 'Snacks file explorer' })
vim.keymap.set("n", "<c-\\>", function() Snacks.terminal.open() end, { desc = 'Snacks Terminal' })
vim.keymap.set("n", "<leader>_", function() Snacks.lazygit.open() end, { desc = 'Snacks LazyGit' })
vim.keymap.set('n', "<leader>sf", function() Snacks.picker.smart() end, { desc = "Smart Find Files" })
vim.keymap.set('n', "<leader><leader>s", function() Snacks.picker.buffers() end, { desc = "Search Buffers" })
-- find
vim.keymap.set('n', "<leader>ff", function() Snacks.picker.files() end, { desc = "Find Files" })
vim.keymap.set('n', "<leader>fg", function() Snacks.picker.git_files() end, { desc = "Find Git Files" })
-- Grep
vim.keymap.set('n', "<leader>sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" })
vim.keymap.set('n', "<leader>sB", function() Snacks.picker.grep_buffers() end, { desc = "Grep Open Buffers" })
vim.keymap.set('n', "<leader>sg", function() Snacks.picker.grep() end, { desc = "Grep" })
vim.keymap.set({ "n", "x" }, "<leader>sw", function() Snacks.picker.grep_word() end, { desc = "Visual selection or ord" })
-- search
vim.keymap.set('n', "<leader>sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" })
vim.keymap.set('n', "<leader>sd", function() Snacks.picker.diagnostics() end, { desc = "Diagnostics" })
vim.keymap.set('n', "<leader>sD", function() Snacks.picker.diagnostics_buffer() end, { desc = "Buffer Diagnostics" })
vim.keymap.set('n', "<leader>sh", function() Snacks.picker.help() end, { desc = "Help Pages" })
vim.keymap.set('n', "<leader>sj", function() Snacks.picker.jumps() end, { desc = "Jumps" })
vim.keymap.set('n', "<leader>sk", function() Snacks.picker.keymaps() end, { desc = "Keymaps" })
vim.keymap.set('n', "<leader>sl", function() Snacks.picker.loclist() end, { desc = "Location List" })
vim.keymap.set('n', "<leader>sm", function() Snacks.picker.marks() end, { desc = "Marks" })
vim.keymap.set('n', "<leader>sM", function() Snacks.picker.man() end, { desc = "Man Pages" })
vim.keymap.set('n', "<leader>sq", function() Snacks.picker.qflist() end, { desc = "Quickfix List" })
vim.keymap.set('n', "<leader>sR", function() Snacks.picker.resume() end, { desc = "Resume" })
vim.keymap.set('n', "<leader>su", function() Snacks.picker.undo() end, { desc = "Undo History" })
end
},
{
"nvim-lspconfig",
auto_enable = true,
-- NOTE: define a function for lsp,
-- and it will run for all specs with type(plugin.lsp) == table
-- when their filetype trigger loads them
lsp = function(plugin)
vim.lsp.config(plugin.name, plugin.lsp or {})
vim.lsp.enable(plugin.name)
end,
-- set up our on_attach function once before the spec loads
before = function(_)
vim.lsp.config('*', {
on_attach = function(_, bufnr)
-- we create a function that lets us more easily define mappings specific
-- for LSP related items. It sets the mode, buffer and description for us each time.
local nmap = function(keys, func, desc)
if desc then
desc = 'LSP: ' .. desc
end
vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc })
end
nmap('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
nmap('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition')
nmap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition')
nmap('gr', function() Snacks.picker.lsp_references() end, '[G]oto [R]eferences')
nmap('gI', function() Snacks.picker.lsp_implementations() end, '[G]oto [I]mplementation')
nmap('<leader>ds', function() Snacks.picker.lsp_symbols() end, '[D]ocument [S]ymbols')
nmap('<leader>ws', function() Snacks.picker.lsp_workspace_symbols() end, '[W]orkspace [S]ymbols')
-- See `:help K` for why this keymap
nmap('K', vim.lsp.buf.hover, 'Hover Documentation')
nmap('<C-k>', vim.lsp.buf.signature_help, 'Signature Documentation')
-- Lesser used LSP functionality
nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
nmap('<leader>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder')
nmap('<leader>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder')
nmap('<leader>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, '[W]orkspace [L]ist Folders')
-- Create a command `:Format` local to the LSP buffer
vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_)
vim.lsp.buf.format()
end, { desc = 'Format current buffer with LSP' })
end
})
end,
},
{
"mason.nvim",
enabled = not nixInfo.isNix,
priority = 100, -- <- run lsp hook before lspconfig's hook
on_plugin = { "nvim-lspconfig" },
lsp = function(plugin)
vim.cmd.MasonInstall(plugin.name)
end,
},
{
-- lazydev makes your lua lsp load only the relevant definitions for a file.
-- It also gives us a nice way to correlate globals we create with files.
"lazydev.nvim",
auto_enable = true,
cmd = { "LazyDev" },
ft = "lua",
after = function(_)
require('lazydev').setup({
library = {
{ words = { "nixInfo%.lze" }, path = nixInfo("lze", "plugins", "start", "lze") .. '/lua', },
{ words = { "nixInfo%.lze" }, path = nixInfo("lzextras", "plugins", "start", "lzextras") .. '/lua' },
},
})
end,
},
{
-- name of the lsp
"lua_ls",
for_cat = "lua",
-- provide a table containing filetypes,
-- and then whatever your functions defined in the function type specs expect.
-- in our case, it just expects the normal lspconfig setup options,
-- but with a default on_attach and capabilities
lsp = {
-- if you provide the filetypes it doesn't ask lspconfig for the filetypes
-- (meaning it doesn't call the callback function we defined in the main init.lua)
filetypes = { 'lua' },
settings = {
Lua = {
signatureHelp = { enabled = true },
diagnostics = {
globals = { "nixInfo", "vim", },
disable = { 'missing-fields' },
},
},
},
},
-- also these are regular specs and you can use before and after and all the other normal fields
},
{
"nixd",
enabled = nixInfo.isNix, -- mason doesn't have nixd
for_cat = "nix",
lsp = {
filetypes = { "nix" },
settings = {
nixd = {
nixpkgs = {
expr = [[import <nixpkgs> {}]],
},
options = {
},
formatting = {
command = { "alejandra" }
},
diagnostic = {
suppress = {
"sema-escaping-with"
}
}
}
},
},
},
{
"nvim-treesitter",
lazy = false,
auto_enable = true,
after = function(plugin)
---@param buf integer
---@param language string
local function treesitter_try_attach(buf, language)
-- check if parser exists and load it
if not vim.treesitter.language.add(language) then
return false
end
-- enables syntax highlighting and other treesitter features
vim.treesitter.start(buf, language)
-- enables treesitter based folds
vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.wo.foldmethod = "expr"
-- ensure folds are open to begin with
vim.o.foldlevel = 99
-- enables treesitter based indentation
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
return true
end
local installable_parsers = require("nvim-treesitter").get_available()
vim.api.nvim_create_autocmd("FileType", {
callback = function(args)
local buf, filetype = args.buf, args.match
local language = vim.treesitter.language.get_lang(filetype)
if not language then
return
end
if not treesitter_try_attach(buf,language) then
if vim.tbl_contains(installable_parsers, language) then
-- not already installed, so try to install them via nvim-treesitter if possible
require("nvim-treesitter").install(language):await(function()
treesitter_try_attach(buf, language)
end)
end
end
end,
})
end,
},
{
"nvim-treesitter-textobjects",
auto_enable = true,
lazy = false,
before = function(plugin)
-- https://github.com/nvim-treesitter/nvim-treesitter-textobjects/tree/main?tab=readme-ov-file#using-a-package-manager
-- 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,
after = function(plugin)
require("nvim-treesitter-textobjects").setup {
select = {
-- Automatically jump forward to textobj, similar to targets.vim
lookahead = true,
-- You can choose the select mode (default is charwise 'v')
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * method: eg 'v' or 'o'
-- and should return the mode ('v', 'V', or '<c-v>') or a table
-- mapping query_strings to modes.
selection_modes = {
['@parameter.outer'] = 'v', -- charwise
['@function.outer'] = 'V', -- linewise
-- ['@class.outer'] = '<c-v>', -- blockwise
},
-- If you set this to `true` (default is `false`) then any textobject is
-- extended to include preceding or succeeding whitespace. Succeeding
-- whitespace has priority in order to act similarly to eg the built-in
-- `ap`.
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * selection_mode: eg 'v'
-- and should return true of false
include_surrounding_whitespace = false,
},
}
-- keymaps
-- You can use the capture groups defined in `textobjects.scm`
vim.keymap.set({ "x", "o" }, "am", function()
require "nvim-treesitter-textobjects.select".select_textobject("@function.outer", "textobjects")
end)
vim.keymap.set({ "x", "o" }, "im", function()
require "nvim-treesitter-textobjects.select".select_textobject("@function.inner", "textobjects")
end)
vim.keymap.set({ "x", "o" }, "ac", function()
require "nvim-treesitter-textobjects.select".select_textobject("@class.outer", "textobjects")
end)
vim.keymap.set({ "x", "o" }, "ic", function()
require "nvim-treesitter-textobjects.select".select_textobject("@class.inner", "textobjects")
end)
-- You can also use captures from other query groups like `locals.scm`
vim.keymap.set({ "x", "o" }, "as", function()
require "nvim-treesitter-textobjects.select".select_textobject("@local.scope", "locals")
end)
-- NOTE: for more textobjects options, see the following link.
-- This template is using the new `main` branch of the repo.
-- https://github.com/nvim-treesitter/nvim-treesitter-textobjects/tree/main
end,
},
{
"conform.nvim",
auto_enable = true,
-- cmd = { "" },
-- event = "",
-- ft = "",
keys = {
{ "<leader>FF", desc = "[F]ormat [F]ile" },
},
-- colorscheme = "",
after = function (plugin)
local conform = require("conform")
conform.setup({
formatters_by_ft = {
-- NOTE: download some formatters
-- and configure them here
lua = nixInfo(nil, "settings", "cats", "lua") and { "stylua" } or nil,
-- go = { "gofmt", "golint" },
-- templ = { "templ" },
-- Conform will run multiple formatters sequentially
-- python = { "isort", "black" },
-- Use a sub-list to run only the first available formatter
-- javascript = { { "prettierd", "prettier" } },
},
})
vim.keymap.set({ "n", "v" }, "<leader>FF", function()
conform.format({
lsp_fallback = true,
async = false,
timeout_ms = 1000,
})
end, { desc = "[F]ormat [F]ile" })
end,
},
{
"nvim-lint",
auto_enable = true,
-- cmd = { "" },
event = "FileType",
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function (plugin)
require('lint').linters_by_ft = {
-- NOTE: download some linters
-- and configure them here
-- markdown = {'vale',},
-- javascript = { 'eslint' },
-- typescript = { 'eslint' },
}
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
callback = function()
require("lint").try_lint()
end,
})
end,
},
{
"cmp-cmdline",
auto_enable = true,
on_plugin = { "blink.cmp" },
load = nixInfo.lze.loaders.with_after,
},
{
"blink.compat",
auto_enable = true,
dep_of = { "cmp-cmdline" },
},
{
"colorful-menu.nvim",
auto_enable = true,
on_plugin = { "blink.cmp" },
},
{
"blink.cmp",
auto_enable = true,
event = "DeferredUIEnter",
after = function (_)
require("blink.cmp").setup({
-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
-- See :h blink-cmp-config-keymap for configuring keymaps
keymap = {
preset = 'default',
},
cmdline = {
enabled = true,
completion = {
menu = {
auto_show = true,
},
},
sources = function()
local type = vim.fn.getcmdtype()
-- Search forward and backward
if type == '/' or type == '?' then return { 'buffer' } end
-- Commands
if type == ':' or type == '@' then return { 'cmdline', 'cmp_cmdline' } end
return {}
end,
},
fuzzy = {
sorts = {
'exact',
-- defaults
'score',
'sort_text',
},
},
signature = {
enabled = true,
window = {
show_documentation = true,
},
},
completion = {
menu = {
draw = {
treesitter = { 'lsp' },
components = {
label = {
text = function(ctx)
return require("colorful-menu").blink_components_text(ctx)
end,
highlight = function(ctx)
return require("colorful-menu").blink_components_highlight(ctx)
end,
},
},
},
},
documentation = {
auto_show = true,
},
},
sources = {
default = { 'lsp', 'path', 'buffer', 'omni' },
providers = {
path = {
score_offset = 50,
},
lsp = {
score_offset = 40,
},
cmp_cmdline = {
name = 'cmp_cmdline',
module = 'blink.compat.source',
score_offset = -100,
opts = {
cmp_name = 'cmdline',
},
},
},
},
})
end,
},
{
"nvim-surround",
auto_enable = true,
event = "DeferredUIEnter",
-- keys = "",
after = function(plugin)
require('nvim-surround').setup()
end,
},
{
"vim-startuptime",
auto_enable = true,
cmd = { "StartupTime" },
before = function(_)
vim.g.startuptime_event_width = 0
vim.g.startuptime_tries = 10
vim.g.startuptime_exe_path = nixInfo(vim.v.progpath, "progpath")
end,
},
{
"fidget.nvim",
auto_enable = true,
event = "DeferredUIEnter",
-- keys = "",
after = function(plugin)
require('fidget').setup({})
end,
},
{
"lualine.nvim",
auto_enable = true,
-- cmd = { "" },
event = "DeferredUIEnter",
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function (plugin)
require('lualine').setup({
options = {
icons_enabled = false,
theme = nixInfo("onedark_dark", "settings", "colorscheme"),
component_separators = '|',
section_separators = '',
},
sections = {
lualine_c = {
{ 'filename', path = 1, status = true, },
},
},
inactive_sections = {
lualine_b = {
{ 'filename', path = 3, status = true, },
},
lualine_x = {'filetype'},
},
tabline = {
lualine_a = { 'buffers' },
-- if you use lualine-lsp-progress, I have mine here instead of fidget
-- lualine_b = { 'lsp_progress', },
lualine_z = { 'tabs' }
},
})
end,
},
{
"gitsigns.nvim",
auto_enable = true,
event = "DeferredUIEnter",
-- cmd = { "" },
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function (plugin)
require('gitsigns').setup({
-- See `:help gitsigns.txt`
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '~' },
},
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
-- Navigation
map({ 'n', 'v' }, ']c', function()
if vim.wo.diff then
return ']c'
end
vim.schedule(function()
gs.next_hunk()
end)
return '<Ignore>'
end, { expr = true, desc = 'Jump to next hunk' })
map({ 'n', 'v' }, '[c', function()
if vim.wo.diff then
return '[c'
end
vim.schedule(function()
gs.prev_hunk()
end)
return '<Ignore>'
end, { expr = true, desc = 'Jump to previous hunk' })
-- Actions
-- visual mode
map('v', '<leader>hs', function()
gs.stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'stage git hunk' })
map('v', '<leader>hr', function()
gs.reset_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'reset git hunk' })
-- normal mode
map('n', '<leader>gs', gs.stage_hunk, { desc = 'git stage hunk' })
map('n', '<leader>gr', gs.reset_hunk, { desc = 'git reset hunk' })
map('n', '<leader>gS', gs.stage_buffer, { desc = 'git Stage buffer' })
map('n', '<leader>gu', gs.undo_stage_hunk, { desc = 'undo stage hunk' })
map('n', '<leader>gR', gs.reset_buffer, { desc = 'git Reset buffer' })
map('n', '<leader>gp', gs.preview_hunk, { desc = 'preview git hunk' })
map('n', '<leader>gb', function()
gs.blame_line { full = false }
end, { desc = 'git blame line' })
map('n', '<leader>gd', gs.diffthis, { desc = 'git diff against index' })
map('n', '<leader>gD', function()
gs.diffthis '~'
end, { desc = 'git diff against last commit' })
-- Toggles
map('n', '<leader>gtb', gs.toggle_current_line_blame, { desc = 'toggle git blame line' })
map('n', '<leader>gtd', gs.toggle_deleted, { desc = 'toggle git show deleted' })
-- Text object
map({ 'o', 'x' }, 'ih', ':<C-U>Gitsigns select_hunk<CR>', { desc = 'select git hunk' })
end,
})
vim.cmd([[hi GitSignsAdd guifg=#04de21]])
vim.cmd([[hi GitSignsChange guifg=#83fce6]])
vim.cmd([[hi GitSignsDelete guifg=#fa2525]])
end,
},
{
"which-key.nvim",
auto_enable = true,
-- cmd = { "" },
event = "DeferredUIEnter",
-- ft = "",
-- keys = "",
-- colorscheme = "",
after = function (plugin)
require('which-key').setup({
})
require('which-key').add {
{ "<leader><leader>", group = "buffer commands" },
{ "<leader><leader>_", hidden = true },
{ "<leader>c", group = "[c]ode" },
{ "<leader>c_", hidden = true },
{ "<leader>d", group = "[d]ocument" },
{ "<leader>d_", hidden = true },
{ "<leader>g", group = "[g]it" },
{ "<leader>g_", hidden = true },
{ "<leader>m", group = "[m]arkdown" },
{ "<leader>m_", hidden = true },
{ "<leader>r", group = "[r]ename" },
{ "<leader>r_", hidden = true },
{ "<leader>s", group = "[s]earch" },
{ "<leader>s_", hidden = true },
{ "<leader>t", group = "[t]oggles" },
{ "<leader>t_", hidden = true },
{ "<leader>w", group = "[w]orkspace" },
{ "<leader>w_", hidden = true },
}
end,
},
}