From 57b3eed0c43061130b32d96a98499d000044b199 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Thu, 14 Sep 2023 10:50:26 +0100 Subject: [PATCH] nix: Update nvim-lspconfig example config - Implement sync scrolling - Attempt to automatically detect the user's virtual env - Move nix config code into its own package - simplifying the top-level flake. --- docs/lsp/editors/nvim-lspconfig/default.nix | 37 +++++++++ docs/lsp/editors/nvim-lspconfig/init.vim | 67 +++++++++++++++- flake.lock | 86 +++++---------------- flake.nix | 48 ++++-------- lib/esbonio/pyproject.toml | 2 +- 5 files changed, 139 insertions(+), 101 deletions(-) create mode 100644 docs/lsp/editors/nvim-lspconfig/default.nix diff --git a/docs/lsp/editors/nvim-lspconfig/default.nix b/docs/lsp/editors/nvim-lspconfig/default.nix new file mode 100644 index 000000000..f7a1e43d2 --- /dev/null +++ b/docs/lsp/editors/nvim-lspconfig/default.nix @@ -0,0 +1,37 @@ +{ + lib, + neovim, + stdenv, + python3Packages, + vimPlugins, + writeShellScriptBin, + writeText, +}: + +let + paths = lib.makeBinPath [ + neovim + (python3Packages.esbonio.overridePythonAttrs (_: { doCheck = false ;})) + ]; + + pluginList = with vimPlugins; [ + nvim-lspconfig + ]; + + plugins = stdenv.mkDerivation { + name = "esbonio-nvim-plugins"; + buildCommand = '' + mkdir -p $out/nvim/site/pack/plugins/start/ + ${lib.concatMapStringsSep "\n" (path: "ln -s ${path} $out/nvim/site/pack/plugins/start/") pluginList} + ''; + }; + + initVim = builtins.readFile ./init.vim; +in + +writeShellScriptBin "nvim" '' + export PATH=${paths}:$PATH + export XDG_CONFIG_DIRS= + export XDG_DATA_DIRS=${plugins.outPath} + nvim --clean --cmd 'source ${writeText "init.vim" initVim}' "$@" +'' diff --git a/docs/lsp/editors/nvim-lspconfig/init.vim b/docs/lsp/editors/nvim-lspconfig/init.vim index 8f66cf463..e6cf56494 100644 --- a/docs/lsp/editors/nvim-lspconfig/init.vim +++ b/docs/lsp/editors/nvim-lspconfig/init.vim @@ -1,3 +1,4 @@ +" vim: et ts=2 sw=2 set expandtab set tabstop=3 set softtabstop=3 @@ -7,6 +8,7 @@ let mapleader='' lua << EOF local lspconfig = require('lspconfig') +local util = require('lspconfig.util') local keymap_opts = { noremap = true, silent = true} vim.keymap.set('n', 'e', vim.diagnostic.open_float, keymap_opts) @@ -14,18 +16,80 @@ vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, keymap_opts) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, keymap_opts) vim.keymap.set('n', 'q', vim.diagnostic.setloclist, keymap_opts) -local on_attach = function(client, bufnr) +vim.lsp.set_log_level("info") + +local function scroll_view(ev) + local esbonio = vim.lsp.get_active_clients({bufnr = 0, name = "esbonio"})[1] + local view = vim.fn.winsaveview() + + local params = { line = view.topline } + esbonio.notify("view/scroll", params) +end + +local function preview_file() + local params = { + command = "esbonio.server.previewFile", + arguments = { + { uri = vim.uri_from_bufnr(0), show = false }, + } + } + local result = vim.lsp.buf.execute_command(params) + print(vim.inspect(result)) + + -- Setup sync scrolling + local augroup = vim.api.nvim_create_augroup("EsbonioSyncScroll", { clear = true }) + vim.api.nvim_create_autocmd({"WinScrolled"}, { + callback = scroll_view, + group = augroup, + buffer = 0, + }) +end + +-- Attempt to find a virtualenv that the server can use to build the docs. + +local function find_venv() + + -- If there is an active virtual env, use that + if vim.env.VIRTUAL_ENV then + return { vim.env.VIRTUAL_ENV .. "/bin/python" } + end + + -- Search within the current git repo to see if we can find a virtual env to use. + local repo = util.find_git_ancestor(vim.fn.getcwd()) + if not repo then + return nil + end + + local candidates = vim.fs.find("pyvenv.cfg", { path = repo }) + if #candidates == 0 then + return nil + end + + return { vim.fn.resolve(candidates[1] .. "./../bin/python") } end lspconfig.esbonio.setup { cmd = { 'esbonio' }, init_options = { server = { + logLevel = 'debug', completion = { preferredInsertBehavior = 'insert' } } }, + settings = { + esbonio = { + sphinx = { + pythonCommand = find_venv(), + } + } + }, + handlers = { + ["editor/scroll"] = function(err, result, ctx, config) + vim.cmd('normal '.. result.line .. 'Gzt') + end + }, on_attach = function(client, bufnr) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') @@ -35,6 +99,7 @@ lspconfig.esbonio.setup { vim.keymap.set('n', 'gh', vim.lsp.buf.hover, bufopts) vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) + vim.api.nvim_create_user_command("EsbonioPreviewFile", preview_file, { desc = "Preview file" }) end } EOF diff --git a/flake.lock b/flake.lock index 7ecf16b71..76308b9c4 100644 --- a/flake.lock +++ b/flake.lock @@ -1,31 +1,35 @@ { "nodes": { - "esbonio": { + "lsp-devtools": { "inputs": { "nixpkgs": [ "nixpkgs" ], - "pytest-lsp": "pytest-lsp", - "utils": "utils_2" + "utils": [ + "utils" + ] }, "locked": { - "lastModified": 1, - "narHash": "sha256-QgSDxOPSrtsaqjeStalef07+bUE3qkzz7pJC4y43ltw=", - "path": "lib/esbonio", - "type": "path" + "lastModified": 1694714211, + "narHash": "sha256-dxdw33sA729QK4PRTqz3+0Fnrju6fL5peKmhUBzeU7A=", + "owner": "swyddfa", + "repo": "lsp-devtools", + "rev": "884d5a45cd2d07c3fd9b17860f5fd4c928d0c856", + "type": "github" }, "original": { - "path": "lib/esbonio", - "type": "path" + "owner": "swyddfa", + "repo": "lsp-devtools", + "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1680819799, - "narHash": "sha256-zuHl2LNr1Bll64zfr7805Yvvu23S1e//5Up0oqvjknY=", + "lastModified": 1694593561, + "narHash": "sha256-WSaIQZ5s9N9bDFkEMTw6P9eaZ9bv39ZhsiW12GtTNM0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "144133c526040a5140e89366ff72ac2d387e9bbb", + "rev": "1697b7d480449b01111e352021f46e5879e47643", "type": "github" }, "original": { @@ -35,68 +39,14 @@ "type": "github" } }, - "pytest-lsp": { - "inputs": { - "nixpkgs": [ - "esbonio", - "nixpkgs" - ], - "utils": "utils" - }, - "locked": { - "dir": "lib/pytest-lsp", - "lastModified": 1680461504, - "narHash": "sha256-yinReEwXWeCstM0+zY0A1JE2N59sdMnBsepEBgtZ9xM=", - "owner": "swyddfa", - "repo": "lsp-devtools", - "rev": "6ae80a24b55d2b6943b9d30805cf02440ebbaf5c", - "type": "github" - }, - "original": { - "dir": "lib/pytest-lsp", - "owner": "swyddfa", - "repo": "lsp-devtools", - "type": "github" - } - }, "root": { "inputs": { - "esbonio": "esbonio", + "lsp-devtools": "lsp-devtools", "nixpkgs": "nixpkgs", - "utils": "utils_3" + "utils": "utils" } }, "utils": { - "locked": { - "lastModified": 1678901627, - "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "utils_2": { - "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "utils_3": { "locked": { "lastModified": 1680776469, "narHash": "sha256-3CXUDK/3q/kieWtdsYpDOBJw3Gw4Af6x+2EiSnIkNQw=", diff --git a/flake.nix b/flake.nix index e7d0c6808..3385685f8 100644 --- a/flake.nix +++ b/flake.nix @@ -3,46 +3,32 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - esbonio.url = "path:lib/esbonio"; - esbonio.inputs.nixpkgs.follows = "nixpkgs"; utils.url = "github:numtide/flake-utils"; + + lsp-devtools.url = "github:swyddfa/lsp-devtools"; + lsp-devtools.inputs.nixpkgs.follows = "nixpkgs"; + lsp-devtools.inputs.utils.follows = "utils"; }; - outputs = { self, nixpkgs, esbonio, utils }: + outputs = { self, nixpkgs, lsp-devtools, utils }: utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { inherit system ; overlays = [ esbonio.overlays.default ];}; - - esbonio-lsp = pkgs.python3Packages.esbonio.overridePythonAttrs (_: { doCheck = false ; }); - paths = pkgs.lib.makeBinPath [ - pkgs.neovim - esbonio-lsp - ]; + pkgs = import nixpkgs { inherit system ; overlays = [ self.overlays.default ];}; - pluginList = with pkgs.vimPlugins; [ - nvim-lspconfig - ]; - plugins = pkgs.stdenv.mkDerivation { - name = "esbonio-nvim-plugins"; - buildCommand = '' - mkdir -p $out/nvim/site/pack/plugins/start/ - ${pkgs.lib.concatMapStringsSep "\n" (path: "ln -s ${path} $out/nvim/site/pack/plugins/start/") pluginList } - ''; - }; + nvim-lspconfig = pkgs.callPackage ./docs/lsp/editors/nvim-lspconfig {}; - initVim = builtins.readFile ./docs/lsp/editors/nvim-lspconfig/init.vim; - neovim = pkgs.writeShellScriptBin "nvim" '' - export PATH=${paths}:$PATH - export XDG_CONFIG_DIRS= - export XDG_DATA_DIRS=${plugins.outPath} - nvim --clean --cmd 'source ${pkgs.writeText "init.vim" initVim}' "$@" - ''; in { - apps.default = { + apps.nvim-lspconfig = { type = "app"; - program = "${neovim}/bin/nvim"; + program = "${nvim-lspconfig}/bin/nvim"; }; - } - ); + + }) // { + overlays.default = self: super: + nixpkgs.lib.composeManyExtensions [ + lsp-devtools.overlays.default + (import ./lib/esbonio/nix/esbonio-overlay.nix) + ] self super; + }; } diff --git a/lib/esbonio/pyproject.toml b/lib/esbonio/pyproject.toml index 7d5b8eb2d..0c1ea0dc8 100644 --- a/lib/esbonio/pyproject.toml +++ b/lib/esbonio/pyproject.toml @@ -31,7 +31,7 @@ dependencies = ["platformdirs", "docutils", "pygls>=1.0.0", "websockets"] "Source Code" = "https://github.com/swyddfa/esbonio" [project.scripts] -esbonio = "esbonio.server:main" +esbonio = "esbonio.server.cli:main" esbonio-sphinx = "esbonio.lsp.sphinx.cli:main" [project.optional-dependencies]