neovim/runtime/plugin/rplugin.vim
Samuel (ThinLinc team) adb2258345
fix(rplugin): dont create data dir if it's a broken symlink #25726
Checking if it's non-empty and not a directory gets us quite far, but
not all the way. While a working symlink would trigger the earlier
checks, a broken symlink does not.

This commit fixes the special case where ~/.local/share/nvim  already
exists but is a broken symlink. Thus, it fixes the following error on
startup:

E739: Cannot create directory /home/samuel/.local/share/nvim: file
already exists
2023-11-28 03:17:39 -08:00

70 lines
2.0 KiB
VimL

if exists('g:loaded_remote_plugins')
finish
endif
let g:loaded_remote_plugins = '/path/to/manifest'
" 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 dest = stdpath('data')
if !empty(dest)
if !isdirectory(dest)
if getftype(dest) != "link"
call mkdir(dest, 'p', 0700)
endif
endif
let manifest_base = dest
endif
return manifest_base.'/rplugin.vim'
endfunction
" Old manifest file based on known script locations.
function! s:GetOldManifestPaths() abort
let prefix = exists('$MYVIMRC')
\ ? $MYVIMRC
\ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$')
let origpath = fnamemodify(expand(prefix, 1), ':h')
\.'/.'.fnamemodify(prefix, ':t').'-rplugin~'
if !has('win32')
return [origpath]
endif
" Windows used to use $APPLOCALDATA/nvim but stdpath('data') is
" $XDG_DATA_DIR/nvim-data
let pseudostdpath = exists('$LOCALAPPDATA') ? '$LOCALAPPDATA' : '~/AppData/Local'
let pseudostdpath = fnamemodify(expand(pseudostdpath), ':p')
return [substitute(pseudostdpath, '[/\\]\=$', '/', '') . 'nvim/rplugin.vim', origpath]
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.
for old_manifest in s:GetOldManifestPaths()
if filereadable(old_manifest)
call rename(old_manifest, manifest)
break
endif
endfor
endif
return manifest
endfunction
function! s:LoadRemotePlugins() abort
let g:loaded_remote_plugins = s:GetManifest()
if filereadable(g:loaded_remote_plugins)
execute 'source' fnameescape(g:loaded_remote_plugins)
endif
endfunction
command! -bar UpdateRemotePlugins call remote#host#UpdateRemotePlugins()
if index(v:argv, "--clean") < 0
call s:LoadRemotePlugins()
endif