diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2019-06-06 20:02:24 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2019-06-06 20:02:24 +1200 |
commit | 520e33128edc854b1b8c5bfa05f89e0e79734993 (patch) | |
tree | ec80596428b167e84fb0555dd790b0dea57e567d /vim/autoload | |
parent | Improve handling of awkward filenames in options (diff) | |
download | dotfiles-520e33128edc854b1b8c5bfa05f89e0e79734993.tar.gz dotfiles-520e33128edc854b1b8c5bfa05f89e0e79734993.zip |
Actually correct 'runtimepath' dissection code
I failed to use the source, and assumed I knew what it did. I am
humbled.
Diffstat (limited to 'vim/autoload')
-rw-r--r-- | vim/autoload/.vimrc.vim.un~ | bin | 0 -> 16468 bytes | |||
-rw-r--r-- | vim/autoload/vimrc.vim | 83 | ||||
-rw-r--r-- | vim/autoload/vimrc.vim~ | 76 |
3 files changed, 126 insertions, 33 deletions
diff --git a/vim/autoload/.vimrc.vim.un~ b/vim/autoload/.vimrc.vim.un~ Binary files differnew file mode 100644 index 00000000..f8d8689d --- /dev/null +++ b/vim/autoload/.vimrc.vim.un~ diff --git a/vim/autoload/vimrc.vim b/vim/autoload/vimrc.vim index 25d3b22e..5280baf6 100644 --- a/vim/autoload/vimrc.vim +++ b/vim/autoload/vimrc.vim @@ -1,11 +1,13 @@ " Escape a text value for inclusion in an option value function! vimrc#EscapeSet(string) abort - return escape(a:string, '\ ') + return escape(a:string, '\ |"') endfunction " Escape a text value for inclusion as an element in a comma-separated list -" option value -function! vimrc#EscapeSetList(string) abort +" option value. Yes, the comma being the sole inner escaped character here is +" correct. No, we don't escape backslash itself. Yes, that means it's +" impossible to have the literal string '\,' in a part. +function! vimrc#EscapeSetPart(string) abort return vimrc#EscapeSet(escape(a:string, ',')) endfunction @@ -15,51 +17,66 @@ function! vimrc#PluginReady(filename) abort \ && &loadplugins endfunction -" Split a string with a split character that can be escaped with another, -" e.g. &runtimepath with commas and backslashes respectively -function! vimrc#SplitEscaped(str, ...) abort +" Split a comma-separated option string into its constituent parts, imitating +" copy_option_part() in the Vim sources. No, I'm not going to use some insane +" regular expression. Who do you think I am, Tim Pope? +function! vimrc#SplitOption(str) abort - " Arguments to function - let str = a:str " String to split - let sep = a:0 >= 1 ? a:1 : ',' " Optional split char, default comma - let esc = a:0 >= 2 ? a:2 : '\' " Optional escape char, default backslash + " Specify escaping and separating characters + let esc = '\' + let sep = ',' - " Get length of string, return empty list if it's zero + " Get string and its length into local variable + let str = a:str let len = strlen(str) - if !len - return [] - endif - " Collect items into list by iterating characterwise - let list = [''] " List items - let idx = 0 " Offset in string + " Prepare list of parts and a variable to hold each part as it's built + let parts = [] + let part = '' + + " Start the index + let idx = 0 + + " Iterate through string; we use a while loop because we might be skipping + " over characters while idx < len - if str[idx] ==# sep + " Get the character at this index + let char = str[idx] + + " Examine this character and possibly the one following it + if char ==# esc && str[idx+1] ==# sep - " This character is the item separator, and it wasn't escaped; start a - " new list item - call add(list, '') + " If this is the escape character *and* the following character is the + " separator character, add the separator character to the part, and skip + " to the character after that for the next iteration. Note that if the + " following character is *not* the separator character, that means we add + " the escape character literally. This is deliberate, and is exactly + " what Vim does! + let part .= sep + let idx += 2 + + elseif char ==# sep + + " If this is the separator character, we can add the list part we've + " built (even if it's blank) to the list of parts, and start a new one + call add(parts, part) + let part = '' + let idx += 1 else - " This character is the escape character, so we'll skip to the next - " character, if any, and add that; testing suggests that a terminal - " escape character on its own shouldn't be added - if str[idx] ==# esc - let idx += 1 - endif - let list[-1] .= str[idx] + " Just add this character literally, there's nothing special about it + let part .= char + let idx += 1 endif - " Bump index for next character - let idx += 1 - endwhile - " Return the completed list - return list + " Pass the list of collected string parts to the caller. It might be empty, + " or contain zero-length strings; neither are error conditions. + return parts endfunction diff --git a/vim/autoload/vimrc.vim~ b/vim/autoload/vimrc.vim~ new file mode 100644 index 00000000..3bf6b41c --- /dev/null +++ b/vim/autoload/vimrc.vim~ @@ -0,0 +1,76 @@ +" Escape a text value for inclusion in an option value +function! vimrc#EscapeSet(string) abort + return escape(a:string, '\ |"') +endfunction + +" Escape a text value for inclusion as an element in a comma-separated list +" option value. Yes, the comma being the sole inner escaped character here is +" correct. If you escape existing backslashes, you'll break it. +function! vimrc#EscapeSetList(string) abort + return vimrc#EscapeSet(escape(a:string, ',')) +endfunction + +" Check that we have a plugin available, and will be loading it +function! vimrc#PluginReady(filename) abort + return globpath(&runtimepath, 'plugin/'.a:filename.'.vim') !=# '' + \ && &loadplugins +endfunction + +function! vimrc#SplitOption(str) abort + + let esc = '\' + let sep = ',' + + let str = a:str + let len = strlen(str) + + let parts = [] + let part = '' + let idx = 0 + + while idx < len + + let char = str[idx] + if char ==# esc && str[idx+1] ==# sep + let part .= sep + let idx += 1 + elseif char ==# sep + call add(list, part) + let part = '' + else + let part .= char + endif + let idx += 1 + + endwhile + + return parts + +endfunction + +" Convenience version function check that should work with 7.0 or newer; +" takes strings like 7.3.251 +function! vimrc#Version(verstr) abort + + " Throw toys if the string doesn't match the expected format + if a:verstr !~# '^\d\+\.\d\+.\d\+$' + echoerr 'Invalid version string: '.a:verstr + endif + + " Split version string into major, minor, and patch level integers + let [major, minor, patch] = split(a:verstr, '\.') + + " Create a string like 801 from a version number 8.1 to compare it to + " the v:version integer + let ver = major * 100 + minor + + " Compare versions + if v:version > ver + return 1 " Current Vim is newer than the wanted one + elseif ver < v:version + return 0 " Current Vim is older than the wanted one + else + return has('patch'.patch) " Versions equal, return patch presence + endif + +endfunction |