Skip to content

Commit

Permalink
lsp cleanup (#21)
Browse files Browse the repository at this point in the history
* refactor: clean up snippet/completion code

Also deleted null-ls, no longer maintained / needed IMO

* refactor(lsp): use submodule for server options

closes #20

* chore: format

* docs: remove redundant punctuation

`mkEnableOption` automatically adds a period

* update default cmp config
  • Loading branch information
Toalaah authored Sep 3, 2023
1 parent 603c8a5 commit e996b35
Show file tree
Hide file tree
Showing 11 changed files with 299 additions and 251 deletions.
1 change: 1 addition & 0 deletions modules/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

languages.lua = ./languages/lua;
languages.nix = ./languages/nix;
languages.rust = ./languages/rust;

lazy = ./lazy;

Expand Down
19 changes: 4 additions & 15 deletions modules/languages/lua/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,14 @@ with lib; let
in {
options = {
languages.lua = {
enable = mkEnableOption (lib.mdDoc "lua");
autoEnableLsp = mkOption {
description = lib.mdDoc "lsp features for lua. This implies enabling `lsp.lsp-config`";
type = types.bool;
default = true;
};
enable = mkEnableOption (lib.mdDoc "lua LSP features / additional language tooling.");
lspPkg = mkOption {
type = types.package;
default = pkgs.lua-language-server;
description = lib.mdDoc "Lua language server package to use";
};
settings = mkOption {
type = types.attrsOf types.anything;
type = types.attrs;
default = {
single_file_support = true;
Lua = {
Expand All @@ -41,18 +36,12 @@ in {
};
};
config = mkMerge [
(mkIf (cfg.enable && cfg.autoEnableLsp) {
lsp.lsp-config.enable = true;
})
(mkIf cfg.enable {
treesitter.parsers = ["lua"];

lsp.null-ls.formatters = ["stylua"];
extraPackages = lib.optionals config.lsp.null-ls.enable [pkgs.stylua];

lsp.lsp-config.serverConfigurations.lua_ls = {
lsp.lsp-config.servers.lua_ls = {
cmd = ["${cfg.lspPkg}/bin/lua-language-server"];
inherit (cfg) settings;
extraOpts = {inherit (cfg) settings;};
};
})
];
Expand Down
22 changes: 5 additions & 17 deletions modules/languages/nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,9 @@ with lib; let
in {
options = {
languages.nix = {
enable = mkEnableOption (lib.mdDoc "nix");
autoEnableLsp = mkOption {
description = lib.mdDoc "lsp features for nix. This implies enabling `lsp.lsp-config`";
type = types.bool;
default = true;
};
enable = mkEnableOption (lib.mdDoc "nix LSP features / additional language tooling.");
settings = mkOption {
type = types.attrsOf types.anything;
type = types.attrs;
default = {};
description = lib.mdDoc ''
Additional options passed to nix-lsp.
Expand All @@ -28,20 +23,13 @@ in {
};
};
config = mkMerge [
(mkIf (cfg.enable && cfg.autoEnableLsp) {
lsp.lsp-config.enable = true;
})
(mkIf cfg.enable {
assertions = [];
plugins = [];
treesitter.parsers = ["nix"];
lsp.null-ls.formatters = ["alejandra"];
lsp.null-ls.diagnostics = ["deadnix"];
extraPackages = [pkgs.alejandra pkgs.deadnix];
rtp = [./ftdetect];
lsp.lsp-config.serverConfigurations.nil_ls = {

lsp.lsp-config.servers.nil_ls = {
cmd = ["${pkgs.nil}/bin/nil"];
inherit (cfg) settings;
extraOpts = {inherit (cfg) settings;};
};
})
];
Expand Down
35 changes: 35 additions & 0 deletions modules/languages/rust/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.languages.rust;
in {
options = {
languages.rust = {
enable = mkEnableOption (lib.mdDoc "rust LSP features / additional language tooling.");
settings = mkOption {
type = types.attrs;
default = {};
description = lib.mdDoc ''
Additional options passed to rust-lsp.
Consult the project's [documentation](https://github.com/oxalica/nil/blob/main/docs/configuration.md)
for all available options.
'';
};
};
};
config = mkMerge [
(mkIf cfg.enable {
treesitter.parsers = ["rust"];

lsp.lsp-config.servers.rust_analyzer = {
cmd = ["${pkgs.rust-analyzer}/bin/rust-analyzer"];
extraOpts = {inherit (cfg) settings;};
};
})
];
}
2 changes: 1 addition & 1 deletion modules/lazy/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
src = plug.src;
nativeBuildInputs = [pkgs.neovim];
name = plug.name or plug.src.repo;
phases = [ "unpackPhase" "installPhase" "fixupPhase" ];
phases = ["unpackPhase" "installPhase" "fixupPhase"];
installPhase = ''
target=$out/${name}
mkdir -p $out
Expand Down
205 changes: 125 additions & 80 deletions modules/lsp/completion/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,133 @@
...
}:
with lib; let
inherit (lib.lua) rawLua;
sources = builtins.mapAttrs (_: v: pkgs.fetchFromGitHub (v // {name = v.repo;})) (import ./sources.nix);
cfg = config.lsp.completion;
src = pkgs.fetchFromGitHub {
owner = "hrsh7th";
repo = "nvim-cmp";
rev = "b8c2a62b3bd3827aa059b43be3dd4b5c45037d65";
hash = "sha256-mGRJy5fmGEuJD9jJhNNIW+J7juWPBLqHwlD81di/A/Y=";
};
completionSourceDeps = builtins.map (v: {inherit (v) src;}) (builtins.attrValues cfg.sources);
completionSourceOpts = lib.attrsets.mapAttrsToList (n: v:
v.opts
// {
name =
if v.name == null
then n
else v.name;
})
cfg.sources;
in {
config = mkMerge [
(mkIf config.lsp.lsp-config.enable {
assertions = [];
plugins = [
{
event = ["InsertEnter" "CmdLineEnter"];
src = sources.nvim-cmp;
config = rawLua ''
function(_, opts)
local cmp = require('cmp')
cmp.setup(opts)
-- use cmdline & path source for ':'
cmp.setup.cmdline({ ':' }, {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'async_path', max_item_count = 8, },
{ name = 'cmdline', max_item_count = 8, },
}),
})
end
'';
opts = rawLua ''
function()
local cmp = require('cmp')
return {
completion = {
completeopt = "menu,menuone,noinsert",
autocomplete = {
cmp.TriggerEvent.TextChanged,
cmp.TriggerEvent.InsertEnter,
},
},
-- TODO: snippets
snippet = {},
-- enable for modifiable buffers only
enabled = function()
local is_prompt = vim.api.nvim_buf_get_option(0, 'buftype') == 'prompt'
local is_modifiable = vim.api.nvim_buf_get_option(0, 'modifiable')
return not is_prompt and is_modifiable
end,
imports = [./snippet.nix];
options.lsp.completion = {
enable = mkEnableOption "completion support. Uses `nvim-cmp` under the hood";
src = mkOption {
type = types.package;
description = lib.mdDoc ''
Source to use for this plugin (note this source refers to the
`nvim-cmp` package to use, although you could swap this out for
whatever you like (at the cost of functionality).
'';
default = src;
};
opts = mkOption {
type = types.attrs;
default = {};
description = mdDoc ''
Additional options to pass to `cmp.setup()`. Note that for simple
setups (ex: keybindings and sources), you do not need to pass anything
to this option and should instead use the `keys` and `sources` options
respectively (in fact, default keymaps are already set, although they
may be overwritten using this option).
mapping = cmp.mapping.preset.insert({
["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
select = false,
}),
The `nvim-cmp` module is made available in this scope under the variable
name `cmp`.
'';
example = lib.literalExpression ''
window = {
completion = rawLua "cmp.config.window.bordered()";
documentation = rawLua "cmp.config.window.bordered()";
};
'';
};
sources = mkOption {
type = types.attrsOf (types.submodule {
options = {
name = mkOption {
type = types.nullOr types.str;
default = null;
description = lib.mdDoc ''
The name of the completion source module. If not set, the
attribute's name is used.
'';
};
src = mkOption {
type = types.package;
description = lib.mdDoc ''
The source of the completion module.
'';
};
opts = mkOption {
type = types.attrs;
default = {};
example = lib.literalExpression ''
{
keyword_length = 5;
}
'';
description = mdDoc ''
Options to use for this completion source. Consult the nvim-cmp documentation for available options.
'';
};
};
});
default = {};
description = lib.mdDoc ''
Extra cmp sources to make available during `cmp.setup()`.
'';
};
};
config = mkIf cfg.enable {
plugins = [
{
event = ["InsertEnter"];
dependencies = completionSourceDeps;
opts = lib.lua.rawLua ''
function()
local cmp = require 'cmp'
local opts = {
sources = ${lib.lua.toLua completionSourceOpts},
mapping = cmp.mapping.preset.insert({
["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<S-CR>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
select = true,
}),
sources = {
{ name = 'nvim_lsp' },
{ name = 'nvim_lua' },
{ name = 'async_path', max_item_count = 10, },
{ name = 'buffer', keyword_length = 3, max_item_count = 10, },
}),
completion = {
autocomplete = {
cmp.TriggerEvent.TextChanged,
cmp.TriggerEvent.InsertEnter,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
experimental = {
ghost_text = true
},
}
end
'';
dependencies = [
{src = sources.cmp-nvim-lsp;}
{src = sources.cmp-nvim-lua;}
{src = sources.cmp-buffer;}
{src = sources.cmp-cmdline;}
{src = sources.cmp-async-path;}
];
}
];
})
];
},
}
return vim.tbl_deep_extend(
"force",
opts,
-- custom user-set option overrides
${lib.lua.toLua cfg.opts}
)
end
'';
inherit (cfg) src;
}
];
};
}
Loading

0 comments on commit e996b35

Please sign in to comment.