neovim: Import neovim from flake

This commit is contained in:
traxys 2024-03-11 12:20:53 +01:00
parent 95e06432ac
commit 08aa83ee31
11 changed files with 5782 additions and 33 deletions

1195
flake.lock generated

File diff suppressed because it is too large Load diff

255
flake.nix
View file

@ -88,6 +88,214 @@
#inputs.nixpkgs.follows = "nixpkgs";
};
fioul.url = "github:traxys/fioul";
neovim-flake = {
url = "github:neovim/neovim?dir=contrib";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim";
#url = "/home/traxys/Documents/nixvim";
#url = "github:traxys/nixvim?ref=dev";
inputs.nixpkgs.follows = "nixpkgs";
};
# Neovim plugins
"plugin:clangd_extensions-nvim" = {
url = "github:p00f/clangd_extensions.nvim";
flake = false;
};
"plugin:netman-nvim" = {
url = "github:miversen33/netman.nvim";
flake = false;
};
"plugin:cmp-buffer" = {
url = "github:hrsh7th/cmp-buffer";
flake = false;
};
"plugin:cmp-calc" = {
url = "github:hrsh7th/cmp-calc";
flake = false;
};
"plugin:cmp-nvim-lsp" = {
url = "github:hrsh7th/cmp-nvim-lsp";
flake = false;
};
"plugin:cmp-path" = {
url = "github:hrsh7th/cmp-path";
flake = false;
};
"plugin:cmp_luasnip" = {
url = "github:saadparwaiz1/cmp_luasnip";
flake = false;
};
"plugin:comment-nvim" = {
url = "github:numtostr/comment.nvim";
flake = false;
};
"plugin:firenvim" = {
url = "github:glacambre/firenvim";
flake = false;
};
"plugin:git-messenger-vim" = {
url = "github:rhysd/git-messenger.vim";
flake = false;
};
"plugin:gitsigns-nvim" = {
url = "github:lewis6991/gitsigns.nvim";
flake = false;
};
"plugin:inc-rename-nvim" = {
url = "github:smjonas/inc-rename.nvim";
flake = false;
};
"plugin:indent-blankline-nvim" = {
url = "github:lukas-reineke/indent-blankline.nvim";
flake = false;
};
"plugin:lspkind-nvim" = {
url = "github:onsails/lspkind.nvim";
flake = false;
};
"plugin:lualine-nvim" = {
url = "github:nvim-lualine/lualine.nvim";
flake = false;
};
"plugin:noice-nvim" = {
url = "github:folke/noice.nvim";
flake = false;
};
"plugin:nui-nvim" = {
url = "github:MunifTanjim/nui.nvim";
flake = false;
};
"plugin:nvim-cmp" = {
url = "github:hrsh7th/nvim-cmp";
flake = false;
};
"plugin:nvim-lightbulb" = {
url = "github:kosayoda/nvim-lightbulb";
flake = false;
};
"plugin:nvim-lspconfig" = {
url = "github:neovim/nvim-lspconfig";
flake = false;
};
"plugin:nvim-notify" = {
url = "github:rcarriga/nvim-notify";
flake = false;
};
"plugin:nvim-osc52" = {
url = "github:ojroques/nvim-osc52";
flake = false;
};
"plugin:nvim-tree-lua" = {
url = "github:nvim-tree/nvim-tree.lua";
flake = false;
};
"plugin:nvim-treesitter-context" = {
url = "github:nvim-treesitter/nvim-treesitter-context";
flake = false;
};
"plugin:nvim-treesitter-refactor" = {
url = "github:nvim-treesitter/nvim-treesitter-refactor";
flake = false;
};
"plugin:plantuml-syntax" = {
url = "github:aklt/plantuml-syntax";
flake = false;
};
"plugin:plenary-nvim" = {
url = "github:nvim-lua/plenary.nvim";
flake = false;
};
"plugin:rustaceanvim" = {
url = "github:mrcjkb/rustaceanvim";
flake = false;
};
"plugin:telescope-nvim" = {
url = "github:nvim-telescope/telescope.nvim";
flake = false;
};
"plugin:telescope-ui-select-nvim" = {
url = "github:nvim-telescope/telescope-ui-select.nvim";
flake = false;
};
"plugin:trouble-nvim" = {
url = "github:folke/trouble.nvim";
flake = false;
};
"plugin:vim-matchup" = {
url = "github:andymass/vim-matchup";
flake = false;
};
"plugin:luasnip" = {
url = "github:L3MON4D3/LuaSnip";
flake = false;
};
"plugin:nvim-treesitter" = {
url = "github:nvim-treesitter/nvim-treesitter";
flake = false;
};
"plugin:openscad-nvim" = {
url = "github:salkin-mada/openscad.nvim";
flake = false;
};
"plugin:neo-tree-nvim" = {
url = "github:nvim-neo-tree/neo-tree.nvim";
flake = false;
};
"plugin:nvim-web-devicons" = {
url = "github:nvim-tree/nvim-web-devicons";
flake = false;
};
"plugin:popup-nvim" = {
url = "github:nvim-lua/popup.nvim";
flake = false;
};
"plugin:skim-vim" = {
url = "github:lotabout/skim.vim";
flake = false;
};
"plugin:tokyonight-nvim" = {
url = "github:folke/tokyonight.nvim";
flake = false;
};
"plugin:vim-snippets" = {
url = "github:honza/vim-snippets";
flake = false;
};
"plugin:markdown-preview-nvim" = {
url = "github:iamcco/markdown-preview.nvim";
flake = false;
};
"plugin:which-key-nvim" = {
url = "github:folke/which-key.nvim";
flake = false;
};
"plugin:zk-nvim" = {
url = "github:mickael-menu/zk-nvim";
flake = false;
};
"plugin:efmls-configs-nvim" = {
url = "github:creativenull/efmls-configs-nvim";
flake = false;
};
"plugin:vim-just" = {
url = "github:NoahTheDuke/vim-just/";
flake = false;
};
"plugin:ltex_extra-nvim" = {
url = "github:barreiroleo/ltex_extra.nvim";
flake = false;
};
# Plugins that are not in nixpkgs
"new-plugin:vim-headerguard" = {
url = "github:drmikehenry/vim-headerguard";
flake = false;
};
};
outputs = {
@ -112,7 +320,52 @@
// {
glaurung = inputs.glaurung.defaultPackage."${system}";
raclette = inputs.raclette.defaultPackage."${system}";
neovimTraxys = inputs.nvim-traxys.packages."${system}".nvim;
neovimTraxys = let
inputsMatching = with builtins;
prefix:
nixpkgs.lib.mapAttrs'
(prefixedName: value: {
name =
substring (stringLength "${prefix}:") (stringLength prefixedName) prefixedName;
inherit value;
})
(nixpkgs.lib.filterAttrs
(name: _: (match "${prefix}:.*" name) != null)
inputs);
neovimPlugins = final: prev: {
vimPlugins = prev.vimPlugins.extend (final': prev':
(nixpkgs.lib.mapAttrs (
pname: src:
prev'."${pname}".overrideAttrs (old: {
version = src.shortRev;
inherit src;
})
) (inputsMatching "plugin"))
// (
nixpkgs.lib.mapAttrs (
pname: src:
prev.vimUtils.buildVimPlugin {
inherit pname src;
version = src.shortRev;
}
) (inputsMatching "new-plugin")
));
};
nixvim' = inputs.nixvim.legacyPackages."${system}";
in
callPackage ({pkgs}:
nixvim'.makeNixvimWithModule {
module = import ./neovim;
pkgs = (pkgs.extend neovimPlugins).extend (final: prev: {
vimPlugins = prev.vimPlugins.extend (final': prev': {
nvim-treesitter = prev'.nvim-treesitter.overrideAttrs (
prev.callPackage ./neovim/nvim-treesitter/override.nix {} final' prev'
);
});
});
}) {};
roaming_proxy = inputs.roaming_proxy.defaultPackage."${system}";
inherit (nixpkgs-traxys.legacyPackages."${system}") groovy-language-server;
inherit (inputs.mujmap.packages."${system}") mujmap;

781
neovim/default.nix Normal file
View file

@ -0,0 +1,781 @@
{
pkgs,
config,
helpers,
lib,
...
}: {
imports = [
./modules/commands.nix
./plugins/firenvim.nix
./plugins/headerguard.nix
./plugins/lsp-signature.nix
];
config = {
colorschemes.tokyonight = {
style = "night";
enable = true;
};
autoGroups.BigFileOptimizer = {};
autoCmd = [
{
event = "BufReadPost";
pattern = [
"*.md"
"*.rs"
"*.lua"
"*.sh"
"*.bash"
"*.zsh"
"*.js"
"*.jsx"
"*.ts"
"*.tsx"
"*.c"
".h"
"*.cc"
".hh"
"*.cpp"
".cph"
];
group = "BigFileOptimizer";
callback = helpers.mkRaw ''
function(auEvent)
local bufferCurrentLinesCount = vim.api.nvim_buf_line_count(0)
if bufferCurrentLinesCount > 2048 then
vim.notify("bigfile: disabling features", vim.log.levels.WARN)
vim.cmd("TSBufDisable refactor.highlight_definitions")
vim.g.matchup_matchparen_enabled = 0
require("nvim-treesitter.configs").setup({
matchup = {
enable = false
}
})
end
end
'';
}
];
globals = {
neo_tree_remove_legacy_commands = 1;
mapleader = " ";
};
options = {
termguicolors = true;
number = true;
tabstop = 4;
shiftwidth = 4;
scrolloff = 7;
signcolumn = "yes";
cmdheight = 2;
cot = ["menu" "menuone" "noselect"];
updatetime = 100;
colorcolumn = "100";
# Too many false positives
spell = false;
listchars = "tab:>-,lead:·,nbsp:,trail:";
fsync = true;
timeout = true;
timeoutlen = 300;
};
commands = {
"SpellFr" = "setlocal spelllang=fr";
};
filetype = {
filename = {
Jenkinsfile = "groovy";
};
extension = {
lalrpop = "lalrpop";
};
};
keymaps = let
modeKeys = mode:
lib.attrsets.mapAttrsToList (key: action:
{
inherit key mode;
}
// (
if builtins.isString action
then {inherit action;}
else action
));
nm = modeKeys ["n"];
vs = modeKeys ["v"];
in
helpers.keymaps.mkKeymaps {options.silent = true;} (nm {
"ft" = "<cmd>Neotree<CR>";
"fG" = "<cmd>Neotree git_status<CR>";
"fR" = "<cmd>Neotree remote<CR>";
"fc" = "<cmd>Neotree close<CR>";
"bp" = "<cmd>Telescope buffers<CR>";
"<C-s>" = "<cmd>Telescope spell_suggest<CR>";
"mk" = "<cmd>Telescope keymaps<CR>";
"fg" = "<cmd>Telescope git_files<CR>";
"gr" = "<cmd>Telescope lsp_references<CR>";
"gI" = "<cmd>Telescope lsp_implementations<CR>";
"gW" = "<cmd>Telescope lsp_workspace_symbols<CR>";
"gF" = "<cmd>Telescope lsp_document_symbols<CR>";
"ge" = "<cmd>Telescope diagnostics bufnr=0<CR>";
"gE" = "<cmd>Telescope diagnostics<CR>";
"<leader>h" = {
action = "<cmd>lua vim.lsp.inlay_hint.enable(0, not vim.lsp.inlay_hint.is_enabled())<CR>";
options = {
desc = "toggle inlay hints";
};
};
"<leader>zn" = "<Cmd>ZkNew { title = vim.fn.input('Title: ') }<CR>";
"<leader>zo" = "<Cmd>ZkNotes { sort = { 'modified' } }<CR>";
"<leader>zt" = "<Cmd>ZkTags<CR>";
"<leader>zf" = "<Cmd>ZkNotes { sort = { 'modified' }, match = { vim.fn.input('Search: ') } }<CR>";
"yH" = {
action = "<Cmd>Telescope yank_history<CR>";
options.desc = "history";
};
})
++ (vs {
"<leader>zf" = "'<,'>ZkMatch<CR>";
})
++ [
{
key = "<leader>rn";
mode = ["n"];
action = ''
function()
return ":IncRename " .. vim.fn.expand("<cword>")
end
'';
lua = true;
options.expr = true;
}
];
plugins.nvim-osc52 = {
enable = true;
package = pkgs.vimPlugins.nvim-osc52;
keymaps.enable = true;
};
plugins.efmls-configs = {
enable = true;
toolPackages.mdformat = pkgs.mdformat.withPlugins (ps:
with ps; [
# TODO: broken with update of mdformat
# mdformat-gfm
mdformat-frontmatter
mdformat-footnote
mdformat-tables
mdit-py-plugins
]);
setup = {
sh = {
#linter = "shellcheck";
formatter = "shfmt";
};
bash = {
#linter = "shellcheck";
formatter = "shfmt";
};
c = {
linter = "cppcheck";
};
markdown = {
formatter = ["cbfmt" "mdformat"];
};
python = {
formatter = "black";
};
nix = {
linter = "statix";
};
lua = {
formatter = "stylua";
};
html = {
formatter = ["prettier" (helpers.mkRaw "djlint_fmt")];
};
htmldjango = {
formatter = [(helpers.mkRaw "djlint_fmt")];
linter = "djlint";
};
json = {
formatter = "prettier";
};
css = {
formatter = "prettier";
};
ts = {
formatter = "prettier";
};
gitcommit = {
linter = "gitlint";
};
};
};
# plugins.null-ls = {
# enable = true;
# sources = {
# diagnostics = {
# gitlint.enable = true;
# };
# code_actions = {
# shellcheck.enable = true;
# #gitsigns.enable = true;
# };
# formatting = {
# alejandra.enable = true;
# };
# };
# };
plugins.gitsigns.enable = true;
plugins.gitmessenger.enable = true;
plugins.firenvim.enable = false;
plugins.luasnip = {
enable = true;
};
extraConfigLuaPre = ''
local has_words_before = function()
unpack = unpack or table.unpack
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
local luasnip = require("luasnip")
local efm_fs = require('efmls-configs.fs')
local djlint_fmt = {
formatCommand = string.format('%s --reformat ''${INPUT} -', efm_fs.executable('djlint')),
formatStdin = true,
}
'';
plugins.cmp = {
enable = true;
settings = {
snippet.expand = ''
function(args)
require('luasnip').lsp_expand(args.body)
end
'';
mapping = {
"<CR>" = "cmp.mapping.confirm({select = true })";
"<C-d>" = "cmp.mapping.scroll_docs(-4)";
"<C-f>" = "cmp.mapping.scroll_docs(4)";
"<C-Space>" = "cmp.mapping.complete()";
"<Tab>" = ''
cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
-- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
-- they way you will only jump inside the snippet region
elseif luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { "i", "s" })
'';
"<S-Tab>" = ''
cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" })
'';
"<Down>" = "cmp.mapping(cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }), {'i'})";
"<Up>" = "cmp.mapping(cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }), {'i'})";
};
sources = [
{name = "luasnip";}
{name = "nvim_lsp";}
{name = "path";}
{name = "buffer";}
{name = "calc";}
];
};
filetype.sh = {
sources = [
{name = "zsh";}
];
};
};
plugins.telescope = {
enable = true;
enabledExtensions = ["ui-select"];
extensionConfig = {
ui-select = {
__raw = ''
require("telescope.themes").get_dropdown {
-- even more opts
}
'';
};
};
extraOptions = {
defaults.layout_strategy = "vertical";
};
};
extraFiles."queries/rust/injections.scm" = ''
;; extends
(
(macro_invocation
macro: ((scoped_identifier) @_sql_def)
(token_tree (string_literal) @sql))
(#eq? @_sql_def "sqlx::query")
)
'';
plugins.treesitter = {
enable = true;
indent = true;
nixvimInjections = true;
grammarPackages = with config.plugins.treesitter.package.passthru.builtGrammars; [
arduino
bash
c
cpp
cuda
dart
devicetree
diff
dockerfile
gitattributes
gitcommit
gitignore
git_rebase
groovy
html
ini
json
lalrpop
latex
lua
make
markdown
markdown_inline
meson
ninja
nix
python
regex
rst
rust
slint
sql
tlaplus
toml
vim
vimdoc
yaml
];
};
plugins.treesitter-refactor = {
enable = true;
highlightDefinitions = {
enable = true;
clearOnCursorMove = true;
};
smartRename = {
enable = true;
};
navigation = {
enable = true;
};
};
plugins.treesitter-context = {
enable = true;
};
plugins.vim-matchup = {
treesitterIntegration = {
enable = true;
includeMatchWords = true;
};
enable = true;
};
plugins.headerguard.enable = true;
plugins.comment-nvim = {
enable = true;
};
plugins.neo-tree = {
enable = true;
};
plugins.plantuml-syntax.enable = true;
plugins.indent-blankline = {
enable = true;
scope = {
enabled = true;
showStart = true;
};
};
plugins.lsp = {
enable = true;
enabledServers = [
# {
# name = "groovyls";
# extraOptions = {
# cmd = ["${pkgs.groovy-language-server}/bin/groovy-language-server"];
# };
# }
];
keymaps = {
silent = true;
lspBuf = {
"gd" = "definition";
"gD" = "declaration";
"ca" = "code_action";
"ff" = "format";
"K" = "hover";
};
};
servers = {
nil_ls = {
enable = true;
settings = {
formatting.command = ["${pkgs.alejandra}/bin/alejandra" "--quiet"];
};
};
bashls.enable = true;
dartls.enable = true;
clangd.enable = true;
typst-lsp.enable = true;
tsserver.enable = true;
efm.extraOptions = {
init_options = {
documentFormatting = true;
};
settings = {
logLevel = 1;
languages.meson = [
(helpers.mkRaw (helpers.toLuaObject {
prefix = "muon-fmt";
formatCommand = "muon fmt -";
formatStdin = true;
}))
(helpers.mkRaw (helpers.toLuaObject {
prefix = "muon-analyze";
lintSource = "efm/muon-analyze";
lintCommand = "muon analyze -l";
lintWorkspace = true;
lintStdin = false;
LintIgnoreExitCode = true;
rootMarkers = ["meson_options.txt" ".git"];
lintFormats = [
"%f:%l:%c: %trror %m"
"%f:%l:%c: %tarning %m"
];
}))
];
};
};
taplo.enable = true;
lemminx.enable = true;
ltex = {
enable = true;
onAttach.function = ''
require("ltex_extra").setup{
load_langs = { "en-US", "fr-FR" },
path = ".ltex",
}
'';
filetypes = [
"bib"
"gitcommit"
"markdown"
"org"
"plaintex"
"rst"
"rnoweb"
"tex"
"pandoc"
"typst"
#"mail"
];
};
};
};
plugins.typst-vim.enable = true;
plugins.rustaceanvim = {
enable = true;
server = {
settings = {
cargo.features = "all";
checkOnSave = true;
check.command = "clippy";
rustc.source = "discover";
};
};
};
plugins.lspkind = {
enable = true;
cmp = {
enable = true;
};
};
plugins.nvim-lightbulb = {
enable = true;
settings.autocmd.enabled = true;
};
plugins.lsp_signature = {
#enable = true;
};
plugins.inc-rename = {
enable = true;
};
plugins.clangd-extensions = {
enable = true;
enableOffsetEncodingWorkaround = true;
ast = {
roleIcons = {
type = "";
declaration = "";
expression = "";
specifier = "";
statement = "";
templateArgument = "";
};
kindIcons = {
compound = "";
recovery = "";
translationUnit = "";
packExpansion = "";
templateTypeParm = "";
templateTemplateParm = "";
templateParamObject = "";
};
};
};
# fidget = {
# enable = true;
#
# sources.null-ls.ignore = true;
# };
plugins.lualine = {
enable = true;
};
plugins.trouble = {
enable = true;
};
plugins.noice = {
enable = true;
messages = {
view = "mini";
viewError = "mini";
viewWarn = "mini";
};
lsp.override = {
"vim.lsp.util.convert_input_to_markdown_lines" = true;
"vim.lsp.util.stylize_markdown" = true;
"cmp.entry.get_documentation" = true;
};
presets = {
bottom_search = true;
command_palette = true;
long_message_to_split = true;
inc_rename = true;
lsp_doc_border = false;
};
};
plugins.netman = {
enable = false;
package = pkgs.vimPlugins.netman-nvim;
neoTreeIntegration = true;
};
plugins.openscad = {
enable = true;
loadSnippets = true;
keymaps.enable = true;
};
extraConfigLuaPost = ''
require("luasnip.loaders.from_snipmate").lazy_load()
vim.api.nvim_create_user_command("LtexLangChangeLanguage", function(data)
local language = data.fargs[1]
local bufnr = vim.api.nvim_get_current_buf()
local client = vim.lsp.get_active_clients({ bufnr = bufnr, name = 'ltex' })
if #client == 0 then
vim.notify("No ltex client attached")
else
client = client[1]
client.config.settings = {
ltex = {
language = language
}
}
client.notify('workspace/didChangeConfiguration', client.config.settings)
vim.notify("Language changed to " .. language)
end
end, {
nargs = 1,
force = true,
})
-- local null_ls = require("null-ls")
-- local helpers = require("null-ls.helpers")
--
-- local sca2d = {
-- method = null_ls.methods.DIAGNOSTICS,
-- filetypes = { "openscad" },
-- generator = null_ls.generator({
-- command = "sca2d",
-- args = { "$FILENAME" },
-- from_stderr = false,
-- to_stdin = true,
-- format = "line",
-- check_exit_code = function(code)
-- return code <= 1
-- end,
-- on_output = helpers.diagnostics.from_pattern(
-- [[[^:]+:(%d+):(%d+): (%w)%d+: (.*)]], {"row", "col", "severity", "message"}, {
-- severities = {
-- F = helpers.diagnostics.severities["error"],
-- E = helpers.diagnostics.severities["error"],
-- W = helpers.diagnostics.severities["warning"],
-- D = helpers.diagnostics.severities["warning"],
-- I = helpers.diagnostics.severities["info"],
-- },
-- }),
-- }),
-- }
-- null_ls.register(sca2d)
'';
plugins.zk = {
enable = true;
picker = "telescope";
};
plugins.which-key.enable = true;
plugins.leap.enable = true;
plugins.yanky = {
enable = true;
picker.telescope = {
useDefaultMappings = true;
enable = true;
};
};
files."ftplugin/nix.lua" = {
options = {
tabstop = 2;
shiftwidth = 2;
expandtab = true;
};
};
files."ftplugin/markdown.lua" = {
extraConfigLua = ''
if require("zk.util").notebook_root(vim.fn.expand('%:p')) ~= nil then
local function map(...) vim.api.nvim_buf_set_keymap(0, ...) end
local opts = { noremap=true, silent=false }
-- Open the link under the caret.
map("n", "<CR>", "<Cmd>lua vim.lsp.buf.definition()<CR>", opts)
-- Create a new note after asking for its title.
-- This overrides the global `<leader>zn` mapping to create the note in the same directory as the current buffer.
map("n", "<leader>zn", "<Cmd>ZkNew { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }<CR>", opts)
-- Create a new note in the same directory as the current buffer, using the current selection for title.
map("v", "<leader>znt", ":'<,'>ZkNewFromTitleSelection { dir = vim.fn.expand('%:p:h') }<CR>", opts)
-- Create a new note in the same directory as the current buffer, using the current selection for note content and asking for its title.
map("v", "<leader>znc", ":'<,'>ZkNewFromContentSelection { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }<CR>", opts)
-- Open notes linking to the current buffer.
map("n", "<leader>zb", "<Cmd>ZkBacklinks<CR>", opts)
-- Alternative for backlinks using pure LSP and showing the source context.
--map('n', '<leader>zb', '<Cmd>lua vim.lsp.buf.references()<CR>', opts)
-- Open notes linked by the current buffer.
map("n", "<leader>zl", "<Cmd>ZkLinks<CR>", opts)
-- Preview a linked note.
map("n", "K", "<Cmd>lua vim.lsp.buf.hover()<CR>", opts)
-- Open the code actions for a visual selection.
map("v", "<leader>za", ":'<,'>lua vim.lsp.buf.range_code_action()<CR>", opts)
end
'';
};
extraPackages = with pkgs; [
/*
sca2d
*/
djlint
muon
];
extraPlugins = with pkgs.vimPlugins; [
telescope-ui-select-nvim
vim-snippets
markdown-preview-nvim
vim-just
ltex_extra-nvim
];
};
}

View file

@ -0,0 +1,20 @@
{
lib,
config,
...
}:
with lib; {
options = {
commands = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Extra commands to be created";
};
};
config.extraConfigVim = let
commands = cmds:
concatStringsSep "\n" (map (cmd: "command ${cmd} ${getAttr cmd cmds}") (attrNames cmds));
in
commands config.commands;
}

View file

@ -0,0 +1,40 @@
{
lib,
upstream,
nvim-treesitter,
neovimUtils,
nurl,
python3,
wrapNeovimUnstable,
stdenv,
makeWrapper,
}: let
neovimTs =
(neovimUtils.override {
neovim-unwrapped = upstream;
})
.makeNeovimConfig {
plugins = [nvim-treesitter];
};
in
stdenv.mkDerivation {
name = "update-nvim-treesitter";
src = ./update.py;
nativeBuildInputs = [makeWrapper];
dontUnpack = true;
installPhase = ''
mkdir -p $out/bin
cat $src > $out/bin/update-nvim-treesitter
chmod +x $out/bin/update-nvim-treesitter
wrapProgram $out/bin/update-nvim-treesitter --set NVIM_TREESITTER "${nvim-treesitter}" --prefix PATH : ${
lib.makeBinPath [
(wrapNeovimUnstable upstream neovimTs)
nurl
python3
]
}
'';
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
{
lib,
callPackage,
tree-sitter,
neovim,
neovimUtils,
runCommand,
}: self: super: let
inherit (neovimUtils) grammarToPlugin;
generatedGrammars = callPackage ./generated.nix {
inherit (tree-sitter) buildGrammar;
};
generatedDerivations = lib.filterAttrs (_: lib.isDerivation) generatedGrammars;
# add aliases so grammars from `tree-sitter` are overwritten in `withPlugins`
# for example, for ocaml_interface, the following aliases will be added
# ocaml-interface
# tree-sitter-ocaml-interface
# tree-sitter-ocaml_interface
builtGrammars =
generatedGrammars
// lib.concatMapAttrs
(k: v: let
replaced = lib.replaceStrings ["_"] ["-"] k;
in
{
"tree-sitter-${k}" = v;
}
// lib.optionalAttrs (k != replaced) {
${replaced} = v;
"tree-sitter-${replaced}" = v;
})
generatedDerivations;
allGrammars = lib.attrValues generatedDerivations;
# Usage:
# pkgs.vimPlugins.nvim-treesitter.withPlugins (p: [ p.c p.java ... ])
# or for all grammars:
# pkgs.vimPlugins.nvim-treesitter.withAllGrammars
withPlugins = f:
self.nvim-treesitter.overrideAttrs {
passthru.dependencies =
map grammarToPlugin
(f (tree-sitter.builtGrammars // builtGrammars));
};
withAllGrammars = withPlugins (_: allGrammars);
in {
postPatch = ''
rm -r parser
'';
passthru = {
inherit builtGrammars allGrammars grammarToPlugin withPlugins withAllGrammars;
grammarPlugins = lib.mapAttrs (_: grammarToPlugin) generatedDerivations;
tests.check-queries = let
nvimWithAllGrammars = neovim.override {
configure.packages.all.start = [withAllGrammars];
};
in
runCommand "nvim-treesitter-check-queries"
{
nativeBuildInputs = [nvimWithAllGrammars];
CI = true;
}
''
touch $out
export HOME=$(mktemp -d)
ln -s ${withAllGrammars}/CONTRIBUTING.md .
nvim --headless "+luafile ${withAllGrammars}/scripts/check-queries.lua" | tee log
if grep -q Warning log; then
echo "Error: warnings were emitted by the check"
exit 1
fi
'';
};
meta = with lib;
(super.nvim-treesitter.meta or {})
// {
license = licenses.asl20;
maintainers = with maintainers; [figsoda];
};
}

View file

@ -0,0 +1,77 @@
#!/usr/bin/env python3
import json
import subprocess
from concurrent.futures import ThreadPoolExecutor
from os import environ
from os.path import dirname, join
import sys
lockfile = json.load(open(join(environ["NVIM_TREESITTER"], "lockfile.json")))
configs = json.loads(
subprocess.check_output(
[
"nvim",
"--headless",
"-u",
"NONE",
"+lua io.write(vim.json.encode(require('nvim-treesitter.parsers').get_parser_configs()))",
"+quit!",
]
)
)
def generate_grammar(item):
lang, lock = item
cfg = configs.get(lang)
if not cfg:
return ""
info = cfg["install_info"]
url = info["url"]
rev = lock["revision"]
generated = f""" {lang} = buildGrammar {{
language = "{lang}";
version = "0.0.0+rev={rev[:7]}";
src = """
generated += subprocess.check_output(["nurl", url, rev, "--indent=4"], text=True)
generated += ";"
location = info.get("location")
if location:
generated += f"""
location = "{location}";"""
if info.get("requires_generate_from_grammar"):
generated += """
generate = true;"""
generated += f"""
meta.homepage = "{url}";
}};
"""
return generated
generated_file = """# generated by nix run .\#update-nvim-treesitter -- nvim-treesitter
{ buildGrammar, """
generated_file += subprocess.check_output(["nurl", "-Ls", ", "], text=True)
generated_file += """ }:
{
"""
for generated in ThreadPoolExecutor().map(generate_grammar, lockfile.items()):
generated_file += generated
generated_file += "}\n"
open(join(sys.argv[1], "generated.nix"), "w").write(generated_file)

186
neovim/plugins/firenvim.nix Normal file
View file

@ -0,0 +1,186 @@
{
pkgs,
config,
lib,
...
}:
with lib;
with builtins; {
options.plugins.firenvim = {
enable = mkEnableOption "Enable firenvim support";
global = let
mkKey = mkOption {
type = types.enum ["default" "noop"];
default = "default";
description = ''
When it is possible to do so, if you press this keyboard shortcut while not in a Firenvim
frame, Firenvim will attempt to emulate the expected behavior of the shortcut
'';
};
nvimModes = [
"all"
"normal"
"visual"
"insert"
"replace"
"cmdline_normal"
"cmdline_insert"
"cmdline_replace"
"operator"
"visual_select"
"cmdline_hover"
"statusline_hover"
"statusline_drag"
"vsep_hover"
"vsep_drag"
"more"
"more_lastline"
"showmatch"
];
modeOptions = listToAttrs (map (mode: {
name = mode;
value = mkOption {
type = types.listOf types.str;
default = [];
description = "Keys to ignore in ${mode} mode";
};
})
nvimModes);
in {
alt = mkOption {
type = types.enum ["all" "alphanum"];
# TODO: set to 'alphanum' by default on macOS
default = "all";
description = ''
Change the handling of alt with dead keys. See
https://github.com/glacambre/firenvim#special-characters-on-macos for more information.
'';
};
"<C-n>" = mkKey;
"<C-t>" = mkKey;
"<C-w>" = mkKey;
"<CS-n>" = mkKey;
"<CS-t>" = mkKey;
"<CS-w>" = mkKey;
ignoreKeys = mkOption {
type = types.submodule {options = modeOptions;};
default = {};
description = ''
You can make Firenvim ignore key presses (thus letting the browser handle them) by
specifying them in this module
'';
};
cmdlineTimeout = mkOption {
type = types.int;
default = 3000;
description = ''
Due to space constraints, the external command line covers part of the buffer.
This can be a problem as sometimes neovim will send a message that tells Firenvim to draw
the command line, and then never send the message to tell Firenvim to stop displaying it.
In order to work around this problem, a "cmdlineTimeout" configuration option has been
implemented, which makes Firenvim hide the external command line after the cursor has
moved and some amount of milliseconds have passed:
'';
};
};
local = mkOption {
type = types.attrsOf (types.submodule {
options = {
cmdline = mkOption {
type = types.nullOr (types.enum ["neovim" "firenvim" "none"]);
default = null;
description = ''
You can chose between neovim's built-in command line, firenvim's command line and no
command line at all
Choosing none does not make sense unless you have alternative way to display the
command line such as noice.nvim.
'';
};
content = mkOption {
type = types.nullOr (types.enum ["html" "text"]);
default = null;
description = ''
This option controls how Firenvim should read the content of an element.
Setting it to 'html' will make Firenvim fetch the content of elements as HTML,
'text' will make it use plaintext.
'';
};
priority = mkOption {
type = types.int;
default = 0;
description = "Higher priority options overwrite lower priority ones";
};
renderer = mkOption {
type = types.nullOr (types.enum ["html" "canvas"]);
default = null;
};
selector = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
This options is a CSS selector that allows to choose which elements firenvim
will link to
'';
};
takeover = mkOption {
type = types.nullOr (types.enum ["always" "once" "empty" "nonempty" "never"]);
default = null;
description = ''
When set to 'always', Firenvim will always take over elements for you. When set to
'empty', Firenvim will only take over empty elements. When set to 'never', Firenvim
will never automatically appear, thus forcing you to use a keyboard shortcut in order
to make the Firenvim frame appear. When set to 'nonempty', Firenvim will only take
over elements that aren't empty. When set to 'once', Firenvim will take over elements
the first time you select them, which means that after :q'ing Firenvim, you'll have
to use the keyboard shortcut to make it appear again.
'';
};
filename = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
This setting is a format string where each element in curly braces will be replaced
with a value and where the maximum length can be specified with a percentage. Possible
format elements are 'hostname' (= the domain name of the website), 'pathname'
(= the path of the page), 'selector' (= the CSS selector of the text area),
'timestamp' (= the current date) and 'extension' (the language extension when using
Firenvim on a code editor or txt otherwise).
'';
};
};
});
default = {
".*" = {
cmdline = "firenvim";
content = "text";
priority = 0;
renderer = "canvas";
selector = ''textarea:not([readonly]), div[role="textbox"]'';
takeover = "always";
filename = "{hostname%32}_{pathname%32}_{selector%32}_{timestamp%32}.{extension}";
};
};
description = ''
Configure firenvim for different urls. The keys are regex to match URL, and if multiple
regex match the URL then the value with the highest priority is choosen
'';
};
};
config = let
cfg = config.plugins.firenvim;
in
mkIf cfg.enable {
extraPlugins = with pkgs.vimPlugins; [firenvim];
globals.firenvim_config = {
globalSettings = cfg.global;
localSettings = cfg.local;
};
};
}

View file

@ -0,0 +1,22 @@
{
config,
lib,
pkgs,
...
}:
with lib; {
options.plugins.headerguard = {
enable = mkEnableOption "Enable headerguard";
useCppComment = mkEnableOption "Use c++-style comments instead of c-style";
};
config = let
cfg = config.plugins.headerguard;
in
mkIf cfg.enable {
extraPlugins = with pkgs.vimPlugins; [vim-headerguard];
globals.headerguard_use_cpp_comments = cfg.useCppComment;
};
}

View file

@ -0,0 +1,189 @@
{
config,
lib,
pkgs,
helpers,
...
}:
with lib; {
options.plugins.lsp_signature = {
enable = mkEnableOption "lsp_signature, a plugin to show function signatures";
package = mkOption {
type = types.package;
default = pkgs.vimPlugins.lsp_signature-nvim;
description = "Package to use for lsp_signature";
};
debug = {
enable = helpers.defaultNullOpts.mkBool false "set to true to enable debug logging";
logPath =
helpers.defaultNullOpts.mkNullable types.str
''vim.fn.stdpath("cache") .. "/lsp_signature.log"'' "log dir when debug is on";
verbose = helpers.defaultNullOpts.mkBool false "show debug line number";
};
bind = helpers.defaultNullOpts.mkBool true ''
This is mandatory, otherwise border config won't get registered.
If you want to hook lspsaga or other signature handler, pls set to false
'';
docLines = helpers.defaultNullOpts.mkInt 10 ''
will show two lines of comment/doc(if there are more than two lines in doc, will be truncated);
set to 0 if you DO NOT want any API comments be shown
This setting only take effect in insert mode, it does not affect signature help in normal
mode.
'';
maxHeight = helpers.defaultNullOpts.mkInt 12 "max height of signature floating_window";
maxWidth = helpers.defaultNullOpts.mkInt 82 "max_width of signature floating_window";
noice = helpers.defaultNullOpts.mkBool false "set to true if you using noice to render markdown";
wrap = helpers.defaultNullOpts.mkBool true ''
allow doc/signature text wrap inside floating_window, useful if your lsp return doc/sig is too
long
'';
floatingWindow = {
enable = helpers.defaultNullOpts.mkBool true ''
show hint in a floating window, set to false for virtual text only mode
'';
aboveCurLine = helpers.defaultNullOpts.mkBool true ''
try to place the floating above the current line when possible
Note:
will set to true when fully tested, set to false will use whichever side has more space
this setting will be helpful if you do not want the PUM and floating win overlap
'';
# NOTE: this could be functions, if need be we can adjust the types
offX = helpers.defaultNullOpts.mkInt 1 "adjust float windows x position";
offY = helpers.defaultNullOpts.mkInt 0 ''
adjust float windows y position. e.g -2 move window up 2 lines; 2 move down 2 lines
'';
};
closeTimeout = helpers.defaultNullOpts.mkInt 4000 ''
close floating window after ms when laster parameter is entered
'';
fixPos = helpers.defaultNullOpts.mkBool false ''
set to true, the floating window will not auto-close until finish all parameters
'';
hint = {
enable = helpers.defaultNullOpts.mkBool true "virtual hint enable";
prefix = helpers.defaultNullOpts.mkStr "🐼 " ''
Panda for parameter, NOTE: for the terminal not support emoji, might crash
'';
scheme = helpers.defaultNullOpts.mkStr "String" "";
};
hiParameter =
helpers.defaultNullOpts.mkStr "LspSignatureActiveParameter"
"how your parameter will be highlight";
handlerOpts = {
border = let
bordersTy =
types.enum ["double" "rounded" "single" "shadow" "none"];
in
helpers.defaultNullOpts.mkNullable (types.either bordersTy (types.listOf bordersTy))
''"rounded"'' "";
};
alwaysTrigger = helpers.defaultNullOpts.mkBool false ''
sometime show signature on new line or in middle of parameter can be confusing, set it to
false for #58
'';
autoCloseAfter = helpers.defaultNullOpts.mkNullable types.int "null" ''
autoclose signature float win after x sec, disabled if nil.
'';
extraTriggerChars = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
Array of extra characters that will trigger signature completion, e.g., ["(" ","]
'';
zindex = helpers.defaultNullOpts.mkInt 200 ''
by default it will be on top of all floating windows, set to <= 50 send it to bottom
'';
padding = helpers.defaultNullOpts.mkStr "" ''
character to pad on left and right of signature can be " ", or "|" etc
'';
transparency = helpers.defaultNullOpts.mkNullable types.int "null" ''
disabled by default, allow floating win transparent value 1~100
'';
shadowBlend = helpers.defaultNullOpts.mkInt 36 ''
if you using shadow as border use this set the opacity
'';
shadowGuibg = helpers.defaultNullOpts.mkStr "Black" ''
if you using shadow as border use this set the color e.g. "Green" or "#121315"
'';
timerInterval = helpers.defaultNullOpts.mkInt 200 ''
default timer check interval set to lower value if you want to reduce latency
'';
toggleKey = helpers.defaultNullOpts.mkNullable types.str "null" ''
toggle signature on and off in insert mode, e.g. "<M-x>"
'';
selectSignatureKey = helpers.defaultNullOpts.mkNullable types.str "null" ''
cycle to next signature, e.g. "<M-n>" function overloading
'';
moveCursorKey = helpers.defaultNullOpts.mkNullable types.str "null" ''
imap, use nvim_set_current_win to move cursor between current win and floating
'';
};
config = let
cfg = config.plugins.lsp_signature;
setupOptions = {
debug = cfg.debug.enable;
log_path = cfg.debug.logPath;
verbose = cfg.debug.verbose;
bind = cfg.bind;
doc_lines = cfg.docLines;
max_height = cfg.maxHeight;
noice = cfg.noice;
floating_window = cfg.floatingWindow.enable;
floating_window_above_cur_line = cfg.floatingWindow.aboveCurLine;
floating_window_off_x = cfg.floatingWindow.offX;
floating_window_off_y = cfg.floatingWindow.offY;
close_timeout = cfg.closeTimeout;
fix_pos = cfg.fixPos;
hint_enable = cfg.hint.enable;
hint_prefix = cfg.hint.prefix;
hint_scheme = cfg.hint.scheme;
hi_parameter = cfg.hiParameter;
handle_opts = {border = cfg.handlerOpts.border;};
always_trigger = cfg.alwaysTrigger;
auto_close_after = cfg.autoCloseAfter;
extra_trigger_chars = cfg.extraTriggerChars;
zindex = cfg.zindex;
padding = cfg.padding;
transparency = cfg.transparency;
shadow_blend = cfg.shadowBlend;
shadow_guibg = cfg.shadowGuibg;
timer_interval = cfg.timerInterval;
toggle_key = cfg.toggleKey;
select_signature_key = cfg.selectSignatureKey;
move_cursor_key = cfg.moveCursorKey;
};
in
mkIf cfg.enable {
extraPlugins = [cfg.package];
extraConfigLua = ''
require("lsp_signature").setup(${helpers.toLuaObject setupOptions})
'';
};
}