From ad24ee26c99903461746e26bb6a182471a39cfaa Mon Sep 17 00:00:00 2001 From: Rene Descartes Date: Thu, 9 Jun 2022 15:49:21 -0600 Subject: [PATCH] Add nodejs tool layer --- core/autoload/spacevim/plug/nodejs.vim | 100 +++++++++++++++++++++++++ layers/+tools/lsp/README.md | 57 ++++++++++---- layers/+tools/nodejs/README.md | 32 ++++++++ layers/+tools/nodejs/config.vim | 0 layers/+tools/nodejs/packages.vim | 3 + layers/LAYERS.md | 1 + 6 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 core/autoload/spacevim/plug/nodejs.vim create mode 100644 layers/+tools/nodejs/README.md create mode 100644 layers/+tools/nodejs/config.vim create mode 100644 layers/+tools/nodejs/packages.vim diff --git a/core/autoload/spacevim/plug/nodejs.vim b/core/autoload/spacevim/plug/nodejs.vim new file mode 100644 index 00000000..34d993bf --- /dev/null +++ b/core/autoload/spacevim/plug/nodejs.vim @@ -0,0 +1,100 @@ +" If no valid $NODE or systemwide node.js: build node.js dependency +function! spacevim#plug#nodejs#build(info) + if !spacevim#load('programming') + echom "nodejs layer requires the 'programming' layer to build. Add 'programming' layer to init.spacevim" + return + endif + if g:spacevim.os.windows + echom 'Building Node.js automatically on Windows is untested and likely to fail, PR welcome' + execute('AsyncRun -mode=term -pos=tab @ .\\vcbuild openssl-no-asm') + return + endif + if (!exists('$CC') && executable('gcc') != 1) || executable('make') != 1 || executable('python3') != 1 + echom 'Unable to build Node.js, requires a C++ compiler, make, and python3' + return + endif + + echom 'Building Node.js...' + let ninja_flag = '' + let jobs_flag = '' + if executable('ninja') + let ninja_flag=' --ninja' + else + " Determine number of cores/threads for make -j, ninja autodetects + let num_threads = 4 + if executable('lscpu') + let result = system("lscpu | grep -E '?^(CPU\\(s\\):|Thread\\(s\\) per core:)' | tr -s ' ' | cut -f 2 -d:") + if !v:shell_error + let num_threads = join(split(result), '*') + endif + endif + let jobs_flag = ' -j '.num_threads + endif + + " Build intermediate files to temp, vim will delete folder on exit + let s:cwd = getcwd() + let temp_dir = fnamemodify(tempname(), ':p:h') + call mkdir(temp_dir.'/out', 'p') + if getftype('out') =~# 'link' + call system('rm out') + endif + call system('ln -s '.temp_dir.'/out out') + call system('./configure'.ninja_flag.' > '.temp_dir.'/nodejs_configure.log') + execute('AsyncRun -mode=term -pos=tab -program=make -post=call\ spacevim\\#plug\\#nodejs\\#postbuild(code) @'.jobs_flag) +endfunction + +function! spacevim#plug#nodejs#postbuild(exit_code) + execute 'tcd' fnameescape(s:cwd) + unlet s:cwd + if a:exit_code == 0 + call system('rm -r deps/icu-tmp node') + call rename('out/Release/node', 'node') + let pathsep = g:spacevim.os.windows ? ';' : ':' + let $PATH = g:plug_home.'/node'.pathsep.$PATH + + " This sets up corepack/npm links the same as `make install` does + call system('ln -s deps/corepack/dist/corepack.js corepack') + call system('ln -s deps/npm/bin/npm-cli.js npm') + call system('ln -s deps/npm/bin/npx-cli.js npx') + call system('node corepack enable') + endif + call system('rm out') + tcd - +endfunction + +" Check for Node.js >= v16.10 +function! s:isNodeJsVersionSufficient(node) + if executable(a:node) == 1 + let node_version = system(a:node.' --version') + let node_version_parts = map(filter(split(node_version, '\v\ze\.|v'), 'v:val =~# "\\v\\d+"'), 'matchstr(v:val, "\\v\\d+")') + if len(node_version_parts) >= 2 && (node_version_parts[0] > 16 || (node_version_parts[0] == 16 && node_version_parts[1] >= 10)) + return 1 + endif + endif + return 0 +endfunction + +" Will do the following checks in order of precedence: +" -Use $NODE or $NODE/node if they exist and are executable +" -check for node as vim-plug plugin (user-specific) +" -check for system-wide install of node +" -If all above fail will get node as vim-plug plugin and build it +" Changes $PATH to include node path +function! spacevim#plug#nodejs#isBuildRequired() + let pathsep = g:spacevim.os.windows ? ';' : ':' + " Prefer $NODE override + if exists('$NODE') && s:isNodeJsVersionSufficient('$NODE') + let $PATH = fnamemodify('$NODE', ':h').pathsep.$PATH + return 0 + endif + " Prefer user plugin Node.js if it exists + if s:isNodeJsVersionSufficient(g:plug_home.'/node/node') + let $PATH = g:plug_home.'/node'.pathsep.$PATH + return 0 + endif + " Last check for system-wide Node.js + if s:isNodeJsVersionSufficient('node') + return 0 + endif + return 1 +endfunction diff --git a/layers/+tools/lsp/README.md b/layers/+tools/lsp/README.md index c661251b..08fdd27b 100644 --- a/layers/+tools/lsp/README.md +++ b/layers/+tools/lsp/README.md @@ -5,7 +5,8 @@ * [Description](#description) -* [Requrement](#requrement) +* [Install](#install) +* [Manual Language Server Installation](#manual-language-server-installation) * [Rust](#rust) * [Python](#python) * [Go](#go) @@ -14,7 +15,6 @@ * [Haskell](#haskell) * [Lua](#lua) * [vue](#vue) -* [Install](#install) * [Key Bindings](#key-bindings) * [Related Projects](#related-projects) @@ -24,7 +24,48 @@ This layer adds supports [Language Server Protocol](https://langserver.org/). -## Requrement +## Install + +To use this configuration layer, add it to your `~/.spacevim`, set it up like so: + +```vim +let g:spacevim_layers = [ + \ 'lsp', + \ ] +``` + +Currently [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) is the default *language server client* when using the lsp layer. + +Currently the *language server client* builtin to Neovim is not supported by space-vim [#483](https://github.com/liuchengxu/space-vim/issues/483). + +To use [coc.nvim](https://github.com/neoclide/coc.nvim) or [vim-lsp](https://github.com/prabirshrestha/vim-lsp) instead of the default set `g:spacevim_lsp_engine` as desired: + +```vim +let g:spacevim_layers = [ + \ 'lsp', + \ ] + +let g:spacevim_lsp_engine = 'coc' +let g:spacevim_lsp_engine = 'vim_lsp' +``` + +Note that coc.nvim is dependent on Node.js, the nodejs layer will satisfy that dependency. + +If using vim-lsp as the *language server client*, this layer will handle the configuration and installation of many *language servers* for you (this layer includes the [vim-lsp-settings](https://github.com/mattn/vim-lsp-settings) plugin). On opening a file this layer will detect if there is a *language server* for that filetype and prompt you to run the command `:LspInstallServer`. + +Unlike other Vim *language server clients*, LanguageClient-neovim does not include configuration and installation of *language servers*. space-vim includes some configuration for *language servers* and this client, but installation must be done manually. + +Often the Yarn or npm tools are needed to retrieve a *language server* and its dependencies. For convenience space-vim includes these tools within the nodejs layer, which builds them or locates them using the `$PATH` and `$NODE` environmental variables. You may include the nodejs layer as follows (which may require the programming layer): + +```vim +let g:spacevim_layers = [ + \ 'programming', 'nodejs', 'lsp', + \ ] +``` + +## Manual Language Server Installation + +If using LanguageClient-neovim, directions for the manual installation of some LSP servers are as follows. Other configuration and installation directions can be found in locations like its github wiki pages. ### Rust @@ -120,16 +161,6 @@ $ luarocks install --server=http://luarocks.org/dev lua-lsp $ npm install vue-language-server -g ``` -## Install - -To use this configuration layer, add it to your `~/.spacevim`. - -Currently, [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) is the default LS client. To use [coc.nvim](https://github.com/neoclide/coc.nvim) instead: - -```vim -let g:spacevim_lsp_engine = 'coc' -``` - ## Key Bindings Key Binding | Mode | Description diff --git a/layers/+tools/nodejs/README.md b/layers/+tools/nodejs/README.md new file mode 100644 index 00000000..4b871768 --- /dev/null +++ b/layers/+tools/nodejs/README.md @@ -0,0 +1,32 @@ +# nodejs Layer + +## Table of Contents + + +* [Description](#description) +* [Install](#install) +* [Key Bindings](#keybindings) + + + +## Description + +This layer adds support for the Node.js tool. + +## Install + +To use this layer, add it to your `~/.spacevim` as follows: + +``` +let g:spacevim_layers = [ + \ 'programming', 'nodejs', + \ ] +``` + +If Node.js is installed system-wide and is version >= 16.10 then that will be used. Otherwise the nodejs layer requires the programming layer to build Node.js as a dependency within vim-plug's plugged directory. + +Node.js built with the repo requires 1.2 GiB space. Intermediate files are deleted after build. + +If you instead wish to use Node.js elsewhere (not on `$PATH`), this package will look at `$NODE` and use that if it is of sufficient version. + +The curated node will be added to `$PATH` for use by other plugins. Node.js >= v16.10 also includes yarn/npm, useful for other plugins to install dependencies. diff --git a/layers/+tools/nodejs/config.vim b/layers/+tools/nodejs/config.vim new file mode 100644 index 00000000..e69de29b diff --git a/layers/+tools/nodejs/packages.vim b/layers/+tools/nodejs/packages.vim new file mode 100644 index 00000000..2b52051e --- /dev/null +++ b/layers/+tools/nodejs/packages.vim @@ -0,0 +1,3 @@ +if spacevim#plug#nodejs#isBuildRequired() + MP 'nodejs/node', { 'do': function('spacevim#plug#nodejs#build') } +endif diff --git a/layers/LAYERS.md b/layers/LAYERS.md index cc9db23e..69116945 100644 --- a/layers/LAYERS.md +++ b/layers/LAYERS.md @@ -50,6 +50,7 @@ Topic | Layer | Plugins +tools | [file-manager](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/file-manager) | +tools | [fzf](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/fzf) | +tools | [lsp](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/lsp) | ++tools | [nodejs](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/nodejs) | +tools | [tmux](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/tmux) | +tools | [ycmd](https://github.com/liuchengxu/space-vim/tree/master/layers/+tools/ycmd) | +version-control | [git](https://github.com/liuchengxu/space-vim/tree/master/layers/+version-control/git) |