2023-03-15 16:41:44 +07:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
{
|
|
|
|
imports = [ ../options.nix ];
|
|
|
|
/*
|
|
|
|
VIM config backup:
|
|
|
|
syntax on
|
|
|
|
au FileType markdown set colorcolumn=73 textwidth=72
|
|
|
|
au FileType gitcommit set colorcolumn=73
|
|
|
|
highlight NormalFloat guibg=NONE
|
|
|
|
au BufReadPre * set foldmethod=syntax
|
|
|
|
au BufReadPost * folddoc foldopen!
|
|
|
|
autocmd BufReadPost * if @% !~# '\.git[\/\\]COMMIT_EDITMSG$' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
|
|
|
|
*/
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# welcome to my cursed DSL
|
2023-03-15 16:41:44 +07:00
|
|
|
programs.neovim = let
|
2023-03-15 17:43:16 +07:00
|
|
|
# add a single ident level to code
|
2023-03-15 16:41:44 +07:00
|
|
|
identLines = lines: builtins.concatStringsSep "\n" (map (x: " ${x}") lines);
|
|
|
|
ident = code: identLines (lib.splitString "\n" code);
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# wrap an expression in parentheses if necessary
|
2023-03-15 16:41:44 +07:00
|
|
|
# probably not the best heuristics, but good enough to make the output readable
|
|
|
|
wrapSafe = s: (builtins.match "^[-\"a-zA-Z0-9_.()]*$" s) != null;
|
|
|
|
wrapExpr = s: if wrapSafe s then s else "(${s})";
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Same, but for table keys
|
2023-03-15 16:41:44 +07:00
|
|
|
keySafe = s: (builtins.match "^[a-zA-Z_][_a-zA-Z0-9]*$" s) != null;
|
|
|
|
wrapKey = scope: s: if keySafe s then s else "[${compileExpr scope s}]";
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# The following functions take state: sname and scope
|
|
|
|
# sname is module name
|
|
|
|
# scope is how many variables are currently in scope
|
|
|
|
# the count is used for generating new variable names
|
|
|
|
|
2023-03-15 16:41:44 +07:00
|
|
|
compileFunc' = argn: sc@{sname,scope}: id: func:
|
|
|
|
(if builtins.isFunction func
|
|
|
|
then
|
|
|
|
(compileFunc'
|
|
|
|
(argn + 1)
|
|
|
|
sc
|
|
|
|
id
|
|
|
|
(func (let
|
|
|
|
args = builtins.functionArgs func;
|
|
|
|
rawVar = var "${sname}_${id}_arg${builtins.toString (scope + argn)}";
|
|
|
|
in if args == {}
|
|
|
|
then rawVar
|
|
|
|
else builtins.mapAttrs (k: v: prop rawVar k) args
|
|
|
|
)))
|
|
|
|
else ''
|
|
|
|
function ${id}(${builtins.concatStringsSep ", " (builtins.genList (n: "${sname}_${id}_arg${builtins.toString (scope + n)}") argn)})
|
|
|
|
${ident (compileStmt {inherit sname;scope = scope + argn;} func)}
|
|
|
|
end'');
|
|
|
|
compileFunc = compileFunc' 0;
|
2023-03-15 17:43:16 +07:00
|
|
|
|
2023-03-15 16:41:44 +07:00
|
|
|
compileExpr = sc: func: (
|
|
|
|
if builtins.isString func then
|
|
|
|
if lib.hasInfix "\n" func then ''
|
|
|
|
[[
|
|
|
|
${ident func}
|
|
|
|
]]'' else "\"${lib.escape ["\\" "\""] func}\""
|
|
|
|
else if builtins.isInt func then builtins.toString func
|
|
|
|
else if builtins.isFloat func then builtins.toString func
|
|
|
|
else if builtins.isBool func then (if func then "true" else "false")
|
|
|
|
else if builtins.isNull func then "nil"
|
|
|
|
else if builtins.isPath func then compileExpr sc (builtins.toString func)
|
|
|
|
else if builtins.isFunction func then let
|
|
|
|
info = if builtins.functionArgs func == {} then (func "GET_INFO") else null; in
|
2023-03-16 23:54:31 +07:00
|
|
|
if builtins.isAttrs info && info?_name
|
|
|
|
then info._name
|
2023-03-15 16:41:44 +07:00
|
|
|
else (compileFunc sc "" func)
|
|
|
|
else if builtins.isList func then ''
|
|
|
|
{
|
|
|
|
${ident (builtins.concatStringsSep "\n" (map (x: (compileExpr sc x) + ";" ) func))}
|
|
|
|
}''
|
|
|
|
else if builtins.isAttrs func && !(func?__kind) then ''
|
|
|
|
{
|
|
|
|
${ident (builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${wrapKey sc k} = ${compileExpr sc v};") func))}
|
|
|
|
}''
|
|
|
|
else if func.__kind == "var" then
|
|
|
|
"${func._name}"
|
|
|
|
else if func.__kind == "op2" then
|
|
|
|
builtins.concatStringsSep func.op (map (x: wrapExpr (compileExpr sc x)) func.args)
|
|
|
|
else if func.__kind == "defun" then
|
|
|
|
(compileFunc sc (if func?id then func.id else "") func.func)
|
|
|
|
else if func.__kind == "prop" then
|
|
|
|
"${wrapExpr (compileExpr sc func.expr)}.${func.name}"
|
|
|
|
else if func.__kind == "call" then
|
2023-03-16 23:54:31 +07:00
|
|
|
let args = if builtins.isList func._args then func._args else [func._args]; in
|
|
|
|
assert (lib.assertMsg
|
|
|
|
((!(func._func?_minArity) || (builtins.length args) >= func._func._minArity) && (!(func._func?_maxArity) || (builtins.length args) <= func._func._maxArity))
|
|
|
|
"error: wrong function arity for ${compileExpr sc func._func}! expected at least ${builtins.toString func._func._minArity}; found ${builtins.toString (builtins.length args)}");
|
|
|
|
"${wrapExpr (compileExpr sc func._func)}(${builtins.concatStringsSep ", " (map (compileExpr sc) args)})"
|
2023-03-15 16:41:44 +07:00
|
|
|
else if func.__kind == "mcall" then
|
|
|
|
"${wrapExpr (compileExpr sc func.val)}:${func.name}(${builtins.concatStringsSep ", " (map (compileExpr sc) (if builtins.isList func.args then func.args else [func.args]))})"
|
|
|
|
else if func.__kind == "tableAttr" then
|
|
|
|
"${wrapExpr (compileExpr sc func.table)}[${compileExpr sc func.key}]"
|
|
|
|
else null
|
|
|
|
);
|
2023-03-15 17:43:16 +07:00
|
|
|
|
2023-03-15 16:41:44 +07:00
|
|
|
compileStmt = sc@{sname,scope}: func: (
|
|
|
|
if builtins.isList func then builtins.concatStringsSep "\n" (map (compileStmt sc) func)
|
|
|
|
else if builtins.isAttrs func && (func?__kind) then (
|
|
|
|
if func.__kind == "assign" then
|
|
|
|
"${compileExpr sc func.expr} = ${compileExpr sc func.val}"
|
|
|
|
else if func.__kind == "bind" then
|
|
|
|
"local ${func.name} = ${compileExpr sc func.val}"
|
|
|
|
else if func.__kind == "let" then ''
|
|
|
|
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
|
|
|
"local ${sname}_var${builtins.toString (scope + n)} = ${
|
|
|
|
compileExpr sc val
|
|
|
|
}") func.vals)}
|
|
|
|
${let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
|
|
|
scope = scope + 1;
|
|
|
|
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
|
|
}; in
|
|
|
|
compileStmt {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; inherit (func) func; })
|
|
|
|
}''
|
|
|
|
else if func.__kind == "letrec" then ''
|
|
|
|
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
|
|
|
"local ${sname}_var${builtins.toString (scope + n)} = ${
|
|
|
|
let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
|
|
|
scope = scope + 1;
|
|
|
|
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
|
|
}; in
|
|
|
|
compileExpr {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; func = val; })
|
|
|
|
}") func.vals)}
|
|
|
|
${let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
|
|
|
scope = scope + 1;
|
|
|
|
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
|
|
}; in
|
|
|
|
compileStmt {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; inherit (func) func; })
|
|
|
|
}''
|
|
|
|
else if func.__kind == "for" then let
|
|
|
|
varNames = builtins.genList (n: "${sname}_var${builtins.toString (scope + n)}") func.n;
|
|
|
|
scope' = { inherit sname; scope = scope + 1; };
|
|
|
|
in ''
|
|
|
|
for ${builtins.concatStringsSep "," varNames} in ${compileExpr scope' func.expr} do
|
|
|
|
${
|
|
|
|
let argn = func.n; origScope = scope; apply = { scope, func }: if scope == (origScope + argn) then func else apply {
|
|
|
|
scope = scope + 1;
|
|
|
|
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
|
|
}; in
|
|
|
|
ident (compileStmt scope' (apply { inherit scope; func = func.body; }))
|
|
|
|
}
|
|
|
|
end''
|
|
|
|
else if func.__kind == "return" then
|
|
|
|
"return ${compileExpr sc func.expr}"
|
|
|
|
else if func.__kind == "if" then
|
|
|
|
(lib.removeSuffix "else" ((builtins.concatStringsSep "" (map
|
|
|
|
(cond: ''
|
|
|
|
if ${compileExpr sc (builtins.elemAt cond 0)} then
|
|
|
|
${ident (compileStmt sc (builtins.elemAt cond 1))}
|
|
|
|
else'')
|
|
|
|
func.conds))
|
|
|
|
+ (if func.fallback != null then "\n${ident (compileStmt sc func.fallback)}\n" else ""))) + "end"
|
|
|
|
else compileExpr sc func
|
|
|
|
) else compileExpr sc func
|
|
|
|
);
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# compile a module
|
|
|
|
compile = sname: input: (compileStmt {inherit sname;scope=1;} input) + "\n";
|
|
|
|
# pass some raw code to lua directly
|
2023-03-15 16:41:44 +07:00
|
|
|
var = name: { __kind = "var"; _name = name; };
|
|
|
|
raw = var;
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Access a property
|
|
|
|
# Corresponding lua code: table.property
|
|
|
|
# expr -> identifier -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
prop = expr: name: { __kind = "prop"; inherit expr name; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Call a function
|
|
|
|
# corresponding lua code: someFunc()
|
|
|
|
# expr -> [args] -> expr | expr -> arg1 -> expr
|
2023-03-16 23:37:57 +07:00
|
|
|
call = func: args: { __kind = "call"; _func = func; _args = args; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Call a method
|
|
|
|
# corresponding lua code: someTable:someFunc()
|
|
|
|
# expr -> identifier -> [args] -> expr | expr -> identifier -> arg1 -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
mcall = val: name: args: { __kind = "mcall"; inherit val name args; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# corresponding lua code: =
|
|
|
|
# expr -> expr -> stmt
|
2023-03-15 16:41:44 +07:00
|
|
|
set = expr: val: { __kind = "assign"; inherit expr val; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# opName -> expr1 -> expr2 -> expr | opName -> [exprs] -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
op2 = op: args:
|
|
|
|
if builtins.isList args then { __kind = "op2"; inherit op args; }
|
|
|
|
else (secondArg: { __kind = "op2"; inherit op; args = [ args secondArg ]; })
|
|
|
|
;
|
2023-03-15 17:43:16 +07:00
|
|
|
# The following all have the signature
|
|
|
|
# expr1 -> expr2 -> expr2 | [exprs] -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
eq = op2 "==";
|
|
|
|
# gt = op2 ">";
|
|
|
|
# ge = op2 ">=";
|
|
|
|
# ne = op2 "~=";
|
|
|
|
# and = op2 "and";
|
|
|
|
# or = op2 "or";
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Corresponding lua code: for
|
|
|
|
# argc -> expr -> (expr1 -> ... -> exprN -> stmts) -> stmts
|
|
|
|
# forin = n: expr: body: { __kind = "for"; inherit n expr body; };
|
|
|
|
|
|
|
|
# Issues a return statement
|
|
|
|
# Corresponding lua code: return
|
|
|
|
# expr -> stmt
|
2023-03-15 16:41:44 +07:00
|
|
|
return = expr: { __kind = "return"; inherit expr; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Creates a zero argument function with user-provided statements
|
|
|
|
# stmts -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
defun = func: { __kind = "defun"; inherit func; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Corresponding lua code: if then else
|
|
|
|
# [[cond expr]] -> fallbackExpr -> stmts
|
2023-03-15 16:41:44 +07:00
|
|
|
ifelse = conds: fallback: { __kind = "if"; inherit fallback; conds = if builtins.isList (builtins.elemAt conds 0) then conds else [conds]; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Corresponding lua code: if then
|
|
|
|
# [[cond expr]] -> > stmts
|
2023-03-15 16:41:44 +07:00
|
|
|
# ifnoelse = conds: ifelse conds null;
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Corresponding lua code: table[key]
|
|
|
|
# table -> key -> expr
|
2023-03-15 16:41:44 +07:00
|
|
|
tableAttr = table: key: { __kind = "tableAttr"; inherit table key; };
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Directly creates a local varible with your chosen name
|
|
|
|
# But why would you use this???
|
|
|
|
# bind' = name: val: { __kind = "bind"; inherit name val; };
|
|
|
|
|
|
|
|
# Creates variables and passes them to the function
|
|
|
|
# Corresponding lua code: local ... = ...
|
|
|
|
# [expr] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
2023-03-15 16:41:44 +07:00
|
|
|
bind = vals: func: if builtins.isList vals then { __kind = "let"; inherit vals func; } else bind [ vals ] func;
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# Creates variables and passes them to the function as well as variable binding code
|
|
|
|
# Corresponding lua code: local ... = ...
|
|
|
|
# [(expr1 -> ... -> exprN -> expr)] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
2023-03-15 16:41:44 +07:00
|
|
|
bindrec = vals: func: if builtins.isList vals then { __kind = "letrec"; inherit vals func; } else bindrec [ vals ] func;
|
2023-03-15 17:43:16 +07:00
|
|
|
|
|
|
|
# "type definitions" for neovim
|
2023-03-16 23:37:57 +07:00
|
|
|
defs = pkgs.callPackage ./vim-opts.nix { inherit raw call; plugins = config.programs.neovim.plugins; };
|
|
|
|
reqbind = name: func: bind [ (defs.require name) ] (result: func (defs._reqbind name result._name));
|
2023-03-15 16:41:44 +07:00
|
|
|
in with defs; let
|
2023-03-16 23:37:57 +07:00
|
|
|
# require = name: call (var "require") [ name ];
|
|
|
|
# setup = plugin: opts: call (prop plugin "setup") [ opts ];
|
2023-03-15 16:41:44 +07:00
|
|
|
# vimfn = name: call (raw "vim.fn.${name}");
|
|
|
|
vimcmd = name: call (raw "vim.cmd.${name}");
|
2023-03-16 23:37:57 +07:00
|
|
|
vimg = name: prop vim.g name;
|
2023-03-15 16:41:44 +07:00
|
|
|
keymapSetSingle = opts@{
|
|
|
|
mode,
|
|
|
|
lhs,
|
|
|
|
rhs,
|
|
|
|
noremap ? true,
|
|
|
|
silent ? true,
|
|
|
|
...
|
|
|
|
}: let
|
2023-03-15 19:14:37 +07:00
|
|
|
opts'' = opts // { inherit noremap silent; };
|
2023-03-15 16:41:44 +07:00
|
|
|
opts' = lib.filterAttrs (k: v:
|
|
|
|
k != "keys" && k != "mode" && k != "lhs" && k != "rhs" && k != "desc"
|
|
|
|
# defaults to false
|
2023-03-15 19:14:37 +07:00
|
|
|
&& ((k != "silent" && k != "noremap") || (builtins.isBool v && v))) opts'';
|
2023-03-15 16:41:44 +07:00
|
|
|
in vim.keymap.set [ mode lhs rhs opts' ];
|
|
|
|
keymapSetMulti = opts@{
|
|
|
|
keys,
|
|
|
|
mode,
|
|
|
|
noremap ? true,
|
|
|
|
silent ? true,
|
|
|
|
...
|
|
|
|
}: let
|
|
|
|
opts'' = opts // { inherit noremap silent; };
|
|
|
|
opts' = lib.filterAttrs (k: v:
|
|
|
|
k != "keys" && k != "lhs" && k != "rhs" && k != "desc"
|
|
|
|
# defaults to false
|
|
|
|
&& ((k != "silent" && k != "noremap") || (builtins.isBool v && v))) opts'';
|
|
|
|
in (lib.mapAttrsToList (k: {rhs, desc}: keymapSetSingle (opts' // {
|
|
|
|
lhs = k; inherit rhs;
|
|
|
|
})) keys) ++ [
|
2023-03-16 23:37:57 +07:00
|
|
|
(which-key.register [(lib.mapAttrs (k: v: [v.rhs v.desc]) keys) opts'])
|
2023-03-15 16:41:44 +07:00
|
|
|
];
|
|
|
|
keymapSetNs = args: keymapSetMulti (args // { mode = "n"; });
|
|
|
|
kmSetNs = keys: keymapSetNs { inherit keys; };
|
2023-03-15 17:43:16 +07:00
|
|
|
keymapSetVs = args: keymapSetMulti (args // { mode = "v"; });
|
|
|
|
kmSetVs = keys: keymapSetVs { inherit keys; };
|
2023-03-16 23:37:57 +07:00
|
|
|
|
|
|
|
which-key = req "which-key";
|
|
|
|
luasnip = req "luasnip";
|
|
|
|
cmp = req "cmp";
|
2023-03-15 16:41:44 +07:00
|
|
|
in {
|
|
|
|
enable = true;
|
|
|
|
defaultEditor = true;
|
|
|
|
package = pkgs.neovim-unwrapped;
|
|
|
|
extraPackages = with pkgs; [
|
|
|
|
rust-analyzer
|
|
|
|
nodePackages_latest.bash-language-server shellcheck
|
|
|
|
nodePackages_latest.typescript-language-server
|
|
|
|
nodePackages_latest.svelte-language-server
|
2023-03-16 23:37:57 +07:00
|
|
|
clang-tools_latest
|
2023-03-15 16:41:44 +07:00
|
|
|
nodePackages_latest.vscode-langservers-extracted
|
|
|
|
nil
|
|
|
|
marksman
|
|
|
|
taplo
|
2023-03-15 19:14:37 +07:00
|
|
|
ripgrep
|
2023-03-15 16:41:44 +07:00
|
|
|
(python3.withPackages (p: with p; [
|
|
|
|
python-lsp-server
|
|
|
|
pylsp-mypy
|
|
|
|
python-lsp-server.optional-dependencies.pyflakes
|
|
|
|
python-lsp-server.optional-dependencies.mccabe
|
|
|
|
python-lsp-server.optional-dependencies.pycodestyle
|
|
|
|
]))
|
|
|
|
];
|
|
|
|
# extraPython3Packages = pyPkgs: with pyPkgs; [
|
|
|
|
# ];
|
2023-03-16 23:37:57 +07:00
|
|
|
viAlias = true;
|
|
|
|
vimAlias = true;
|
|
|
|
vimdiffAlias = true;
|
|
|
|
|
2023-03-15 16:41:44 +07:00
|
|
|
extraLuaConfig = (compile "main" [
|
2023-03-16 23:37:57 +07:00
|
|
|
(set (vimg "vimsyn_embed") "l")
|
2023-03-15 16:41:44 +07:00
|
|
|
(bind (vim.api.nvim_create_augroup [ "nvimrc" { clear = true; } ]) (group:
|
|
|
|
map (au: let au' = lib.filterAttrs (k: v: k != "event") au;
|
|
|
|
in vim.api.nvim_create_autocmd [ au.event ({
|
|
|
|
inherit group;
|
|
|
|
} // au') ]
|
|
|
|
) [
|
|
|
|
{ event = "FileType";
|
|
|
|
pattern = ["markdown" "gitcommit"];
|
2023-03-16 23:37:57 +07:00
|
|
|
# must be a string
|
2023-03-15 17:43:16 +07:00
|
|
|
callback = defun (set vim.o.colorcolumn "73"); }
|
2023-03-15 16:41:44 +07:00
|
|
|
{ event = "FileType";
|
|
|
|
pattern = ["markdown"];
|
2023-03-16 23:37:57 +07:00
|
|
|
# must be a number...
|
|
|
|
callback = defun (set vim.o.textwidth 72); }
|
2023-03-15 16:41:44 +07:00
|
|
|
{ event = "BufReadPre";
|
|
|
|
callback = defun (set vim.o.foldmethod "syntax"); }
|
|
|
|
{ event = "BufWinEnter";
|
|
|
|
callback = { buf, ... }:
|
|
|
|
(bind (vim.filetype.match { inherit buf; }) (filetype: [
|
|
|
|
(vimcmd "folddoc" [ "foldopen!" ])
|
|
|
|
(ifelse [(eq filetype "gitcommit") [
|
2023-03-16 23:37:57 +07:00
|
|
|
(call vim.cmd {
|
2023-03-15 16:41:44 +07:00
|
|
|
cmd = "normal";
|
|
|
|
bang = true;
|
|
|
|
args = [ "gg" ];
|
|
|
|
})
|
|
|
|
]]
|
2023-03-16 23:37:57 +07:00
|
|
|
(call vim.cmd {
|
2023-03-15 16:41:44 +07:00
|
|
|
cmd = "normal";
|
|
|
|
bang = true;
|
|
|
|
args = [ "g`\"" ];
|
|
|
|
})
|
|
|
|
)
|
|
|
|
])); }
|
|
|
|
])) # END
|
|
|
|
]);
|
2023-03-16 23:37:57 +07:00
|
|
|
plugins = let ps = pkgs.vimPlugins; in map (x: if x?config && x?plugin then { type = "lua"; } // x else x) [
|
|
|
|
ps.vim-svelte
|
2023-03-15 16:41:44 +07:00
|
|
|
# TODO remove on next nvim update (0.8.3/0.9)
|
2023-03-16 23:37:57 +07:00
|
|
|
ps.vim-nix
|
2023-03-15 16:41:44 +07:00
|
|
|
{ plugin = pkgs.vimUtils.buildVimPluginFrom2Nix {
|
|
|
|
pname = "vscode-nvim";
|
|
|
|
version = "2023-02-10";
|
|
|
|
src = pkgs.fetchFromGitHub {
|
|
|
|
owner = "Mofiqul";
|
|
|
|
repo = "vscode.nvim";
|
|
|
|
rev = "db9ee339b5556aa832ca58871fd18f9467a18520";
|
|
|
|
sha256 = "sha256-X2IgIjO5NNq7vJdl09hBY1TFqHlsfF1xfllKr4osILI=";
|
|
|
|
};
|
|
|
|
};
|
2023-03-16 23:37:57 +07:00
|
|
|
config = compile "vscode_nvim" [
|
|
|
|
((req "vscode").setup {
|
|
|
|
transparent = true;
|
|
|
|
color_overrides = {
|
|
|
|
vscGray = "#745b5f";
|
|
|
|
vscViolet = "#${config.colors.magenta}";
|
|
|
|
vscBlue = "#6ddfd8";
|
|
|
|
vscDarkBlue = "#${config.colors.blue}";
|
|
|
|
vscGreen = "#${config.colors.green}";
|
|
|
|
vscBlueGreen = "#73bf88";
|
|
|
|
vscLightGreen = "#6acf6e";
|
|
|
|
vscRed = "#${config.colors.red}";
|
|
|
|
vscOrange = "#e89666";
|
|
|
|
vscLightRed = "#e64e4e";
|
|
|
|
vscYellowOrange = "#e8b166";
|
|
|
|
vscYellow = "#${config.colors.yellow}";
|
|
|
|
vscPink = "#cf83c4";
|
|
|
|
};
|
|
|
|
})
|
|
|
|
(vim.api.nvim_set_hl [ 0 "NormalFloat" {
|
|
|
|
bg = "NONE";
|
|
|
|
}])
|
|
|
|
]; }
|
|
|
|
{ plugin = ps.nvim-web-devicons;
|
|
|
|
config = compile "nvim_web_devicons" ((req "nvim-web-devicons").setup {}); }
|
|
|
|
{ plugin = ps.nvim-tree-lua;
|
2023-03-15 16:41:44 +07:00
|
|
|
config = compile "nvim_tree_lua" [
|
2023-03-16 23:37:57 +07:00
|
|
|
(set (vimg "loaded_netrw") 1)
|
|
|
|
(set (vimg "loaded_netrwPlugin") 1)
|
|
|
|
(set vim.o.termguicolors true)
|
|
|
|
((req "nvim-tree").setup {}) # :help nvim-tree-setup
|
2023-03-15 17:43:16 +07:00
|
|
|
(kmSetNs {
|
|
|
|
"<C-N>" = {
|
2023-03-16 23:37:57 +07:00
|
|
|
rhs = (req "nvim-tree.api").tree.toggle;
|
2023-03-15 17:43:16 +07:00
|
|
|
desc = "Toggle NvimTree";
|
|
|
|
};
|
2023-03-15 16:41:44 +07:00
|
|
|
})
|
|
|
|
]; }
|
2023-03-16 23:37:57 +07:00
|
|
|
ps.vim-sleuth
|
|
|
|
ps.luasnip
|
|
|
|
{ plugin = ps.nvim-cmp;
|
2023-03-15 16:41:44 +07:00
|
|
|
config = let
|
|
|
|
border = (name: [
|
|
|
|
[ "╭" name ]
|
|
|
|
[ "─" name ]
|
|
|
|
[ "╮" name ]
|
|
|
|
[ "│" name ]
|
|
|
|
[ "╯" name ]
|
|
|
|
[ "─" name ]
|
|
|
|
[ "╰" name ]
|
|
|
|
[ "│" name ]
|
|
|
|
]);
|
2023-03-16 23:37:57 +07:00
|
|
|
in compile "nvim_cmp" (reqbind "cmp" (cmp:
|
|
|
|
# call is required because cmp.setup is a table
|
|
|
|
(call cmp.setup {
|
2023-03-15 16:41:44 +07:00
|
|
|
snippet = {
|
2023-03-16 23:54:31 +07:00
|
|
|
expand = { body, ... }: luasnip.lsp_expand [ body {} ];
|
2023-03-15 16:41:44 +07:00
|
|
|
};
|
|
|
|
view = { };
|
|
|
|
window = {
|
|
|
|
completion = {
|
|
|
|
border = border "CmpBorder";
|
|
|
|
winhighlight = "Normal:CmpPmenu,CursorLine:PmenuSel,Search:None";
|
|
|
|
};
|
|
|
|
documentation = {
|
|
|
|
border = border "CmpDocBorder";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
formatting = {
|
2023-03-15 18:55:46 +07:00
|
|
|
format = _: vim_item: let kind = prop vim_item "kind"; in [
|
2023-03-15 16:41:44 +07:00
|
|
|
(set
|
2023-03-15 18:55:46 +07:00
|
|
|
kind
|
2023-03-16 23:37:57 +07:00
|
|
|
(string.format [
|
2023-03-15 16:41:44 +07:00
|
|
|
"%s %s"
|
2023-03-16 23:37:57 +07:00
|
|
|
(tableAttr (req "lspkind") kind)
|
2023-03-15 16:41:44 +07:00
|
|
|
kind
|
2023-03-16 23:37:57 +07:00
|
|
|
]))
|
2023-03-15 16:41:44 +07:00
|
|
|
(return vim_item)
|
|
|
|
];
|
|
|
|
};
|
|
|
|
mapping = {
|
2023-03-16 23:54:31 +07:00
|
|
|
"<C-p>" = cmp.mapping.select_prev_item [{}];
|
|
|
|
"<C-n>" = cmp.mapping.select_next_item [{}];
|
|
|
|
"<C-space>" = cmp.mapping.complete [{}];
|
|
|
|
"<C-e>" = cmp.mapping.close [{}];
|
2023-03-16 23:37:57 +07:00
|
|
|
"<cr>" = cmp.mapping.confirm {
|
|
|
|
behavior = cmp.ConfirmBehavior.Replace;
|
2023-03-15 16:41:44 +07:00
|
|
|
select = false;
|
|
|
|
};
|
2023-03-16 23:37:57 +07:00
|
|
|
"<tab>" = call cmp.mapping [(fallback:
|
|
|
|
(ifelse [[(cmp.visible [])
|
|
|
|
(cmp.select_next_item [])]
|
|
|
|
/*elseif*/ [(luasnip.expand_or_jumpable [])
|
|
|
|
(vim.api.nvim_feedkeys [
|
|
|
|
(vim.api.nvim_replace_termcodes [ "<Plug>luasnip-expand-or-jump" true true true ])
|
|
|
|
""
|
|
|
|
false
|
|
|
|
])
|
|
|
|
]] # else
|
|
|
|
(call fallback [])
|
2023-03-15 16:41:44 +07:00
|
|
|
))
|
|
|
|
[ "i" "s" ]
|
|
|
|
];
|
2023-03-16 23:37:57 +07:00
|
|
|
"<S-tab>" = call cmp.mapping [(fallback:
|
|
|
|
(ifelse [[(cmp.visible [])
|
|
|
|
(cmp.select_prev_item [])]
|
|
|
|
/*elseif*/ [(luasnip.jumpable [ (-1) ])
|
|
|
|
(vim.api.nvim_feedkeys [
|
|
|
|
(vim.api.nvim_replace_termcodes [ "<Plug>luasnip-jump-prev" true true true ])
|
|
|
|
""
|
|
|
|
false
|
|
|
|
])
|
|
|
|
]] # else
|
|
|
|
(call fallback [])
|
2023-03-15 16:41:44 +07:00
|
|
|
))
|
|
|
|
[ "i" "s" ]
|
|
|
|
];
|
|
|
|
};
|
2023-03-16 23:37:57 +07:00
|
|
|
sources = cmp.config.sources [[
|
2023-03-15 16:41:44 +07:00
|
|
|
{ name = "nvim_lsp"; }
|
|
|
|
{ name = "luasnip"; }
|
|
|
|
]];
|
|
|
|
})
|
2023-03-15 17:43:16 +07:00
|
|
|
)); }
|
2023-03-16 23:37:57 +07:00
|
|
|
ps.lspkind-nvim
|
|
|
|
ps.cmp_luasnip
|
|
|
|
ps.cmp-nvim-lsp
|
|
|
|
{ plugin = ps.nvim-autopairs;
|
|
|
|
config = compile "nvim_autopairs" (reqbind "nvim-autopairs.completion.cmp" (cmp_autopairs: [
|
|
|
|
((req "nvim-autopairs").setup {
|
2023-03-15 16:41:44 +07:00
|
|
|
disable_filetype = [ "TelescopePrompt" "vim" ];
|
|
|
|
})
|
2023-03-16 23:37:57 +07:00
|
|
|
(mcall cmp.event "on" [
|
2023-03-15 16:41:44 +07:00
|
|
|
"confirm_done"
|
2023-03-16 23:54:31 +07:00
|
|
|
(cmp_autopairs.on_confirm_done [{}])
|
2023-03-15 16:41:44 +07:00
|
|
|
])
|
|
|
|
])); }
|
2023-03-16 23:37:57 +07:00
|
|
|
{ plugin = ps.comment-nvim;
|
2023-03-15 16:41:44 +07:00
|
|
|
config = compile "comment_nvim" [
|
2023-03-16 23:37:57 +07:00
|
|
|
((req "Comment").setup {})
|
2023-03-15 17:43:16 +07:00
|
|
|
(kmSetNs {
|
|
|
|
"<space>/" = {
|
2023-03-16 23:37:57 +07:00
|
|
|
rhs = prop (req "Comment.api").toggle "linewise.current";
|
2023-03-15 17:43:16 +07:00
|
|
|
desc = "Comment current line";
|
|
|
|
};
|
2023-03-15 16:41:44 +07:00
|
|
|
})
|
2023-03-15 17:43:16 +07:00
|
|
|
(kmSetVs {
|
|
|
|
"<space>/" = {
|
|
|
|
rhs = "<esc><cmd>lua require('Comment.api').toggle.linewise(vim.fn.visualmode())<cr>";
|
|
|
|
desc = "Comment selection";
|
|
|
|
};
|
2023-03-15 16:41:44 +07:00
|
|
|
})
|
|
|
|
]; }
|
2023-03-16 23:37:57 +07:00
|
|
|
{ plugin = ps.nvim-lspconfig;
|
|
|
|
config = compile "nvim_lspconfig" (let setupLsp = lsp: builtins.seq (req "lspconfig.server_configurations.${lsp}") (call (prop (req "lspconfig") "${lsp}.setup")); in [
|
2023-03-15 16:41:44 +07:00
|
|
|
# See `:help vim.diagnostic.*` for documentation on any of the below functions
|
|
|
|
(kmSetNs {
|
|
|
|
"<space>e" = {
|
|
|
|
rhs = vim.diagnostic.open_float;
|
|
|
|
desc = "Show diagnostics in a floating window.";
|
|
|
|
};
|
|
|
|
"[d" = {
|
|
|
|
rhs = vim.diagnostic.goto_prev;
|
|
|
|
desc = "Move to the previous diagnostic in the current buffer.";
|
|
|
|
};
|
|
|
|
"]d" = {
|
|
|
|
rhs = vim.diagnostic.goto_next;
|
|
|
|
desc = "Get the next diagnostic closest to the cursor position.";
|
|
|
|
};
|
|
|
|
"<space>q" = {
|
|
|
|
rhs = vim.diagnostic.setloclist;
|
|
|
|
desc = "Add buffer diagnostics to the location list.";
|
|
|
|
};
|
|
|
|
})
|
|
|
|
(bind [
|
|
|
|
# LET on_attach
|
|
|
|
(client: bufnr: ([
|
|
|
|
# Enable completion triggered by <c-x><c-o>
|
|
|
|
(vim.api.nvim_buf_set_option [ bufnr "omnifunc" "v:lua.vim.lsp.omnifunc" ])
|
|
|
|
# Mappings.
|
|
|
|
# See `:help vim.lsp.*` for documentation on any of the below functions
|
|
|
|
(kmSetNs {
|
|
|
|
"gD" = {
|
|
|
|
rhs = vim.lsp.buf.declaration;
|
|
|
|
desc = "Jumps to the declaration of the symbol under the cursor."; };
|
|
|
|
"gd" = {
|
|
|
|
rhs = vim.lsp.buf.definition;
|
|
|
|
desc = "Jumps to the definition of the symbol under the cursor."; };
|
|
|
|
"K" = {
|
|
|
|
rhs = vim.lsp.buf.hover;
|
|
|
|
desc = "Displays hover information about the symbol under the cursor in a floating window."; };
|
|
|
|
"gi" = {
|
|
|
|
rhs = vim.lsp.buf.implementation;
|
|
|
|
desc = "Lists all the implementations for the symbol under the cursor in the quickfix window."; };
|
|
|
|
"<C-h>" = {
|
|
|
|
rhs = vim.lsp.buf.signature_help;
|
|
|
|
desc = "Displays signature information about the symbol under the cursor in a floating window."; };
|
|
|
|
"<space>wa" = {
|
|
|
|
rhs = vim.lsp.buf.add_workspace_folder;
|
|
|
|
desc = "Add a folder to the workspace folders."; };
|
|
|
|
"<space>wr" = {
|
|
|
|
rhs = vim.lsp.buf.remove_workspace_folder;
|
|
|
|
desc = "Remove a folder from the workspace folders."; };
|
|
|
|
"<space>wl" = {
|
|
|
|
rhs = (defun (print [
|
2023-03-16 23:37:57 +07:00
|
|
|
(call vim.inspect [(vim.lsp.buf.list_workspace_folders [])])
|
2023-03-15 16:41:44 +07:00
|
|
|
]));
|
|
|
|
desc = "List workspace folders."; };
|
|
|
|
"<space>D" = {
|
|
|
|
rhs = vim.lsp.buf.type_definition;
|
|
|
|
desc = "Jumps to the definition of the type of the symbol under the cursor."; };
|
|
|
|
"<space>rn" = {
|
|
|
|
rhs = vim.lsp.buf.rename;
|
|
|
|
desc = "Rename old_fname to new_fname"; };
|
|
|
|
"<space>ca" = {
|
|
|
|
rhs = vim.lsp.buf.code_action;
|
|
|
|
desc = "Selects a code action available at the current cursor position."; };
|
|
|
|
"gr" = {
|
|
|
|
rhs = vim.lsp.buf.references;
|
|
|
|
desc = "Lists all the references to the symbol under the cursor in the quickfix window."; };
|
|
|
|
"<space>f" = {
|
|
|
|
rhs = (defun (vim.lsp.buf.format {async = true;}));
|
|
|
|
desc = "Formats a buffer."; };
|
|
|
|
})
|
|
|
|
]))
|
|
|
|
# LET rust_settings
|
|
|
|
{ rust-analyzer = {
|
|
|
|
assist.emitMustUse = true;
|
|
|
|
cargo.buildScripts.enable = true;
|
|
|
|
check.command = "clippy";
|
|
|
|
procMacro.enable = true;
|
|
|
|
}; }
|
|
|
|
# LET capabilities
|
|
|
|
(vim.tbl_extend [
|
|
|
|
"keep"
|
2023-03-16 23:54:31 +07:00
|
|
|
((req "cmp_nvim_lsp").default_capabilities [{}])
|
2023-03-15 16:41:44 +07:00
|
|
|
(vim.lsp.protocol.make_client_capabilities [])
|
|
|
|
])
|
|
|
|
# BEGIN
|
|
|
|
] (on_attach: rust_settings: capabilities: [
|
|
|
|
(bindrec
|
|
|
|
# LETREC on_attach_rust
|
|
|
|
(on_attach_rust: client: bufnr: [
|
|
|
|
(vim.api.nvim_create_user_command ["RustAndroid" (opts: [
|
2023-03-16 23:37:57 +07:00
|
|
|
(vim.lsp.set_log_level "debug")
|
2023-03-15 16:41:44 +07:00
|
|
|
(setupLsp "rust_analyzer" {
|
|
|
|
on_attach = on_attach_rust;
|
|
|
|
inherit capabilities;
|
|
|
|
settings = vim.tbl_deep_extend [
|
|
|
|
"keep"
|
2023-03-16 23:37:57 +07:00
|
|
|
config.rustAnalyzerAndroidSettings
|
2023-03-15 16:41:44 +07:00
|
|
|
rust_settings
|
|
|
|
];
|
|
|
|
})
|
|
|
|
]) {}])
|
|
|
|
(call on_attach [client bufnr])
|
|
|
|
])
|
|
|
|
# BEGIN
|
2023-03-15 19:14:37 +07:00
|
|
|
(let lsp' = { name, settings ? {} }: setupLsp name {
|
2023-03-15 16:41:44 +07:00
|
|
|
inherit on_attach capabilities settings;
|
2023-03-15 19:14:37 +07:00
|
|
|
}; lsp = args: lsp' (if builtins.isString args then { name = args; } else args); in (on_attach_rust: [
|
|
|
|
# (vim.lsp.set_log_level "debug")
|
2023-03-15 16:41:44 +07:00
|
|
|
(map lsp [
|
|
|
|
# see https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
2023-03-15 19:14:37 +07:00
|
|
|
"bashls"
|
|
|
|
"clangd"
|
2023-03-15 16:41:44 +07:00
|
|
|
# https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md
|
|
|
|
{ name = "pylsp"; settings = {
|
|
|
|
pylsp.plugins.pylsp_mypy.enabled = true;
|
|
|
|
}; }
|
2023-03-15 19:14:37 +07:00
|
|
|
"svelte"
|
|
|
|
"html"
|
|
|
|
"cssls"
|
|
|
|
"tsserver"
|
|
|
|
"jsonls"
|
|
|
|
"nil_ls"
|
|
|
|
"taplo"
|
|
|
|
"marksman"
|
2023-03-15 16:41:44 +07:00
|
|
|
])
|
|
|
|
(setupLsp "rust_analyzer" {
|
|
|
|
on_attach = on_attach_rust;
|
|
|
|
settings = rust_settings;
|
|
|
|
inherit capabilities;
|
|
|
|
})
|
|
|
|
]))) # END
|
|
|
|
])) # END
|
|
|
|
]); }
|
2023-03-16 23:37:57 +07:00
|
|
|
{ plugin = ps.which-key-nvim;
|
2023-03-15 16:41:44 +07:00
|
|
|
config = compile "which_key_nvim" [
|
|
|
|
(set vim.o.timeout true)
|
|
|
|
(set vim.o.timeoutlen 500)
|
2023-03-16 23:37:57 +07:00
|
|
|
(which-key.setup {})
|
2023-03-15 16:41:44 +07:00
|
|
|
]; }
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}
|