From 516eea5f36f9d565014c23d8e0b10b43191aedce Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 16 May 2020 01:22:22 +1200 Subject: Switch XDG semantics to functions not global var --- ISSUES.md | 4 -- vim/after/plugin/spellfile_local.vim | 8 +-- vim/autoload/xdg.vim | 32 ++++++---- vim/vimrc | 120 ++++++++++++++++------------------- 4 files changed, 79 insertions(+), 85 deletions(-) diff --git a/ISSUES.md b/ISSUES.md index 3b0b2316..6fd39517 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -31,9 +31,5 @@ Known issues * The `_text_filenames` completion handler for Bash won't work on files with newlines in their names. Can it be made to? * Typing the normal mode mapping for `paste_open.vim` *twice* causes an error. -* The `xdg#` dictionary doesn't really work as an idea because it relies on the - user to make a copy of the structure or lists to avoid changing it in-place. - There would be a little more overhead to change this into a function call, - but it'd be somewhat safer. * Highlighting the variable name in e.g. `unset -v VARNAME` works with `bash` highlighting, but not with `sh` highlighting diff --git a/vim/after/plugin/spellfile_local.vim b/vim/after/plugin/spellfile_local.vim index 9d89852e..1655e78c 100644 --- a/vim/after/plugin/spellfile_local.vim +++ b/vim/after/plugin/spellfile_local.vim @@ -1,8 +1,8 @@ -" Use XDG dirs for 'spellfile' -if xdg#['data']['home'] !=# '' - let g:spellfile_local_dirs = [ xdg#['data']['home'] ] +" Use XDG dirs for 'spellfile' if XDG_DATA_HOME is useable +if xdg#DataHome() !=# '' + let g:spellfile_local_dirs = [ xdg#DataHome() ] call extend( \ g:spellfile_local_dirs, - \ copy(xdg#['data']['dirs']) + \ xdg#DataDirs(), \) endif diff --git a/vim/autoload/xdg.vim b/vim/autoload/xdg.vim index e0230b60..c5737506 100644 --- a/vim/autoload/xdg.vim +++ b/vim/autoload/xdg.vim @@ -40,16 +40,22 @@ function! s:Dirs(name) abort \) endfunction -let xdg# = { - \ 'cache': { - \ 'home': s:Home('XDG_CACHE_HOME'), - \ }, - \ 'config': { - \ 'home': s:Home('XDG_CONFIG_HOME'), - \ 'dirs': s:Dirs('XDG_CONFIG_DIRS'), - \ }, - \ 'data': { - \ 'home': s:Home('XDG_DATA_HOME'), - \ 'dirs': s:Dirs('XDG_DATA_DIRS'), - \ }, - \} +function! xdg#CacheHome() abort + return s:Home('XDG_CACHE_HOME') +endfunction + +function! xdg#ConfigHome() abort + return s:Home('XDG_CONFIG_HOME') +endfunction + +function! xdg#DataHome() abort + return s:Home('XDG_DATA_HOME') +endfunction + +function! xdg#ConfigDirs() abort + return s:Dirs('XDG_CONFIG_DIRS') +endfunction + +function! xdg#DataDirs() abort + return s:Dirs('XDG_DATA_DIRS') +endfunction diff --git a/vim/vimrc b/vim/vimrc index ebd9de3d..13987c10 100644 --- a/vim/vimrc +++ b/vim/vimrc @@ -130,9 +130,7 @@ endif " We'll start by retrieving the list of valid paths for configuration from " both the XDG_CONFIG_HOME and XDG_CONFIG_DIRS variables, or from their -" defaults, using the autoloaded xdg#() function. We need to copy() it -" because of Vim's implicit semantics for map() and reverse(), otherwise we'll -" edit the values in-place. Man, my kingdom for Perl… +" defaults, using autoloaded xdg# functions. " " We put XDG_CONFIG_HOME at the front of the list with insert(), provided it " isn't empty, which is what the function returns when the configured path @@ -147,23 +145,22 @@ endif " " Ours not to reason why… " -let s:xdgconfigpaths = copy(xdg#['config']['dirs']) -if xdg#['config']['home'] !=# '' - call insert(s:xdgconfigpaths, xdg#['config']['home']) -endif -if !empty(s:xdgconfigpaths) +if xdg#ConfigHome() !=# '' || !empty(xdg#ConfigDirs()) execute 'set runtimepath^='.option#Escape(join(map( - \ copy(s:xdgconfigpaths), + \ extend( + \ xdg#ConfigHome() !=# '' ? [xdg#ConfigHome()] : [], + \ xdg#ConfigDirs() + \), \ 'option#item#Escape(v:val)' \), ',')) -endif -if !empty(s:xdgconfigpaths) execute 'set runtimepath+='.option#Escape(join(map( - \ reverse(copy(s:xdgconfigpaths)), + \ reverse(extend( + \ xdg#ConfigHome() !=# '' ? [xdg#ConfigHome()] : [], + \ xdg#ConfigDirs() + \)), \ 'option#item#Escape(v:val.''/after'')' \), ',')) endif -unlet s:xdgconfigpaths " We need a command to reliably establish a full path, whether or not the " directories already exist. We create a wrapper for the autoloaded function @@ -190,9 +187,12 @@ command! -bang -bar -complete=dir -nargs=1 CreatePath " v8.1.716 introduced a way to set this with an option named 'viminfofile', " but I don't see a reason to use that. " -if xdg#['cache']['home'] !=# '' && path#Create(xdg#['cache']['home']) +if xdg#CacheHome() !=# '' + if !isdirectory(xdg#CacheHome()) + call mkdir(xdg#CacheHome(), 'p', 0700) + endif execute 'set viminfo+='.option#Escape( - \ 'n'.xdg#['cache']['home'].'/viminfo' + \ 'n'.xdg#CacheHome().'/viminfo' \) endif @@ -239,14 +239,13 @@ set history=10000 " 'backupfullname', 'swapfilefullname' would have been clearer. " set backup -if xdg#['cache']['home'] !=# '' - let s:backupdir = xdg#['cache']['home'].'/backup' - if path#Create(s:backupdir) - execute 'set backupdir^='.option#Escape(option#item#Escape( - \ s:backupdir.(has#('patch-8.1.251') ? '//' : ''), - \)) +if xdg#CacheHome() !=# '' + if !isdirectory(xdg#CacheHome().'/backup') + call mkdir(xdg#CacheHome().'/backup', 'p', 0700) endif - unlet s:backupdir + execute 'set backupdir^='.option#Escape(option#item#Escape( + \ xdg#CacheHome().'/backup'.(has#('patch-8.1.251') ? '//' : '') + \)) endif " Files in certain directories on Unix-compatible filesystems should not be @@ -280,17 +279,15 @@ endif " default of writing them to the same directory as the buffer file. Add two " trailing slashes to the path to prompt Vim to use the full escaped path in " its name, in order to avoid filename collisions, since the 'directory' -" option has supported that hint for much longer than 'backupdir' has. We -" apply path#Create() to attempt to create the path, if needed. -" -if xdg#['cache']['home'] !=# '' - let s:directory = xdg#['cache']['home'].'/swap' - if path#Create(s:directory) - execute 'set directory^='.option#Escape(option#item#Escape( - \ s:directory.'//' - \)) +" option has supported that hint for much longer than 'backupdir' has. +" +if xdg#CacheHome() !=# '' + if !isdirectory(xdg#CacheHome().'/swap') + call mkdir(xdg#CacheHome().'/swap', 'p', 0700) endif - unlet s:directory + execute 'set directory^='.option#Escape(option#item#Escape( + \ xdg#CacheHome().'/swap//' + \)) endif " Keep tracked undo history for files permanently, in a dedicated cache @@ -306,17 +303,14 @@ endif " Support for these persistent undo file caches was not released until v7.3.0, " so we need to check for the feature’s presence before we enable it. " -if has#('persistent_undo') +if xdg#CacheHome() !=# '' && has#('persistent_undo') set undofile - if xdg#['cache']['home'] !=# '' - let s:undodir = xdg#['cache']['home'].'/undo' - if path#Create(s:undodir) - execute 'set undodir^='.option#Escape(option#item#Escape( - \ s:undodir.'//' - \)) - endif - unlet s:undodir + if !isdirectory(xdg#CacheHome().'/undo') + call mkdir(xdg#CacheHome().'/undo', 'p', 0700) endif + execute 'set undodir^='.option#Escape(option#item#Escape( + \ xdg#CacheHome().'/undo//' + \)) endif " Set up a directory for files generated by :mkview. To date, I think I have @@ -324,13 +318,13 @@ endif " directories of this type. This isn't a comma-separated list like the others " ('backupdir', 'directory', 'spell', 'undodir') " -if has#('mksession') && xdg#['cache']['home'] - let s:viewdir = xdg#['cache']['home'].'/view' - if path#Create(s:viewdir) - execute 'set viewdir=' - \.option#Escape(option#item#Escape(s:viewdir)) +if xdg#CacheHome() !=# '' && has#('mksession') + if !isdirectory(xdg#CacheHome().'/view') + call mkdir(xdg#CacheHome().'/view', 'p', 0700) endif - unlet s:viewdir + execute 'set viewdir='.option#Escape(option#item#Escape( + \ xdg#CacheHome().'/view' + \)) endif " Now that we have a bit more confidence in our runtime environment, set up @@ -450,24 +444,22 @@ set spellcapcheck=[.?!]\\%(\ \ \\\|[\\n\\r\\t]\\) " 'isfname'; the blacklist is hard-coded. " set dictionary^=/usr/share/dict/words -let s:refdirs = copy(xdg#['data']['dirs']) -if xdg#['data']['home'] !=# '' - call insert(s:refdirs, xdg#['data']['home']) -endif -if !empty(s:refdirs) - try - execute 'set dictionary^='.option#Escape(join(map( - \ copy(s:refdirs), - \ 'option#item#Escape(v:val.''/dictionary.txt'')' - \), ',')) - execute 'set thesaurus^='.option#Escape(join(map( - \ copy(s:refdirs), - \ 'option#item#Escape(v:val.''/thesaurus.txt'')' - \), ',')) - catch /^Vim\%((\a\+)\)\=:E474:/ - endtry +if xdg#DataHome() !=# '' || !empty(xdg#DataDirs()) + execute 'set dictionary^='.option#Escape(join(map( + \ extend( + \ xdg#DataHome() !=# '' ? [xdg#DataHome()] : [], + \ xdg#DataDirs() + \), + \ 'option#item#Escape(v:val.''/dictionary.txt'')' + \), ',')) + execute 'set thesaurus^='.option#Escape(join(map( + \ reverse(extend( + \ xdg#DataHome() !=# '' ? [xdg#DataHome()] : [], + \ xdg#DataDirs() + \)), + \ 'option#item#Escape(v:val.''/thesaurus.txt'')' + \), ',')) endif -unlet s:refdirs " Next, we’ll modernize a little in adjusting some options with old " language-specific defaults. -- cgit v1.2.3