summaryrefslogtreecommitdiffstats
path: root/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim')
-rw-r--r--runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim183
1 files changed, 183 insertions, 0 deletions
diff --git a/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim b/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim
new file mode 100644
index 0000000..c9a66e1
--- /dev/null
+++ b/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim
@@ -0,0 +1,183 @@
+" autoload/editorconfig_core/handler.vim: Main worker for
+" editorconfig-core-vimscript and editorconfig-vim.
+" Modified from the Python core's handler.py.
+
+" Copyright (c) 2012-2019 EditorConfig Team {{{1
+" All rights reserved.
+"
+" Redistribution and use in source and binary forms, with or without
+" modification, are permitted provided that the following conditions are met:
+"
+" 1. Redistributions of source code must retain the above copyright notice,
+" this list of conditions and the following disclaimer.
+" 2. Redistributions in binary form must reproduce the above copyright notice,
+" this list of conditions and the following disclaimer in the documentation
+" and/or other materials provided with the distribution.
+"
+" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+" POSSIBILITY OF SUCH DAMAGE. }}}1
+
+let s:saved_cpo = &cpo
+set cpo&vim
+
+" Return full filepath for filename in each directory in and above path. {{{1
+" Input path must be an absolute path.
+" TODO shellslash/shellescape?
+function! s:get_filenames(path, config_filename)
+ let l:path = a:path
+ let l:path_list = []
+ while 1
+ call add(l:path_list, editorconfig_core#util#path_join(l:path, a:config_filename))
+ let l:newpath = fnamemodify(l:path, ':h')
+ if l:path ==? l:newpath || !strlen(l:path)
+ break
+ endif
+ let l:path = l:newpath
+ endwhile
+ return l:path_list
+endfunction " get_filenames
+
+" }}}1
+" === Main ============================================================== {{{1
+
+" Find EditorConfig files and return all options matching target_filename.
+" Throws on failure.
+" @param job {Dictionary} required 'target'; optional 'config' and 'version'
+function! editorconfig_core#handler#get_configurations(job)
+ " TODO? support VERSION checks?
+
+" Special exceptions that may be raised by this function include:
+" - ``VersionError``: self.version is invalid EditorConfig version
+" - ``PathError``: self.filepath is not a valid absolute filepath
+" - ``ParsingError``: improperly formatted EditorConfig file found
+
+ let l:job = deepcopy(a:job)
+ if has_key(l:job, 'config')
+ let l:config_filename = l:job.config
+ else
+ let l:config_filename = '.editorconfig'
+ let l:job.config = l:config_filename
+ endif
+
+ if has_key(l:job, 'version')
+ let l:version = l:job.version
+ else
+ let l:version = editorconfig_core#version()
+ let l:job.version = l:version
+ endif
+
+ let l:target_filename = l:job.target
+
+ "echom 'Beginning job ' . string(l:job)
+ if !s:check_assertions(l:job)
+ throw "Assertions failed"
+ endif
+
+ let l:fullpath = fnamemodify(l:target_filename,':p')
+ let l:path = fnamemodify(l:fullpath, ':h')
+ let l:conf_files = s:get_filenames(l:path, l:config_filename)
+
+ " echom 'fullpath ' . l:fullpath
+ " echom 'path ' . l:path
+
+ let l:retval = {}
+
+ " Attempt to find and parse every EditorConfig file in filetree
+ for l:conf_fn in l:conf_files
+ "echom 'Trying ' . l:conf_fn
+ let l:parsed = editorconfig_core#ini#read_ini_file(l:conf_fn, l:target_filename)
+ if !has_key(l:parsed, 'options')
+ continue
+ endif
+ " echom ' Has options'
+
+ " Merge new EditorConfig file's options into current options
+ let l:old_options = l:retval
+ let l:retval = l:parsed.options
+ " echom 'Old options ' . string(l:old_options)
+ " echom 'New options ' . string(l:retval)
+ call extend(l:retval, l:old_options, 'force')
+
+ " Stop parsing if parsed file has a ``root = true`` option
+ if l:parsed.root
+ break
+ endif
+ endfor
+
+ call s:preprocess_values(l:job, l:retval)
+ return l:retval
+endfunction " get_configurations
+
+function! s:check_assertions(job)
+" TODO
+" """Raise error if filepath or version have invalid values"""
+
+" # Raise ``PathError`` if filepath isn't an absolute path
+" if not os.path.isabs(self.filepath):
+" raise PathError("Input file must be a full path name.")
+
+ " Throw if version specified is greater than current
+ let l:v = a:job.version
+ let l:us = editorconfig_core#version()
+ " echom 'Comparing requested version ' . string(l:v) .
+ " \ ' to our version ' . string(l:us)
+ if l:v[0] > l:us[0] || l:v[1] > l:us[1] || l:v[2] > l:us[2]
+ throw 'Required version ' . string(l:v) .
+ \ ' is greater than the current version ' . string(l:us)
+ endif
+
+ return 1 " All OK if we got here
+endfunction " check_assertions
+
+" }}}1
+
+" Preprocess option values for consumption by plugins. {{{1
+" Modifies its argument in place.
+function! s:preprocess_values(job, opts)
+
+ " Lowercase option value for certain options
+ for l:name in ['end_of_line', 'indent_style', 'indent_size',
+ \ 'insert_final_newline', 'trim_trailing_whitespace',
+ \ 'charset']
+ if has_key(a:opts, l:name)
+ let a:opts[l:name] = tolower(a:opts[l:name])
+ endif
+ endfor
+
+ " Set indent_size to "tab" if indent_size is unspecified and
+ " indent_style is set to "tab", provided we are at least v0.10.0.
+ if get(a:opts, 'indent_style', '') ==? "tab" &&
+ \ !has_key(a:opts, 'indent_size') &&
+ \ ( a:job.version[0]>0 || a:job.version[1] >=10 )
+ let a:opts['indent_size'] = 'tab'
+ endif
+
+ " Set tab_width to indent_size if indent_size is specified and
+ " tab_width is unspecified
+ if has_key(a:opts, 'indent_size') && !has_key(a:opts, 'tab_width') &&
+ \ get(a:opts, 'indent_size', '') !=? "tab"
+ let a:opts['tab_width'] = a:opts['indent_size']
+ endif
+
+ " Set indent_size to tab_width if indent_size is "tab"
+ if has_key(a:opts, 'indent_size') && has_key(a:opts, 'tab_width') &&
+ \ get(a:opts, 'indent_size', '') ==? "tab"
+ let a:opts['indent_size'] = a:opts['tab_width']
+ endif
+endfunction " preprocess_values
+
+" }}}1
+
+let &cpo = s:saved_cpo
+unlet! s:saved_cpo
+
+" vi: set fdm=marker fdl=1: