From 01e33e1c74619fc8d262e2dedbd45a20bdb24245 Mon Sep 17 00:00:00 2001 From: Tommy Allen Date: Tue, 12 Jul 2016 02:17:58 -0400 Subject: [PATCH 1/5] runtime: rplugin manifest written to $XDG_DATA_HOME Uses $NVIM_RPLUGIN_MANIFEST if available --- runtime/autoload/remote/host.vim | 55 +++++++++++++++++++++++++++++--- runtime/doc/remote_plugin.txt | 26 ++++++++++----- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index eb5e87d7e1..104a27f357 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -118,7 +118,38 @@ function! remote#host#RegisterPlugin(host, path, specs) abort endfunction -function! s:GetManifest() abort +" Get the path to the rplugin manifest file. +function! s:GetManifestPath() abort + let manifest_base = '' + + if exists('$NVIM_RPLUGIN_MANIFEST') + return fnamemodify($NVIM_RPLUGIN_MANIFEST, ':p') + endif + + let preferred = has('win32') + \ ? ['$LOCALAPPDATA', '~/AppData/Local'] + \ : ['$XDG_DATA_HOME', '~/.local/share'] + + for dest in preferred + if dest[0] == '$' && !exists(dest) + continue + endif + + let dest = fnamemodify(expand(dest), ':p') + if !empty(dest) && isdirectory(dest) + let dest .= 'nvim/' + call mkdir(dest, 'p', 700) + let manifest_base = dest + break + endif + endfor + + return manifest_base.'rplugin.vim' +endfunction + + +" Old manifest file based on known script locations. +function! s:GetOldManifestPath() abort let prefix = exists('$MYVIMRC') \ ? $MYVIMRC \ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$') @@ -127,9 +158,25 @@ function! s:GetManifest() abort endfunction +function! s:GetManifest() abort + let manifest = s:GetManifestPath() + + if !filereadable(manifest) + " Check if an old manifest file exists and move it to the new location. + let old_manifest = s:GetOldManifestPath() + if filereadable(old_manifest) + call rename(old_manifest, manifest) + endif + endif + + return manifest +endfunction + + function! remote#host#LoadRemotePlugins() abort - if filereadable(s:GetManifest()) - exe 'source '.s:GetManifest() + let manifest = s:GetManifest() + if filereadable(manifest) + execute 'source' fnameescape(manifest) endif endfunction @@ -202,7 +249,7 @@ function! remote#host#UpdateRemotePlugins() abort endif endfor call writefile(commands, s:GetManifest()) - echomsg printf('remote/host: generated the manifest file in "%s"', + echomsg printf('remote/host: generated rplugin manifest: %s', \ s:GetManifest()) endfunction diff --git a/runtime/doc/remote_plugin.txt b/runtime/doc/remote_plugin.txt index d906096a86..25fd638b10 100644 --- a/runtime/doc/remote_plugin.txt +++ b/runtime/doc/remote_plugin.txt @@ -93,22 +93,22 @@ approach with |rpcnotify()|, meaning return values or exceptions raised in the handler function are ignored. To test the above plugin, it must be saved in "rplugin/python" in a -'runtimepath' directory (~/.config/nvim/rplugin/python/limit.py for example). -Then, the remote plugin manifest must be generated with -`:UpdateRemotePlugins`. +'runtimepath' directory (~/.config/nvim/rplugin/python/limit.py for example). +Then, the remote plugin manifest must be generated with +|:UpdateRemotePlugins|. ============================================================================== 4. Remote plugin manifest *remote-plugin-manifest* + *:UpdateRemotePlugins* Just installing remote plugins to "rplugin/{host}" isn't enough for them to be -automatically loaded when required. You must execute `:UpdateRemotePlugins` +automatically loaded when required. You must execute |:UpdateRemotePlugins| every time a remote plugin is installed, updated, or deleted. -`:UpdateRemotePlugins` generates the remote plugin manifest, a special +|:UpdateRemotePlugins| generates the remote plugin manifest, a special Vimscript file containing declarations for all Vimscript entities (commands/autocommands/functions) defined by all remote plugins, with each -entity associated with the host and plugin path. The manifest is a generated -extension to the user's vimrc (it even has the vimrc filename prepended). +entity associated with the host and plugin path. Manifest declarations are just calls to the `remote#host#RegisterPlugin` function, which takes care of bootstrapping the host as soon as the declared @@ -125,10 +125,20 @@ the example, say the Java plugin is a semantic completion engine for Java code. If it defines the autocommand "BufEnter *.java", then the Java host is spawned only when Nvim loads a buffer matching "*.java". -If the explicit call to `:UpdateRemotePlugins` seems incovenient, try to see it +If the explicit call to |:UpdateRemotePlugins| seems incovenient, try to see it like this: It's a way to provide IDE capabilities in Nvim while still keeping it fast and lightweight for general use. It's also analogous to the |:helptags| command. +Unless a path is set in the `$NVIM_RPLUGIN_MANIFEST` environment variable, the +manifest will be written to a file named `rplugin.vim` in one of the following +directories: + + Unix ~ + $XDG_DATA_HOME/nvim/ or ~/.local/share/nvim/ + + Windows ~ + $LOCALAPPDATA/nvim/ or ~/AppData/Local/nvim/ + ============================================================================== vim:tw=78:ts=8:noet:ft=help:norl: From 966f1abd8bc07915c30b4530627e272bf7a1c1c6 Mon Sep 17 00:00:00 2001 From: Tommy Allen Date: Mon, 15 Aug 2016 23:25:02 -0400 Subject: [PATCH 2/5] tests: Set env variables in RunTests.cmake - NVIM_RPLUGIN_MANIFEST - XDG_CONFIG_HOME - XDG_DATA_HOME --- cmake/RunTests.cmake | 6 ++++++ test/functional/helpers.lua | 1 + 2 files changed, 7 insertions(+) diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake index 9fa91ffb5d..a045f9f982 100644 --- a/cmake/RunTests.cmake +++ b/cmake/RunTests.cmake @@ -2,6 +2,9 @@ get_filename_component(BUSTED_DIR ${BUSTED_PRG} PATH) set(ENV{PATH} "${BUSTED_DIR}:$ENV{PATH}") set(ENV{VIMRUNTIME} ${WORKING_DIR}/runtime) +set(ENV{NVIM_RPLUGIN_MANIFEST} ${WORKING_DIR}/Xtest_rplugin_manifest) +set(ENV{XDG_CONFIG_HOME} ${WORKING_DIR}/Xtest_xdg/config) +set(ENV{XDG_DATA_HOME} ${WORKING_DIR}/Xtest_xdg/share) if(NVIM_PRG) set(ENV{NVIM_PROG} "${NVIM_PRG}") @@ -34,6 +37,9 @@ execute_process( RESULT_VARIABLE res ${EXTRA_ARGS}) +file(REMOVE ${WORKING_DIR}/Xtest_rplugin_manifest) +file(REMOVE_RECURSE ${WORKING_DIR}/Xtest_xdg) + if(NOT res EQUAL 0) message(STATUS "Output to stderr:\n${err}") message(FATAL_ERROR "Running ${TEST_TYPE} tests failed with error: ${res}.") diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 6f43ec817c..2d54d23254 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -241,6 +241,7 @@ local function clear(...) 'ASAN_OPTIONS', 'LD_LIBRARY_PATH', 'PATH', 'NVIM_LOG_FILE', + 'NVIM_RPLUGIN_MANIFEST', }) do env_tbl[k] = os.getenv(k) end From 4b0b391f9f4ecac903b490cdb0834a2f4ab0e310 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 17 Aug 2016 17:30:17 -0400 Subject: [PATCH 3/5] host.vim: s:GetManifestPath(): Remove for-loop. Without the for-loop it is easier to follow, more explicit, and fewer lines. --- runtime/autoload/remote/host.vim | 26 ++++++++++---------------- runtime/doc/remote_plugin.txt | 6 +++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index 104a27f357..355ff339dc 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -126,23 +126,17 @@ function! s:GetManifestPath() abort return fnamemodify($NVIM_RPLUGIN_MANIFEST, ':p') endif - let preferred = has('win32') - \ ? ['$LOCALAPPDATA', '~/AppData/Local'] - \ : ['$XDG_DATA_HOME', '~/.local/share'] + let dest = has('win32') ? '$LOCALAPPDATA' : '$XDG_DATA_HOME' + if !exists(dest) + let dest = has('win32') ? '~/AppData/Local' : '~/.local/share' + endif - for dest in preferred - if dest[0] == '$' && !exists(dest) - continue - endif - - let dest = fnamemodify(expand(dest), ':p') - if !empty(dest) && isdirectory(dest) - let dest .= 'nvim/' - call mkdir(dest, 'p', 700) - let manifest_base = dest - break - endif - endfor + let dest = fnamemodify(expand(dest), ':p') + if !empty(dest) && isdirectory(dest) + let dest .= 'nvim/' + call mkdir(dest, 'p', 700) + let manifest_base = dest + endif return manifest_base.'rplugin.vim' endfunction diff --git a/runtime/doc/remote_plugin.txt b/runtime/doc/remote_plugin.txt index 25fd638b10..dddc021d68 100644 --- a/runtime/doc/remote_plugin.txt +++ b/runtime/doc/remote_plugin.txt @@ -130,9 +130,9 @@ like this: It's a way to provide IDE capabilities in Nvim while still keeping it fast and lightweight for general use. It's also analogous to the |:helptags| command. -Unless a path is set in the `$NVIM_RPLUGIN_MANIFEST` environment variable, the -manifest will be written to a file named `rplugin.vim` in one of the following -directories: + *$NVIM_RPLUGIN_MANIFEST* +Unless $NVIM_RPLUGIN_MANIFEST is set the manifest will be written to a file +named `rplugin.vim` at: Unix ~ $XDG_DATA_HOME/nvim/ or ~/.local/share/nvim/ From acaf480bdcd5f3e8562fd78cd94850f4eb83ec57 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 17 Aug 2016 17:56:10 -0400 Subject: [PATCH 4/5] host.vim: s:GetManifestPath(): Create base directory if needed. If the base directory does not exist, let mkdir(...,'p') create it. --- runtime/autoload/remote/host.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index 355ff339dc..3c70101966 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -132,13 +132,13 @@ function! s:GetManifestPath() abort endif let dest = fnamemodify(expand(dest), ':p') - if !empty(dest) && isdirectory(dest) - let dest .= 'nvim/' + if !empty(dest) && !filereadable(dest) + let dest .= ('/' ==# dest[-1:] ? '' : '/') . 'nvim' call mkdir(dest, 'p', 700) let manifest_base = dest endif - return manifest_base.'rplugin.vim' + return manifest_base.'/rplugin.vim' endfunction From f9aa029a8b5b9dd93b4af56c995337bd853dc5c0 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 17 Aug 2016 18:11:17 -0400 Subject: [PATCH 5/5] host.vim: s:GetManifestPath(): octal permissions --- runtime/autoload/remote/host.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index 3c70101966..5948de2b3d 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -134,7 +134,7 @@ function! s:GetManifestPath() abort let dest = fnamemodify(expand(dest), ':p') if !empty(dest) && !filereadable(dest) let dest .= ('/' ==# dest[-1:] ? '' : '/') . 'nvim' - call mkdir(dest, 'p', 700) + call mkdir(dest, 'p', 0700) let manifest_base = dest endif