refactor neovim config

This commit is contained in:
Murphy 2025-02-05 13:13:14 -05:00
parent 0f2ef46b80
commit 463220c485
Signed by: freya
GPG key ID: 9FBC6FFD6D2DBF17
2 changed files with 519 additions and 319 deletions
nix/programs/neovim

View file

@ -1,84 +1,530 @@
{ config, lib, pkgs, ... }:
let
with lib;
colorschemeLua = ''
-- [[ COLORSCHEME ]] --
local colorscheme = require('base16-colorscheme')
colorscheme.setup({
base00 = '#${config.theme.colors.base00}',
base01 = '#${config.theme.colors.base01}',
base02 = '#${config.theme.colors.base02}',
base03 = '#${config.theme.colors.base03}',
base04 = '#${config.theme.colors.base04}',
base05 = '#${config.theme.colors.base05}',
base06 = '#${config.theme.colors.base06}',
base07 = '#${config.theme.colors.base07}',
base08 = '#${config.theme.colors.base08}',
base09 = '#${config.theme.colors.base09}',
base0A = '#${config.theme.colors.base0A}',
base0B = '#${config.theme.colors.base0B}',
base0C = '#${config.theme.colors.base0C}',
base0D = '#${config.theme.colors.base0D}',
base0E = '#${config.theme.colors.base0E}',
base0F = '#${config.theme.colors.base0F}',
})
'';
initLua = lib.fileContents ./init.lua;
luaConfig = colorschemeLua + initLua;
in
{
environment.variables.EDITOR = "nvim";
options = {
neovim = {
home-manager.users.${config.user} = {
programs.neovim = {
tabWidth = mkOption {
type = types.int;
description = "Width of tabes in the editor.";
default = 4;
};
expandTab = mkOption {
type = types.bool;
description = "If tabs should be expanded to spaces.";
default = false;
};
enable = true;
viAlias = true;
vimAlias = true;
extraLuaConfig = luaConfig;
keys = {
leader = mkOption {
type = types.str;
description = "NeoVIM leader key";
default = " ";
};
noh = mkOption {
type = types.str;
description = "Keybind to remove active hilighted content.";
default = "<leader>h";
};
plugins = with pkgs.vimPlugins; [
# Deoendencies
vim-devicons
nvim-web-devicons
# Lua functions
plenary-nvim
# Lines
lualine-nvim # mode line
bufferline-nvim # buffer line
# Menus
nvim-tree-lua # file browser
undotree # undo menu
trouble-nvim # error menu
telescope-nvim # grep/find menus
# Snippets
vim-vsnip
vim-vsnip-integ
friendly-snippets
# Completion
nvim-cmp
cmp-buffer
cmp-nvim-lsp
cmp-vsnip
nvim-surround # delimiter
# Lsp
base16-nvim # colorscheme
nerdcommenter # comment functions
nvim-treesitter.withAllGrammars # hilighting
vim-illuminate # hilighting
todo-comments-nvim # todo comments
nvim-lspconfig # lsp server
fidget-nvim # notifications
indent-o-matic # auto indentation
hologram-nvim # images
virt-column-nvim # 80 col line
];
menus = {
# file browser
browser = mkOption {
type = types.str;
description = "Keybind to open file browser.";
default = "<leader>e";
};
# active buffers
buffers = mkOption {
type = types.str;
description = "Keybind to show active buffers.";
default = "<leader>fb";
};
# error list
error = mkOption {
type = types.str;
description = "Keybind to show LSP errors.";
default = "<leader>t";
};
# find files
find = mkOption {
type = types.str;
description = "Keybind to search files in working directory.";
default = "<leader>ff";
};
# grep files
grep = mkOption {
type = types.str;
description = "Keybind to grep files in working directory.";
default = "<leader>fg";
};
# help menu
help = mkOption {
type = types.str;
description = "Keybind to search help menus.";
default = "<leader>fh";
};
# undo tree
undo = mkOption {
type = types.str;
description = "Keybind to view undo tree.";
default = "<leader>u";
};
};
# lsp actions
lsp = {
hover = mkOption {
type = types.str;
description = "Keybind to open LSP hover menu on a value.";
default = "K";
};
action = mkOption {
type = types.str;
description = "Keybind to perform an LSP action on a value.";
default = "<leader>la";
};
references = mkOption {
type = types.str;
description = "Keybind to view all references of a value.";
default = "<leader>lr";
};
rename = mkOption {
type = types.str;
description = "Keybind to rename currrent and all references of a value.";
default = "<leader>ln";
};
};
# completion
cmp = {
prev = mkOption {
type = types.str;
description = "Keybind to select previous value in completion engine.";
default = "<C-p>";
};
next = mkOption {
type = types.str;
description = "Keybind to select next value in completion engine.";
default = "<C-n>";
};
confirm = mkOption {
type = types.str;
description = "Keybind to confirm current value in completion engine.";
default = "<CR>";
};
complete = mkOption {
type = types.str;
description = "Keybind to auto complete using completion engine.";
default = "<C-space>";
};
};
};
# active lsp servers
lsps = mkOption {
type = with types; listOf str;
description = "List of lsp servers to load";
default = ["clangd" "rust_analyzer"];
};
};
};
config = {
environment.variables.EDITOR = "nvim";
home-manager.users.${config.user} = {
programs.neovim = {
enable = true;
viAlias = true;
vimAlias = true;
extraLuaConfig = ''
--[[ VIM ]]--
vim.opt.tabstop = ${toString config.neovim.tabWidth}
vim.opt.softtabstop = ${toString config.neovim.tabWidth}
vim.opt.shiftwidth = ${toString config.neovim.tabWidth}
vim.opt.expandtab = ${boolToString config.neovim.expandTab}
vim.opt.mouse = "a"
vim.opt.clipboard = "unnamedplus"
vim.opt.hlsearch = true
vim.opt.autoindent = true
vim.opt.ttyfast = true
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.rnu = true
vim.opt.swapfile = false
--[[ BUF ]]--
-- remove trailing whitespace on save
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = { "*" },
command = [[%s/\s\+$//e]],
})
--[[ KEYBINDS ]]--
-- leader
vim.g.mapleader = "${config.neovim.keys.leader}"
vim.g.maplocalleader = "${config.neovim.keys.leader}"
vim.keymap.set("", '<leader>', '<Nop>', { noremap = true, silent = true })
-- bind helper function
local function bind(key, action, opts)
opts = opts or {}
vim.keymap.set('n', key, action, opts)
end
-- lsp
bind("${config.neovim.keys.noh}", vim.cmd.noh)
vim.api.nvim_create_autocmd('LspAttach', {
desc = 'LSP actions',
callback = function(event)
local opts = {buffer = event.buf}
bind("${config.neovim.keys.lsp.hover}", function() vim.lsp.buf.hover() end, opts)
bind("${config.neovim.keys.lsp.action}", function() vim.lsp.buf.code_action() end, opts)
bind("${config.neovim.keys.lsp.references}", function() vim.lsp.buf.references() end, opts)
bind("${config.neovim.keys.lsp.rename}", function() vim.lsp.buf.rename() end, opts)
end
})
'';
plugins = with pkgs.vimPlugins; [
# Deoendencies
vim-devicons
nvim-web-devicons
plenary-nvim
# Colorscheme
{
plugin = base16-nvim;
type = "lua";
config = ''
vim.opt.termguicolors = true
vim.g.base16_transparent_background = 1
local colorscheme = require('base16-colorscheme')
colorscheme.setup({
base00 = '#${config.theme.colors.base00}',
base01 = '#${config.theme.colors.base01}',
base02 = '#${config.theme.colors.base02}',
base03 = '#${config.theme.colors.base03}',
base04 = '#${config.theme.colors.base04}',
base05 = '#${config.theme.colors.base05}',
base06 = '#${config.theme.colors.base06}',
base07 = '#${config.theme.colors.base07}',
base08 = '#${config.theme.colors.base08}',
base09 = '#${config.theme.colors.base09}',
base0A = '#${config.theme.colors.base0A}',
base0B = '#${config.theme.colors.base0B}',
base0C = '#${config.theme.colors.base0C}',
base0D = '#${config.theme.colors.base0D}',
base0E = '#${config.theme.colors.base0E}',
base0F = '#${config.theme.colors.base0F}',
})
-- make transparent background
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" })
vim.api.nvim_set_hl(0, 'EndOfBuffer', { bg = "none" })
-- identifiers should not be colored
vim.api.nvim_set_hl(0, "Identifier", { fg = "#${config.theme.colors.base05}" })
vim.api.nvim_set_hl(0, "TSVariable", { fg = "#${config.theme.colors.base05}" })
-- macro should be colored as a keyword
vim.api.nvim_set_hl(0, "TSFuncMacro", { fg = "#${config.theme.colors.base0E}" })
-- comments are too dark
vim.api.nvim_set_hl(0, "Comment", { fg = "#${config.theme.colors.base07}" })
vim.api.nvim_set_hl(0, "@comment", { link = "Comment" })
'';
}
# Mode line
{
plugin = lualine-nvim;
type = "lua";
config = ''
require('lualine').setup {
options = {
theme = 'base16',
icons_enabled = true,
globalstatus = true,
},
};
'';
}
# Buffer line
{
plugin = bufferline-nvim;
type = "lua";
config = ''
require('bufferline').setup {}
'';
}
# File browser
{
plugin = nvim-tree-lua;
type = "lua";
config = ''
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
require('nvim-tree').setup {
sort = {
sorter = "case_sensitive",
},
view = {
centralize_selection = true,
signcolumn = "yes",
float = {
enable = true,
quit_on_focus_loss = true,
open_win_config = {
relative = "editor",
border = "rounded",
width = 60,
height = 20,
row = 1,
col = 1,
},
};
},
renderer = {
group_empty = true,
},
actions = {
use_system_clipboard = true,
change_dir = {
enable = true,
global = false,
restrict_above_cwd = false,
},
expand_all = {
max_folder_discovery = 300,
exclude = {},
},
file_popup = {
open_win_config = {
col = 1,
row = 1,
relative = "cursor",
border = "shadow",
style = "minimal",
},
},
open_file = {
quit_on_open = true,
window_picker = {
enable = false,
picker = "default",
chars = "abcdefghijklmnopqrstuvwxyz1234567890",
exclude = {
filetype = { "notify", "lazy", "qf", "diff", "fugitive", "fugitiveblame" },
buftype = { "nofile", "terminal", "help" },
},
}
},
remove_file = {
close_window = true,
},
},
filters = {
dotfiles = false,
},
tab = {
sync = {
open = false,
close = false,
ignore = {},
},
},
git = {
enable = false,
},
update_cwd = true,
respect_buf_cwd = true,
update_focused_file = {
enable = true,
update_cwd = true
},
};
bind("${config.neovim.keys.menus.browser}", vim.cmd.NvimTreeToggle)
'';
}
# Undo tree
{
plugin = undotree;
type = "lua";
config = ''
bind("${config.neovim.keys.menus.undo}", vim.cmd.UndotreeToggle)
'';
}
# Trouble (error menu)
{
plugin = trouble-nvim;
type = "lua";
config = ''
bind("${config.neovim.keys.menus.error}", function() require('trouble').toggle() end)
'';
}
# Telescope (buffers/find/grep/help)
{
plugin = telescope-nvim;
type = "lua";
config = ''
local telescope = require('telescope.builtin')
bind("${config.neovim.keys.menus.buffers}", telescope.buffers)
bind("${config.neovim.keys.menus.find}", telescope.find_files)
bind("${config.neovim.keys.menus.grep}", telescope.live_grep)
bind("${config.neovim.keys.menus.help}", telescope.help_tags)
vim.api.nvim_set_hl(0, 'TelescopeNormal', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopeBorder', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopeResultsTitle', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopePromptTitle', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopePreviewTitle', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopePromptNormal', { bg = "none" })
vim.api.nvim_set_hl(0, 'TelescopePromptBorder', { bg = "none" })
'';
}
# Snippets
vim-vsnip
vim-vsnip-integ
friendly-snippets
# Completion
cmp-buffer
cmp-nvim-lsp
cmp-vsnip
{
plugin = nvim-cmp;
type = "lua";
config = ''
local cmp = require('cmp');
local cmp_select = {behavior = cmp.SelectBehavior.select}
local cmp_mappings = cmp.mapping.preset.insert({
["${config.neovim.keys.cmp.prev}"] = cmp.mapping.select_prev_item(cmp_select),
["${config.neovim.keys.cmp.next}"] = cmp.mapping.select_next_item(cmp_select),
["${config.neovim.keys.cmp.confirm}"] = cmp.mapping.confirm({ select = true }),
["${config.neovim.keys.cmp.complete}"] = cmp.mapping.complete(),
})
cmp_mappings['<Tab>'] = nil
cmp_mappings['<S-Tab>'] = nil
cmp.setup {
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
sources = cmp.config.sources {
{ name = 'nvim_lsp' },
{ name = 'vsnip' },
{ name = 'buffer' },
},
mapping = cmp_mappings,
}
'';
}
# Sourround delimiters
{
plugin = nvim-surround;
type = "lua";
config = ''
require('nvim-surround').setup {}
'';
}
# Comment functions
nerdcommenter
# Treesitter
nvim-treesitter.withAllGrammars
# Syntax hilighting
{
plugin = vim-illuminate;
type = "lua";
config = ''
require('illuminate').configure {
providers = {
'lsp',
'treesitter',
'regex',
},
}
'';
}
# Todo comments
{
plugin = todo-comments-nvim;
type = "lua";
config = ''
require('todo-comments').setup()
'';
}
# Lsp server
{
plugin = nvim-lspconfig;
type = "lua";
config = let
lspConfigs = map (server: ''
lspconfig["${server}"].setup({
capabilities = capabilities
})
'') config.neovim.lsps;
in ''
local lspconfig = require('lspconfig')
local capabilities = require'cmp_nvim_lsp'.default_capabilities()
${lib.concatStrings lspConfigs}
'';
}
# Notifications
{
plugin = fidget-nvim;
type = "lua";
config = ''
require("fidget").setup {
notification = {
window = {
winblend = 0,
},
},
}
'';
}
# Auto indentation
{
plugin = indent-o-matic;
type = "lua";
config = ''
require('indent-o-matic').setup {
max_lines = 2048,
standard_widths = { 2, 4, 8 },
skip_multiline = true,
};
'';
}
# 80 column width
{
plugin = virt-column-nvim;
type = "lua";
config = ''
require('virt-column').setup {
enabled = true,
virtcolumn = "80"
}
'';
}
];
};
};
};
}

View file

@ -1,246 +0,0 @@
--[[ CONFIG ]]--
-- global config for iris configuration
config = {
-- colorscheme for nvim
flavour = "mocha",
-- indentation
tab_width = 4,
expand_tab = false,
-- keybinds to be set to actions
keybinds = {
-- leader key
leader = ' ',
-- toggle menus
menus = {
-- file browser
browser = '<leader>e',
-- active buffers
buffers = '<leader>fb',
-- error list
error = '<leader>t',
-- find files
find = '<leader>ff',
-- grep files
grep = '<leader>fg',
-- help browser
help = '<leader>fh',
-- undo tree
undo = '<leader>u',
},
-- lsp actions
lsp = {
hover = 'K',
action = '<leader>la',
references = '<leader>lr',
rename = '<leader>ln',
},
-- completion
cmp = {
-- prev item
prev = '<C-p>',
-- next item
next = '<C-n>',
-- confirm
confirm = '<CR>',
-- complete
complete = '<C-Space>',
},
-- disable active selection
noh = '<leader>h',
},
-- lsp servers
lsps = {
-- rust
rust_analyzer = {},
-- c / c++
clangd = {},
-- java
jdtls = {},
},
};
--[[ VIM ]]--
vim.opt.tabstop = config.tab_width
vim.opt.softtabstop = config.tab_width
vim.opt.shiftwidth = config.tab_width
vim.opt.expandtab = config.expand_tab
vim.opt.mouse = "a"
vim.opt.clipboard = "unnamedplus"
vim.opt.hlsearch = true
vim.opt.autoindent = true
vim.opt.ttyfast = true
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.rnu = true
vim.opt.swapfile = false
vim.opt.termguicolors = true
-- remove trailing whitespace on save
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = { "*" },
command = [[%s/\s\+$//e]],
})
--[[ THEME ]]--
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" })
vim.api.nvim_set_hl(0, "NvimTreeNormal", { bg = "none" })
vim.api.nvim_set_hl(0, "Comment", { fg = colorscheme.colors.base04 })
vim.api.nvim_set_hl(0, "@comment", { link = "Comment" })
--[[ LINES ]]--
-- mode line
require('lualine').setup {
options = {
theme = config.colorscheme,
icons_enabled = true,
globalstatus = true,
},
}
-- buffer line
require("bufferline").setup {}
--[[ MENUS ]]--
-- file browser
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.opt.termguicolors = true
require("nvim-tree").setup {
sort = {
sorter = "case_sensitive",
},
view = {
width = 30,
},
renderer = {
group_empty = true,
},
actions = {
open_file = {
quit_on_open = true,
},
},
filters = {
dotfiles = false,
},
}
--[[ COMPLETION ]]--
-- completion engine
--local cmp = require('cmp')
--
--local cmp_select = {behavior = cmp.SelectBehavior.Select}
--local cmp_mappings = cmp.mapping.preset.insert({
-- [config.keybinds.cmp.prev] = cmp.mapping.select_prev_item(cmp_select),
-- [config.keybinds.cmp.next] = cmp.mapping.select_next_item(cmp_select),
-- [config.keybinds.cmp.confirm] = cmp.mapping.confirm({ select = true }),
-- [config.keybinds.cmp.complete] = cmp.mapping.complete(),
--})
--
--cmp_mappings['<Tab>'] = nil
--cmp_mappings['<S-Tab>'] = nil
--
--cmp.setup {
-- snippet = {
-- expand = function(args)
-- vim.fn["vsnip#anonymous"](args.body)
-- end,
-- },
-- sources = cmp.config.sources({
-- { name = 'nvim_lsp' },
-- { name = 'vsnip' },
-- { name = 'buffer' },
-- }),
-- mapping = cmp_mappings,
--}
--
-- delimiter completion
require'nvim-surround'.setup {}
--[[ LSP ]]--
local capabilities = require'cmp_nvim_lsp'.default_capabilities()
for lsp,config in pairs(config.lsps) do
config.capabilities = capabilities
require'lspconfig'[lsp].setup(config)
end
-- illuminate
require'illuminate'.configure {
providers = {
'lsp',
'treesitter',
'regex',
},
}
-- todo comments
require('todo-comments').setup()
-- auto indentation
require('indent-o-matic').setup {
max_lines = 2048,
standard_widths = { 2, 4, 8 },
skip_multiline = true,
}
-- image viewer
--require'hologram'.setup {
-- auto_display = true
--}
-- 80 col bar
require'virt-column'.setup {
enabled = true,
virtcolumn = "80"
}
-- notifications
require("fidget").setup {
notification = {
window = {
winblend = 0,
},
},
}
--[[ KEYBINDS ]]--
vim.g.mapleader = config.keybinds.leader
vim.g.maplocalleader = config.keybinds.leader
vim.keymap.set('', '<leader>', '<Nop>', { noremap = true, silent = true })
local function bind(key, action, opts)
opts = opts or {}
vim.keymap.set('n', key, action, opts)
end
bind(config.keybinds.noh, vim.cmd.noh)
bind(config.keybinds.menus.browser, vim.cmd.NvimTreeToggle)
bind(config.keybinds.menus.undo, vim.cmd.UndotreeToggle)
bind(config.keybinds.menus.error, function() require'trouble'.toggle() end)
local telescope = require'telescope.builtin'
bind(config.keybinds.menus.buffers, telescope.buffers)
bind(config.keybinds.menus.find, telescope.find_files)
bind(config.keybinds.menus.grep, telescope.live_grep)
bind(config.keybinds.menus.help, telescope.help_tags)
vim.api.nvim_create_autocmd('LspAttach', {
desc = 'LSP actions',
callback = function(event)
local opts = {buffer = event.buf}
bind(config.keybinds.lsp.hover, function() vim.lsp.buf.hover() end, opts)
bind(config.keybinds.lsp.action, function() vim.lsp.buf.code_action() end, opts)
bind(config.keybinds.lsp.references, function() vim.lsp.buf.references() end, opts)
bind(config.keybinds.lsp.rename, function() vim.lsp.buf.rename() end, opts)
end
})