ported the lua, port is complete, I think.

This commit is contained in:
Gabe Venberg 2026-03-13 15:47:42 +01:00
parent 7c9d33f7bb
commit 24a7f2cda3
26 changed files with 810 additions and 868 deletions

View file

@ -1,89 +1,3 @@
# Neovim module # Neovim module
This is a demonstration of the [neovim module](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html) A wrapper around nvim that includes the plugins I use day to day.
It makes use of the tips in the [tips and tricks](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html#tips-and-tricks) section of the documentation.
This template configuration is by no means a perfect, complete configuration.
However, it is plenty to start on, and covers some interesting ways to use the module (and how to lazily load plugins and config).
This configuration is 1 `lua` file, however the whole set of directories from a normal `neovim` configuration directory are available.
To see what directories you can put stuff in, see: [:help 'rtp'](https://neovim.io/doc/user/options.html#'rtp')
The main reason it is in 1 file is that it is following the style of [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim).
The other reason it is in 1 file, is that it makes it a cleaner experience to init this template into an existing configuration.
This template config uses [lze](https://github.com/BirdeeHub/lze) for lazy loading of the configuration.
You may also be interested in [lz.n](https://github.com/lumen-oss/lz.n) for this purpose.
Both achieve the same general result and main interface,
but have different underlying implementations and thus have different handler features.
Both are fantastic for lazy loading with both nix and the builtin plugin manager.
You may also decide you don't need lazy loading at all. This is fine, many plugins mostly handle that themselves.
To initialize this template flake into the current directory, run:
```bash
nix flake init -t github:BirdeeHub/nix-wrapper-modules#neovim
```
It will not replace existing files.
If you are using `zsh` you may need to escape the `#`
To build it from that directory
```bash
nix build .
```
It exports a package! (and other things)
If you don't want your config in a separate flake, just call the `module.nix` file like:
```nix
inputs: # <-- get the library somehow
{ pkgs, ... }: {
# call the module and install the package (nixos example)
environment.systemPackages = [ (inputs.nix-wrapper-modules.lib.evalPackage [ ./module.nix { inherit pkgs; } ]) ];
}
```
There are a lot of other ways to install it as well, see [the getting started documentation](https://birdeehub.github.io/nix-wrapper-modules/md/getting-started.html)
You may also wish to view the `flake.nix` of this template, as it demonstrates some of those things when setting up its outputs.
---
The nix in this template is not as simple as it could possibly be, as it demonstrates some things
from the [tips and tricks](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html#tips-and-tricks) section of the documentation.
If you wanted as simple as possible, you could use something more like the following as your `module.nix`
```nix
{ wlib, config, pkgs, lib, ... }:
imports = [ wlib.wrapperModules.neovim ];
specs.general = with pkgs.vimPlugins; [
# plugins which are loaded at startup ...
];
specs.lazy = {
lazy = true;
data = with pkgs.vimPlugins; [
# plugins which are not loaded until you vim.cmd.packadd them ...
];
};
extraPackages = with pkgs; [
# lsps, formatters, etc...
];
settings.config_directory = ./.; # or lib.generators.mkLuaInline "vim.fn.stdpath('config')";
}
```
At the same time, you may find that the `module.nix` file from this template is not massively more complex than that either,
and contains some useful tricks and information.

24
flake.lock generated
View file

@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1772674223, "lastModified": 1773231277,
"narHash": "sha256-/suKbHSaSmuC9UY7G0VRQ3aO+QKqxAQPQ19wG7QNkF8=", "narHash": "sha256-Xy3WEpUAbpsz8ydgvVAQAGGB/WB+8cNA5cshiL0McTI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "66d9241e3dc2296726dc522e62dbfe89c7b449f3", "rev": "75690239f08f885ca9b0267580101f60d10fbe62",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -19,11 +19,11 @@
"plugins-lze": { "plugins-lze": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1772337062, "lastModified": 1772949858,
"narHash": "sha256-joi1087b2iDmwOHv7/0YCrDPucbu0osbS8WQmDYoyE4=", "narHash": "sha256-skLhmn/MvxOZbrBiceF/xiLRRmmEs6ZQS2sGrBrUyLU=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "lze", "repo": "lze",
"rev": "f50a84a5d84f6b16e254091e755f5a9e839a9924", "rev": "a3ba1a2d469d4ab26acb629aba8c7d70a6cbe558",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -35,11 +35,11 @@
"plugins-lzextras": { "plugins-lzextras": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1772336997, "lastModified": 1772949841,
"narHash": "sha256-BsoZTfXpISPeTnTQWtnZkDXzvo9ocILB5IO2vU8IvAM=", "narHash": "sha256-MQ1h2R5axM3u6mLNTDzXF/40o8+U0JOWb48UTQO9jfc=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "lzextras", "repo": "lzextras",
"rev": "abdda956a2947d0617133a018992d035fc5781da", "rev": "a6ac9a7bee380881af2dfbfd238ccb1697d677d7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -63,11 +63,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1772662098, "lastModified": 1773360496,
"narHash": "sha256-BKxBM4RNWP+5q0ZQ6v3JlJ0e6fFj/YoYNZ7/OpgabdU=", "narHash": "sha256-AQN5UhIc2WHvELT4TWIsD1W05ksLXWRkS5NjPm3jkc0=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "nix-wrapper-modules", "repo": "nix-wrapper-modules",
"rev": "2c0a3b795766b25d15ad1ec9eef3a06160154c9a", "rev": "8f1770c6d58a89a4757849713c0e6d9ace7b4ac3",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,6 +1,5 @@
-- NOTE: Welcome to your neovim configuration!
-- The first 100ish lines are setup, -- The first 100ish lines are setup,
-- the rest is usage of lze and various core plugins! -- the rest is usage of require(vim.g.nix_info_plugin_name)lze and various core plugins!
vim.loader.enable() -- <- bytecode caching vim.loader.enable() -- <- bytecode caching
do do
-- Set up a global in a way that also handles non-nix compat -- Set up a global in a way that also handles non-nix compat
@ -17,9 +16,9 @@ do
-- TODO: for non-nix compat, vim.pack.add in another file and require here. -- TODO: for non-nix compat, vim.pack.add in another file and require here.
end end
nixInfo.isNix = vim.g.nix_info_plugin_name ~= nil nixInfo.isNix = vim.g.nix_info_plugin_name ~= nil
---@module 'lzextras' ---@module "lzextras"
---@type lzextras | lze ---@type lzextras | lze
nixInfo.lze = setmetatable(require('lze'), getmetatable(require('lzextras'))) nixInfo.lze = setmetatable(require("lze"), getmetatable(require("lzextras")))
function nixInfo.get_nix_plugin_path(name) function nixInfo.get_nix_plugin_path(name)
return nixInfo(nil, "plugins", "lazy", name) or nixInfo(nil, "plugins", "start", name) return nixInfo(nil, "plugins", "lazy", name) or nixInfo(nil, "plugins", "start", name)
end end
@ -78,7 +77,7 @@ nixInfo.lze.register_handlers {
-- NOTE: This config uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler -- NOTE: This config uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler
-- Because we have the paths, we can set a more performant fallback function -- Because we have the paths, we can set a more performant fallback function
-- for when you don't provide a filetype to trigger on yourself. -- for when you don"t provide a filetype to trigger on yourself.
-- If you do provide a filetype, this will never be called. -- If you do provide a filetype, this will never be called.
nixInfo.lze.h.lsp.set_ft_fallback(function(name) nixInfo.lze.h.lsp.set_ft_fallback(function(name)
local lspcfg = nixInfo.get_nix_plugin_path "nvim-lspconfig" local lspcfg = nixInfo.get_nix_plugin_path "nvim-lspconfig"
@ -91,6 +90,7 @@ nixInfo.lze.h.lsp.set_ft_fallback(function(name)
end end
end) end)
require('opts') require("opts")
require('keys') require("keys")
require('plugins') require("plugins")
require("lsp")

View file

@ -2,8 +2,8 @@
-- Keymaps for better default experience -- Keymaps for better default experience
-- See `:help vim.keymap.set()` -- See `:help vim.keymap.set()`
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv", { desc = 'Moves Line Down' }) 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("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-d>", "<C-d>zz", { desc = 'Scroll Down' })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = 'Scroll Up' }) 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 = 'Next Search Result' })

7
lua/lsp/C.lua Normal file
View file

@ -0,0 +1,7 @@
return {
{
"clangd",
for_cat = "C",
lsp = {},
},
}

7
lua/lsp/bash.lua Normal file
View file

@ -0,0 +1,7 @@
return {
{
"bashls",
for_cat = "bash",
lsp = {},
},
}

92
lua/lsp/init.lua Normal file
View file

@ -0,0 +1,92 @@
local lspEnabled = nixInfo("settings", "cat", "lsp")
if lspEnabled then
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,
})
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,
},
{ import = "lsp.lua" },
{ import = "lsp.python" },
{ import = "lsp.C" },
{ import = "lsp.nix" },
{ import = "lsp.typst" },
{ import = "lsp.bash" },
{ import = "lsp.zk" },
{ import = "lsp.rust" },
}

45
lua/lsp/lua.lua Normal file
View file

@ -0,0 +1,45 @@
return {
{
-- lazydev makes your lsp way better in your config without needing extra lsp configuration.
"lazydev.nvim",
for_cat = "lua",
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
filetypes = { 'lua' },
settings = {
Lua = {
runtime = { version = 'LuaJIT' },
formatters = {
ignoreComments = true,
},
signatureHelp = { enabled = true },
diagnostics = {
globals = { "nixInfo", "vim", },
disable = { 'missing-fields' },
},
telemetry = { enabled = false },
},
},
},
},
}

27
lua/lsp/nix.lua Normal file
View file

@ -0,0 +1,27 @@
return {
{
"nixd",
enabled = nixInfo.isNix, -- mason doesn't have nixd
for_cat = "nix",
lsp = {
filetypes = { "nix" },
settings = {
nixd = {
nixpkgs = {
expr = [[import <nixpkgs> {}]],
},
options = {
},
formatting = {
command = { "nixfmt" }
},
diagnostic = {
suppress = {
"sema-escaping-with"
}
}
}
},
},
},
}

12
lua/lsp/python.lua Normal file
View file

@ -0,0 +1,12 @@
return {
{
"ty",
for_cat = "python",
lsp = {},
},
{
"ruff",
for_cat = "python",
lsp = {},
},
}

6
lua/lsp/rust.lua Normal file
View file

@ -0,0 +1,6 @@
return {
{
"rustaceanvim",
for_cat = "rust",
},
}

13
lua/lsp/typst.lua Normal file
View file

@ -0,0 +1,13 @@
return {
{
"tinymist",
for_cat = "typst",
lsp = {
filetypes = { "typst" },
settings = {
formatterMode = "typstyle",
},
},
},
}

23
lua/lsp/zk.lua Normal file
View file

@ -0,0 +1,23 @@
return {
{
"zk-nvim",
for_cat = "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,6 +1,6 @@
-- NOTE: These 2 should be set up before any plugins with keybinds are loaded. -- NOTE: These 2 should be set up before any plugins with keybinds are loaded.
vim.g.mapleader = ';' vim.g.mapleader = ";"
vim.g.maplocalleader = ';' vim.g.maplocalleader = ";"
-- [[ Setting options ]] -- [[ Setting options ]]
-- See `:help vim.o` -- See `:help vim.o`
@ -10,9 +10,9 @@ vim.g.maplocalleader = ';'
vim.o.exrc = false -- can be toggled off in that file to stop it from searching further 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. -- Sets how neovim will display certain whitespace characters in the editor.
-- See `:help 'list'` -- See `:help "list"`
-- and `:help 'listchars'` -- and `:help "listchars"`
-- and `:help 'showbreak'` -- and `:help "showbreak"`
vim.opt.list = true vim.opt.list = true
vim.opt.listchars = { eol = "", extends = "", nbsp = "", precedes = "", tab = ">-", trail = "" } vim.opt.listchars = { eol = "", extends = "", nbsp = "", precedes = "", tab = ">-", trail = "" }
vim.opt.showbreak = ""; vim.opt.showbreak = "";
@ -20,10 +20,10 @@ vim.opt.showbreak = "↪";
-- Set highlight on search -- Set highlight on search
vim.opt.hlsearch = true vim.opt.hlsearch = true
vim.opt.incsearch = true vim.opt.incsearch = true
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>') vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- Preview substitutions live, as you type! -- Preview substitutions live, as you type!
vim.opt.inccommand = 'split' vim.opt.inccommand = "split"
-- Automatically load changed files -- Automatically load changed files
vim.opt.autoread = true vim.opt.autoread = true
@ -36,7 +36,7 @@ vim.opt.number = true
vim.opt.numberwidth = 3 vim.opt.numberwidth = 3
-- Enable mouse mode -- Enable mouse mode
vim.opt.mouse = 'a' vim.opt.mouse = "a"
-- no hard wrapping -- no hard wrapping
vim.opt.textwidth = 0 vim.opt.textwidth = 0
@ -62,7 +62,7 @@ vim.opt.ignorecase = true
vim.opt.smartcase = true vim.opt.smartcase = true
-- Keep signcolumn on by default -- Keep signcolumn on by default
vim.opt.signcolumn = 'yes' vim.opt.signcolumn = "yes"
vim.opt.relativenumber = true vim.opt.relativenumber = true
-- Decrease update time -- Decrease update time
@ -70,7 +70,7 @@ vim.opt.updatetime = 250
vim.opt.timeoutlen = 300 vim.opt.timeoutlen = 300
-- Set completeopt to have a better completion experience -- Set completeopt to have a better completion experience
vim.opt.completeopt = { 'menu', 'preview', 'noselect' } vim.opt.completeopt = { "menu", "preview", "noselect" }
vim.opt.termguicolors = true vim.opt.termguicolors = true
@ -85,13 +85,13 @@ vim.opt.formatoptions = "rojq"
-- [[ Highlight on yank ]] -- [[ Highlight on yank ]]
-- See `:help vim.highlight.on_yank()` -- See `:help vim.highlight.on_yank()`
local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }) local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true })
vim.api.nvim_create_autocmd('TextYankPost', { vim.api.nvim_create_autocmd("TextYankPost", {
callback = function() callback = function()
vim.highlight.on_yank() vim.highlight.on_yank()
end, end,
group = highlight_group, group = highlight_group,
pattern = '*', pattern = "*",
}) })
vim.g.netrw_liststyle = 0 vim.g.netrw_liststyle = 0

View file

@ -1,743 +0,0 @@
-- 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,
},
}

156
lua/plugins/completion.lua Normal file
View file

@ -0,0 +1,156 @@
local load_w_after = function(name)
vim.cmd.packadd(name)
vim.cmd.packadd(name .. '/after')
end
return {
{
"cmp-cmdline",
for_cat = "lazy",
on_plugin = { "blink.cmp" },
load = load_w_after,
},
{
"blink.compat",
for_cat = "lazy",
dep_of = { "cmp-cmdline" },
},
{
"luasnip",
for_cat = "lazy",
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 = "lazy",
on_plugin = { "blink.cmp" },
},
{
"blink-emoji.nvim",
for_cat = "lazy",
on_plugin = { "blink.cmp" },
},
{
"blink.cmp",
for_cat = "lazy",
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,
},
}

86
lua/plugins/gitsigns.lua Normal file
View file

@ -0,0 +1,86 @@
return {
{
"gitsigns.nvim",
for_cat = 'lazy',
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,
},
}

39
lua/plugins/init.lua Normal file
View file

@ -0,0 +1,39 @@
local colorschemeName = nixInfo("retrobox", "settings", "colorscheme")
vim.cmd.colorscheme(colorschemeName)
require("plugins.lualine")
require("plugins.oil")
require("plugins.snacks")
require('lze').load {
{ import = "plugins.treesitter", },
{ import = "plugins.gitsigns", },
{ import = "plugins.which-key", },
{ import = "plugins.completion", },
{ import = "plugins.preview.markdown", },
{ import = "plugins.preview.typst", },
{
"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
},
}

36
lua/plugins/lualine.lua Normal file
View file

@ -0,0 +1,36 @@
-- lualine
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 } }
},
})
-- marks.nvim
require("marks").setup({})

45
lua/plugins/oil.lua Normal file
View file

@ -0,0 +1,45 @@
-- oil.nvim
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",
},
})
-- 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,
})
-- oil keybinds
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" })

View file

@ -0,0 +1,19 @@
return {
"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,
}

View file

@ -0,0 +1,14 @@
return {
"typst-preview.nvim",
for_cat = "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
}

87
lua/plugins/snacks.lua Normal file
View file

@ -0,0 +1,87 @@
-- snacks.nvim setup
require("snacks").setup({
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 = true, configure = false },
})
-- 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" })
-- double tap escape leaves terminal mode
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" })

View file

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

22
lua/plugins/which-key.lua Normal file
View file

@ -0,0 +1,22 @@
return {
{
"which-key.nvim",
for_cat = 'lazy',
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

@ -38,7 +38,7 @@ inputs: {
# You can declare your own options! # You can declare your own options!
options.settings.colorscheme = lib.mkOption { options.settings.colorscheme = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "onedark_dark"; default = "gruvbox";
}; };
options.settings.minimal = lib.mkOption { options.settings.minimal = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
@ -47,7 +47,6 @@ inputs: {
config.settings.colorscheme = "gruvbox"; # <- just demonstrating that it is an option config.settings.colorscheme = "gruvbox"; # <- just demonstrating that it is an option
# and grab it in lua with `require(vim.g.nix_info_plugin_name)("onedark", "settings", "colorscheme") == "moonfly"` # and grab it in lua with `require(vim.g.nix_info_plugin_name)("onedark", "settings", "colorscheme") == "moonfly"`
config.specs.colorscheme = { config.specs.colorscheme = {
lazy = true;
enable = lib.mkIf config.settings.minimal (lib.mkDefault true); enable = lib.mkIf config.settings.minimal (lib.mkDefault true);
data = builtins.getAttr config.settings.colorscheme ( data = builtins.getAttr config.settings.colorscheme (
with pkgs.vimPlugins; { with pkgs.vimPlugins; {
@ -82,6 +81,7 @@ inputs: {
fzf fzf
zoxide zoxide
git git
delta
lazygit lazygit
tree-sitter tree-sitter
]; ];
@ -93,7 +93,6 @@ inputs: {
oil-nvim oil-nvim
nvim-web-devicons nvim-web-devicons
nvim-numbertoggle nvim-numbertoggle
lualine-nvim
marks-nvim marks-nvim
]; ];
}; };