Files
nixos/home/common/neovim/default.nix
2025-03-01 13:20:50 +02:00

434 lines
13 KiB
Nix

{ pkgs, lib, ... }:
{
imports = [ ../../modules/neovim ];
programs.neovim =
let
toLua = lib.generators.toLua { };
luaMap = rhs: { rhs = rhs; lua = true; options = { silent = true; }; };
in
{
enable = true;
defaultEditor = false;
options = {
number = true;
expandtab = true;
tabstop = 2;
shiftwidth = 2;
softtabstop = 2;
signcolumn = "yes";
modeline = true;
hidden = true;
listchars = "tab: ,trail:·";
list = true;
undofile = true;
winblend = 30;
};
withTreesitterPlugins = p: [
p.lua
p.vim
p.vimdoc
p.nix
p.query
p.make
];
formatters = [
{
filetypes = [ "nix" ];
globs = [ "*.nix" ];
exe = "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt";
stdin = true;
}
{
filetypes = [ "lua" ];
globs = [ "*.lua" ];
exe = "${pkgs.stylua}/bin/stylua";
args = _: [ "-" ];
stdin = true;
}
{
filetypes = [ "crystal" ];
globs = [ "*.cr" ];
exe = "${pkgs.crystal}/bin/crystal";
args = file: [ "tool" "format" ];
stdin = false;
}
];
autoCommands = [
{
event = "FileType";
pattern = [ "lua" ];
command = "setlocal expandtab";
}
{
event = "FileType";
pattern = [
"makefile"
];
command = "setlocal shiftwidth=4 tabstop=4 softtabstop=4 noexpandtab";
}
{
event = "FileType";
pattern = [ "gitcommit" "gitrebase" "gitconfig" ];
command = "set bufhidden=delete";
}
{
event = "BufWinEnter";
pattern = "*";
command = "if line2byte(line('$')) > 1000000 | syntax clear | endif";
}
];
signs = {
error = "";
warning = "";
hint = "";
info = "";
};
env = {
GIT_EDITOR = "nvr -cc split --remote-wait";
EDITOR = "nvr -cc close --remote-wait";
};
leader = " ";
mappings = {
normal = {
"<C-h>" = "<C-w>h";
"<C-j>" = "<C-w>j";
"<C-k>" = "<C-w>k";
"<C-l>" = "<c-w>l";
"n" = "n";
};
visual = {
"<tab>" = ">gv^";
"<s-tab>" = "<gv^";
};
};
snippets = {
snippets = ./snippets;
luasnippets = ./luasnippets;
};
plug = with pkgs.vimPlugins; [
vimpeccable
vim-crystal
{
plugin = telescope-nvim;
dependencies = [ plenary-nvim telescope-file-browser-nvim commander-nvim telescope-ui-select-nvim ];
config =
let
commands = [
{ cmd = "<cmd>!rails db:migrate<cr>"; desc = "Run rails migrations"; }
{ cmd = "<cmd>!yarn codegen --no-watch<cr>"; desc = "Run yarn codegen"; }
{ cmd = "<cmd>!rails translations:update<cr>"; desc = "Update i18n translations"; }
{ cmd = "<cmd>!deploy staging-v6 -t $(git branch --show-current)<cr>"; desc = "Deploy to staging"; }
{ cmd = "<cmd>!db-restore -d db-prod-inc<cr>"; desc = "Restore db from prod-inc"; }
];
mappings = { i = { "<c-h>" = "which_key"; }; };
in
''
local telescope = require('telescope')
local commander = require('commander')
commander.add(${toLua commands})
telescope.load_extension('commander')
telescope.load_extension('ui-select')
telescope.setup({
defaults = { mappings = ${toLua mappings}, winblend = 30; },
pickers = {
find_files = {
find_command = { "${pkgs.fd}/bin/fd", "-H", "--type=file", "--type=symlink" }
},
},
extensions = {
file_browser = {
hidden = true
},
}
})
'';
mappings = {
normal = (
lib.attrsets.mapAttrs
(key: value: luaMap "require('telescope.builtin').${value}")
{
"<leader>f" = "find_files";
"<leader>r" = "live_grep";
"<leader>b" = "buffers";
"<leader>h" = "help_tags";
"<leader>o" = "oldfiles";
"<leader>s" = "git_status";
"<leader>/" = "current_buffer_fuzzy_find";
"<leader>c" = "git_branches";
}
) // (
lib.attrsets.mapAttrs
(key: value: luaMap "require('telescope').extensions.${value}")
{
"<leader>n" = "file_browser.file_browser";
"<leader>:" = "commander.filter";
}
);
};
}
{
plugin = base16-nvim;
config = ''
vim.opt.termguicolors = true
vim.cmd('colorscheme base16-tomorrow-night')
'';
}
{ plugin = octo-nvim; config = "require('octo').setup()"; }
{
plugin = gitsigns-nvim;
dependencies = [ plenary-nvim ];
config = ''
require('gitsigns').setup(${toLua {
current_line_blame = true;
}})
'';
}
{ plugin = windline-nvim; config = "require('wlsample.airline')"; }
{
plugin = luasnip;
config = ''
require('luasnip.loaders.from_snipmate').lazy_load()
require('luasnip.loaders.from_lua').lazy_load()
local luasnip = require('luasnip')
luasnip.setup({ updateevents = 'TextChanged,TextChangedI' })
'';
mappings =
let
mapping = rhs: luaMap "function() ${rhs} end";
mappings = {
"<c-n>" = mapping "luasnip.jump(1)";
"<c-p>" = mapping "luasnip.jump(-1)";
"<c-e>" = mapping "if luasnip.choice_active() then luasnip.change_choice(1) end";
};
in
{
insert = mappings;
select = mappings;
};
}
{ plugin = vim-abolish; }
{ plugin = NrrwRgn; }
{
plugin = trouble-nvim;
dependencies = [ nvim-web-devicons ];
mappings =
let
mapping = rhs: luaMap "function() require('trouble').${rhs} end";
in
{
normal = {
"<leader>xx" = mapping "open()";
"<leader>xd" = mapping "open('document_diagnostics')";
"<leader>xl" = mapping "open('loclist')";
"gR" = mapping "open('lsp_references')";
};
};
}
{ plugin = twilight-nvim; }
{ plugin = which-key-nvim; }
{ plugin = zen-mode-nvim; }
{
plugin = diffview-nvim;
config =
let
config = {
default = {
layout = "diff2_vertical";
};
merge_tool = {
layout = "diff3_vertical";
};
file_history = {
layout = "diff2_vertical";
};
};
in
''
require('diffview').setup(${toLua config})
'';
}
{
plugin = toggleterm-nvim;
dependencies = [ plenary-nvim pkgs.lazygit ];
config = ''
local Terminal = require('toggleterm.terminal').Terminal
local lazygit = Terminal:new({
cmd = "${pkgs.lazygit}/bin/lazygit",
dir = "git_dir",
direction = "float",
hidden = true,
on_open = function (term)
vim.cmd('startinsert!')
vim.api.nvim_buf_set_keymap(term.bufnr, 'n', 'q', '<cmd>close<cr>', { noremap = true, silent = true })
end,
on_close = function (term)
vim.cmd('startinsert!')
end,
})
'';
mappings = {
normal = {
"<leader>g" = luaMap "function () lazygit:toggle() end";
};
};
}
{
plugin = copilot-cmp;
dependencies = [{
plugin = copilot-lua;
config = ''
require('copilot').setup({
suggestion = { enabled = false },
panel = { enajkbled = false },
copilot_node_command = '${pkgs.nodejs}/bin/node',
})
'';
}];
config = ''
require('copilot_cmp').setup()
'';
}
{
plugin = gen-nvim;
config =
let
config = {
model = "llama3";
};
in
''
require('gen').setup(${toLua config})
'';
}
{
plugin = bufferline-nvim;
config =
let
options = {
hover = {
enabled = true;
delay = 200;
reveal = [ "close" ];
};
};
in
''
require('bufferline').setup({ options = ${toLua options} })
'';
dependencies = [{
plugin = nvim-web-devicons;
}];
}
];
lsp = {
servers = with pkgs; [
{
name = "lua_ls";
config = {
settings = {
Lua = {
diagnostics = {
globals = [ "vim" ];
};
};
};
};
package = lua-language-server;
}
{
name = "yamlls";
config = {
settings = {
redhat = { telemetry = { enabled = false; }; };
yaml = {
schemas = {
"https://json.schemastore.org/github-workflow" = ".github/workflows/*.yml";
"https://json.schemastore.org/prettierrc" = ".prettierrc";
"https://json.schemastore.org/prettierrc.yml" = ".prettierrc.yml";
"https://json.schemastore.org/prettierrc.yaml" = ".prettierrc.yaml";
"https://json.schemastore.org/prettier.config.yml" = "prettier.config.yml";
"https://json.schemastore.org/prettier.config.yaml" = "prettier.config.yaml";
"https://schema.jokke.space/caddy.json" = [ "*caddy*.yml" "*caddy*.yaml" ];
};
};
};
};
package = yaml-language-server;
}
{
name = "tailwindcss";
config = {
settings = {
tailwindCSS = {
classAttributes = [ "class" "className" ];
};
};
};
package = tailwindcss-language-server;
}
{
name = "ts_ls";
package = nodePackages.typescript-language-server;
config = {
single_file_support = false;
};
rootPattern = [ "package.json" ];
}
{ name = "eslint"; package = vscode-langservers-extracted; }
{ name = "nixd"; package = nixd; }
{
name = "bashls";
package = nodePackages.bash-language-server.overrideAttrs (oldAttrs: {
buildDependencies = [ shellcheck ];
afterInstall = ''
wrapProgram "$out/bin/bash-language-server" --prefix PATH : "${shellcheck}/bin"
'';
});
}
{
name = "crystalline";
package = crystalline;
}
{
name = "rust_analyzer";
package = rust-analyzer;
}
];
mappings = {
buf = {
declaration = "gD";
definition = "gd";
hover = "K";
implementation = "gi";
type_definition = "<leader>D";
rename = "<leader>rn";
code_action = "<leader>ca";
};
diagnostic = {
show_line_diagnostics = "<leader>e";
goto_prev = "[d";
goto_next = "]d";
set_loclist = "<leader>q";
};
};
};
extraLuaConfig = ''
local function close_all_other_buffers(opts)
local current_buf = vim.api.nvim_get_current_buf()
local buffers = vim.api.nvim_list_bufs()
for _, buf in ipairs(buffers) do
if buf ~= current_buf and vim.api.nvim_buf_is_loaded(buf) then
vim.api.nvim_buf_delete(buf, { force = opts.bang })
end
end
end
vim.api.nvim_create_user_command('CloseOtherBuffers', close_all_other_buffers, { bang = true })
'';
};
}