diff options
45 files changed, 1996 insertions, 1239 deletions
diff --git a/after/ftplugin/terraform.vim b/after/ftplugin/terraform.vim index f495e583..17115b1b 100644 --- a/after/ftplugin/terraform.vim +++ b/after/ftplugin/terraform.vim @@ -18,4 +18,11 @@ if g:terraform_align && exists(':Tabularize') endfunction endif +" Match the identation put in place by Hashicorp and :TerraformFmt, https://github.com/hashivim/vim-terraform/issues/21 +if get(g:, "terraform_align", 1) + setlocal tabstop=2 + setlocal softtabstop=2 + setlocal shiftwidth=2 +endif + endif diff --git a/after/syntax/c.vim b/after/syntax/c.vim index aa4a31ec..8cec90f6 100644 --- a/after/syntax/c.vim +++ b/after/syntax/c.vim @@ -25,6 +25,16 @@ syn match cCustomFunc "\w\+\s*(\@=" contains=cCustomParen hi def link cCustomFunc Function " ----------------------------------------------------------------------------- +" Highlight member variable names. +" ----------------------------------------------------------------------------- +if exists('g:cpp_member_variable_highlight') && g:cpp_member_variable_highlight + syn match cCustomDot "\." contained + syn match cCustomPtr "->" contained + syn match cCustomMemVar "\(\.\|->\)\w\+" contains=cCustomDot,cCustomPtr + hi def link cCustomMemVar Function +endif + +" ----------------------------------------------------------------------------- " Source: aftersyntaxc.vim " ----------------------------------------------------------------------------- diff --git a/after/syntax/cpp.vim b/after/syntax/cpp.vim index 99d9f18e..4faa0f6b 100644 --- a/after/syntax/cpp.vim +++ b/after/syntax/cpp.vim @@ -557,6 +557,7 @@ syntax keyword cppSTLios defaultfloat syntax keyword cppSTLios endl syntax keyword cppSTLios ends syntax keyword cppSTLios fixed +syntax keyword cppSTLios floatfield syntax keyword cppSTLios flush syntax keyword cppSTLios get_money syntax keyword cppSTLios get_time diff --git a/after/syntax/html.vim b/after/syntax/html.vim index ab99117d..43c0c41e 100644 --- a/after/syntax/html.vim +++ b/after/syntax/html.vim @@ -35,6 +35,22 @@ syn region ShaderScript \ contains=@GLSL,htmlScriptTag,@htmlPreproc endif +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 + +" Vim syntax file +" Language: HTML (version 5.1) +" Last Change: 2017 Feb 15 +" License: Public domain +" (but let me know if you like :) ) +" +" Maintainer: Kao, Wei-Ko(othree) ( othree AT gmail DOT com ) + +" Comment +" https://github.com/w3c/html/issues/694 +syntax region htmlComment start=+<!--+ end=+-->+ contains=@Spell +syntax region htmlComment start=+<!DOCTYPE+ keepend end=+>+ + +endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'less') == -1 if !exists("g:less_html_style_tags") diff --git a/after/syntax/yaml.vim b/after/syntax/yaml.vim index 7f4808db..78983cc2 100644 --- a/after/syntax/yaml.vim +++ b/after/syntax/yaml.vim @@ -21,9 +21,7 @@ if version < 600 endif syntax clear -syn match yamlDelimiter "[:,-]" syn match yamlBlock "[\[\]\{\}\|\>]" -syn match yamlOperator "[?^+-]\|=>" syn region yamlComment start="\#" end="$" syn match yamlIndicator "#YAML:\S\+" @@ -41,10 +39,11 @@ syn keyword yamlConstant TRUE True true YES Yes yes ON On on syn keyword yamlConstant FALSE False false NO No no OFF Off off syn match yamlKey "^\s*\zs\S\+\ze\s*:" +syn match yamlKey "^\s*-\s*\zs\S\+\ze\s*:" syn match yamlAnchor "&\S\+" syn match yamlAlias "*\S\+" -" Setupt the hilighting links +" Setup the highlighting links hi link yamlConstant Keyword hi link yamlIndicator PreCondit @@ -55,10 +54,7 @@ hi link yamlType Type hi link yamlComment Comment hi link yamlBlock Operator -hi link yamlOperator Operator -hi link yamlDelimiter Delimiter hi link yamlString String hi link yamlEscape Special - endif diff --git a/autoload/dart.vim b/autoload/dart.vim index df341b48..9f04fcc2 100644 --- a/autoload/dart.vim +++ b/autoload/dart.vim @@ -68,5 +68,86 @@ function! dart#tojs(q_args) abort endif endfunction +" Finds the path to `uri`. +" +" If the file is a package: uri, looks for a .packages file to resolve the path. +" If the path cannot be resolved, or is not a package: uri, returns the +" original. +function! dart#resolveUri(uri) abort + if a:uri !~ 'package:' + return a:uri + endif + let package_name = substitute(a:uri, 'package:\(\w\+\)\/.*', '\1', '') + let [found, package_map] = s:PackageMap() + if !found + call s:error('cannot find .packages file') + return a:uri + endif + if !has_key(package_map, package_name) + call s:error('no package mapping for '.package_name) + return a:uri + endif + let package_lib = package_map[package_name] + return substitute(a:uri, + \ 'package:'.package_name, + \ escape(package_map[package_name], '\'), + \ '') +endfunction + +" A map from package name to lib directory parse from a '.packages' file. +" +" Returns [found, package_map] +function! s:PackageMap() abort + let [found, dot_packages] = s:DotPackagesFile() + if !found + return [v:false, {}] + endif + let dot_packages_dir = fnamemodify(dot_packages, ':p:h') + let lines = readfile(dot_packages) + let map = {} + for line in lines + if line =~ '\s*#' + continue + endif + let package = substitute(line, ':.*$', '', '') + let lib_dir = substitute(line, '^[^:]*:', '', '') + if lib_dir =~ 'file:/' + let lib_dir = substitute(lib_dir, 'file://', '', '') + if lib_dir =~ '/[A-Z]:/' + let lib_dir = lib_dir[1:] + endif + else + let lib_dir = resolve(dot_packages_dir.'/'.lib_dir) + endif + if lib_dir =~ '/$' + let lib_dir = lib_dir[:len(lib_dir) - 2] + endif + let map[package] = lib_dir + endfor + return [v:true, map] +endfunction + +" Finds a file name '.packages' in the cwd, or in any directory above the open +" file. +" +" Returns [found, file]. +function! s:DotPackagesFile() abort + if filereadable('.packages') + return [v:true, '.packages'] + endif + let dir_path = expand('%:p:h') + while v:true + let file_path = dir_path.'/.packages' + if filereadable(file_path) + return [v:true, file_path] + endif + let parent = fnamemodify(dir_path, ':h') + if dir_path == parent + break + endif + let dir_path = parent + endwhile + return [v:false, ''] +endfunction endif diff --git a/autoload/rubycomplete.vim b/autoload/rubycomplete.vim index 973be8ef..8cb73fd5 100644 --- a/autoload/rubycomplete.vim +++ b/autoload/rubycomplete.vim @@ -589,11 +589,13 @@ class VimRubyCompletion # {{{ main completion code def self.preload_rails a = VimRubyCompletion.new - require 'Thread' - Thread.new(a) do |b| - begin - b.load_rails - rescue + if VIM::evaluate("has('nvim')") == 0 + require 'thread' + Thread.new(a) do |b| + begin + b.load_rails + rescue + end end end a.load_rails diff --git a/autoload/xml/aria.vim b/autoload/xml/aria.vim index 8974526e..2a3c88f0 100644 --- a/autoload/xml/aria.vim +++ b/autoload/xml/aria.vim @@ -3,33 +3,220 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 " Vim completion for WAI-ARIA data file " Language: HTML + WAI-ARIA " Maintainer: othree <othree@gmail.com> -" Last Change: 2010 Sep 09 +" Last Change: 2017 Mar 07 " WAI_ARIA: {{{ -" Ref: http://www.w3.org/TR/wai-aria/ -" Version: Draft 15 December 2009 +" Ref: https://www.w3.org/TR/wai-aria-1.1/ +" Version: W3C Candidate Recommendation 27 October 2016 let abstract_role = {} let role_attributes = {} let default_role = {} -" Ref: http://www.w3.org/TR/wai-aria/roles -" Version: Draft 15 December 2009 -let widget_role = ['alert', 'alertdialog', 'button', 'checkbox', 'combobox', 'dialog', 'gridcell', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'radiogroup', 'scrollbar', 'slider', 'spinbutton', 'status', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'treeitem', 'combobox', 'grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'] -let document_structure = ['article', 'columnheader', 'definition', 'directory', 'document', 'group', 'heading', 'img', 'list', 'listitem', 'math', 'note', 'presentation', 'region', 'row', 'rowheader', 'separator'] -let landmark_role = ['application', 'banner', 'complementary', 'contentinfo', 'form', 'main', 'navigation', 'search'] -let dpub_role = ['dpub-abstract', 'dpub-afterword', 'dpub-appendix', 'dpub-biblioentry', 'dpub-bibliography', 'dpub-biblioref', 'dpub-chapter', 'dpub-cover', 'dpub-epilogue', 'dpub-footnote', 'dpub-footnotes', 'dpub-foreword', 'dpub-glossary', 'dpub-glossdef', 'dpub-glossref', 'dpub-glossterm', 'dpub-index', 'dpub-locator', 'dpub-noteref', 'dpub-notice', 'dpub-pagebreak', 'dpub-pagelist', 'dpub-part', 'dpub-preface', 'dpub-prologue', 'dpub-pullquote', 'dpub-qna', 'dpub-subtitle', 'dpub-tip', 'dpub-title', 'dpub-toc'] +" Ref: https://www.w3.org/TR/wai-aria-1.1/#roles_categorization +" Version: W3C Candidate Recommendation 27 October 2016 +let widget_role = [ + \ 'alert', + \ 'alertdialog', + \ 'button', + \ 'checkbox', + \ 'combobox', + \ 'dialog', + \ 'gridcell', + \ 'link', + \ 'log', + \ 'marquee', + \ 'menuitem', + \ 'menuitemcheckbox', + \ 'menuitemradio', + \ 'option', + \ 'progressbar', + \ 'radio', + \ 'radiogroup', + \ 'scrollbar', + \ 'searchbox', + \ 'slider', + \ 'spinbutton', + \ 'status', + \ 'switch', + \ 'tab', + \ 'tabpanel', + \ 'textbox', + \ 'timer', + \ 'tooltip', + \ 'treeitem', + \ 'combobox', + \ 'grid', + \ 'listbox', + \ 'menu', + \ 'menubar', + \ 'radiogroup', + \ 'tablist', + \ 'tree', + \ 'treegrid' +\ ] + +let document_structure = [ + \ 'article', + \ 'cell', + \ 'columnheader', + \ 'definition', + \ 'directory', + \ 'document', + \ 'feed', + \ 'figure', + \ 'group', + \ 'heading', + \ 'img', + \ 'list', + \ 'listitem', + \ 'math', + \ 'none', + \ 'note', + \ 'presentation', + \ 'region', + \ 'row', + \ 'rowheader', + \ 'separator', + \ 'table', + \ 'term' +\ ] + +let landmark_role = [ + \ 'application', + \ 'banner', + \ 'complementary', + \ 'contentinfo', + \ 'form', + \ 'main', + \ 'navigation', + \ 'search' +\ ] + +" Ref: https://www.w3.org/TR/dpub-aria-1.0/ +" Version: W3C Candidate Recommendation 15 December 2016 +let dpub_role = [ + \ 'dpub-abstract', + \ 'dpub-afterword', + \ 'dpub-appendix', + \ 'dpub-biblioentry', + \ 'dpub-bibliography', + \ 'dpub-biblioref', + \ 'dpub-chapter', + \ 'dpub-cover', + \ 'dpub-epilogue', + \ 'dpub-footnote', + \ 'dpub-footnotes', + \ 'dpub-foreword', + \ 'dpub-glossary', + \ 'dpub-glossdef', + \ 'dpub-glossref', + \ 'dpub-glossterm', + \ 'dpub-index', + \ 'dpub-locator', + \ 'dpub-noteref', + \ 'dpub-notice', + \ 'dpub-pagebreak', + \ 'dpub-pagelist', + \ 'dpub-part', + \ 'dpub-preface', + \ 'dpub-prologue', + \ 'dpub-pullquote', + \ 'dpub-qna', + \ 'dpub-subtitle', + \ 'dpub-tip', + \ 'dpub-title', + \ 'dpub-toc' +\ ] + let role = extend(widget_role, document_structure) let role = extend(role, landmark_role) let role = extend(role, dpub_role) -" http://www.w3.org/TR/wai-aria/states_and_properties#state_prop_taxonomy -"let global_states_and_properties = {'aria-atomic': ['true', 'false'], 'aria-busy': ['true', 'false'], 'aria-controls': [], 'aria-describedby': [], 'aria-disabled': ['true', 'false'], 'aria-dropeffect': ['copy', 'move', 'link', 'execute', 'popup', 'none'], 'aria-flowto': [], 'aria-grabbed': ['true', 'false', 'undefined'], 'aria-haspopup': ['true', 'false'], 'aria-hidden': ['true', 'false'], 'aria-invalid': ['grammar', 'spelling', 'true', 'false'], 'aria-label': [], 'aria-labelledby': [], 'aria-live': ['off', 'polite', 'assertive'], 'aria-owns': [], 'aria-relevant': ['additions', 'removals', 'text', 'all']} -let widget_attributes = {'aria-autocomplete': ['inline', 'list', 'both', 'none'], 'aria-checked': ['true', 'false', 'mixed', 'undefined'], 'aria-disabled': ['true', 'false'], 'aria-expanded': ['true', 'false', 'undefined'], 'aria-haspopup': ['true', 'false'], 'aria-hidden': ['true', 'false'], 'aria-invalid': ['grammar', 'spelling', 'true', 'false'], 'aria-label': [], 'aria-level': [], 'aria-multiline': ['true', 'false'], 'aria-multiselectable': ['true', 'false'], 'aria-orientation': ['horizontal', 'vertical'], 'aria-pressed': ['true', 'false', 'mixed', 'undefined'], 'aria-readonly': ['true', 'false'], 'aria-required': ['true', 'false'], 'aria-selected': ['true', 'false', 'undefined'], 'aria-sort': ['ascending', 'descending', 'none', 'other'], 'aria-valuemax': [], 'aria-valuemin': [], 'aria-valuenow': [], 'aria-valuetext': []} -let live_region_attributes = {'aria-atomic': ['true', 'false'], 'aria-busy': ['true', 'false'], 'aria-live': ['off', 'polite', 'assertive'], 'aria-relevant': ['additions', 'removals', 'text', 'all', 'additions text']} -let drag_and_drop_attributes = {'aria-dropeffect': ['copy', 'move', 'link', 'execute', 'popup', 'none'], 'aria-grabbed': ['true', 'false', 'undefined']} -let relationship_attributes = {'aria-activedescendant': [], 'aria-controls': [], 'aria-describedby': [], 'aria-flowto': [], 'aria-labelledby': [], 'aria-owns': [], 'aria-posinset': [], 'aria-setsize': []} -let aria_attributes = widget_attributes +" https://www.w3.org/TR/wai-aria-1.1/#states_and_properties +let global_states_and_properties = { + \ 'aria-atomic': ['true', 'false'], + \ 'aria-busy': ['true', 'false'], + \ 'aria-controls': [], + \ 'aria-current': [], + \ 'aria-describedby': [], + \ 'aria-disabled': ['true', 'false'], + \ 'aria-dropeffect': ['copy', 'move', 'link', 'execute', 'popup', 'none'], + \ 'aria-errormessage': [], + \ 'aria-flowto': [], + \ 'aria-grabbed': ['true', 'false', 'undefined'], + \ 'aria-haspopup': ['true', 'false'], + \ 'aria-hidden': ['true', 'false'], + \ 'aria-invalid': ['grammar', 'spelling', 'true', 'false'], + \ 'aria-keyshortcuts': [], + \ 'aria-label': [], + \ 'aria-labelledby': [], + \ 'aria-live': ['off', 'polite', 'assertive'], + \ 'aria-owns': [], + \ 'aria-relevant': ['additions', 'removals', 'text', 'all'], + \ 'aria-roledescription': [], +\ } + +let widget_attributes = { + \ 'aria-autocomplete': ['inline', 'list', 'both', 'none'], + \ 'aria-checked': ['true', 'false', 'mixed', 'undefined'], + \ 'aria-disabled': ['true', 'false'], + \ 'aria-errormessage': [], + \ 'aria-expanded': ['true', 'false', 'undefined'], + \ 'aria-haspopup': ['true', 'false'], + \ 'aria-hidden': ['true', 'false'], + \ 'aria-invalid': ['grammar', 'spelling', 'true', 'false'], + \ 'aria-label': [], + \ 'aria-level': [], + \ 'aria-modal': ['true', 'false'], + \ 'aria-multiline': ['true', 'false'], + \ 'aria-multiselectable': ['true', 'false'], + \ 'aria-orientation': ['horizontal', 'vertical'], + \ 'aria-placeholder': [], + \ 'aria-pressed': ['true', 'false', 'mixed', 'undefined'], + \ 'aria-readonly': ['true', 'false'], + \ 'aria-required': ['true', 'false'], + \ 'aria-selected': ['true', 'false', 'undefined'], + \ 'aria-sort': ['ascending', 'descending', 'none', 'other'], + \ 'aria-valuemax': [], + \ 'aria-valuemin': [], + \ 'aria-valuenow': [], + \ 'aria-valuetext': [] +\ } + +let live_region_attributes = { + \ 'aria-atomic': ['true', 'false'], + \ 'aria-busy': ['true', 'false'], + \ 'aria-live': ['off', 'polite', 'assertive'], + \ 'aria-relevant': ['additions', 'removals', 'text', 'all', 'additions text'] +\ } + +let drag_and_drop_attributes = { + \ 'aria-dropeffect': ['copy', 'move', 'link', 'execute', 'popup', 'none'], + \ 'aria-grabbed': ['true', 'false', 'undefined'] +\ } + +let relationship_attributes = { + \ 'aria-activedescendant': [], + \ 'aria-colcount': [], + \ 'aria-colindex': [], + \ 'aria-colspan': [], + \ 'aria-controls': [], + \ 'aria-describedby': [], + \ 'aria-details': [], + \ 'aria-errormessage': [], + \ 'aria-flowto': [], + \ 'aria-labelledby': [], + \ 'aria-owns': [], + \ 'aria-posinset': [], + \ 'aria-rowcount': [], + \ 'aria-rowindex': [], + \ 'aria-rowspan': [], + \ 'aria-setsize': [] +\ } + +let aria_attributes = global_states_and_properties +let aria_attributes = extend(aria_attributes, widget_attributes) let aria_attributes = extend(aria_attributes, live_region_attributes) let aria_attributes = extend(aria_attributes, drag_and_drop_attributes) let aria_attributes = extend(aria_attributes, relationship_attributes) @@ -84,6 +271,8 @@ let role_attributes['status'] = abstract_role['composite'] + role_attributes['re let role_attributes['tab'] = abstract_role['sectionhead'] + abstract_role['widget'] + ['aria-selected'] let role_attributes['tabpanel'] = role_attributes['region'] let role_attributes['textbox'] = abstract_role['input'] + ['aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required'] +let role_attributes['searchbox'] = role_attributes['textbox'] +let role_attributes['switch'] = role_attributes['checkbox'] let role_attributes['timer'] = role_attributes['status'] let role_attributes['tooltip'] = abstract_role['section'] let role_attributes['treeitem'] = role_attributes['listitem'] + role_attributes['option'] @@ -101,16 +290,22 @@ let role_attributes['treegrid'] = role_attributes['grid'] + role_attributes['tre let role_attributes['document'] = abstract_role['structure'] + ['aria-expanded'] let role_attributes['article'] = role_attributes['document'] + role_attributes['region'] +let role_attributes['cell'] = abstract_role['section'] + ['aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan'] let role_attributes['columnheader'] = role_attributes['gridcell'] + abstract_role['sectionhead'] + ['aria-sort'] let role_attributes['definition'] = abstract_role['section'] +let role_attributes['feed'] = role_attributes['list'] +let role_attributes['figure'] = abstract_role['section'] let role_attributes['heading'] = abstract_role['sectionhead'] + ['aria-level'] let role_attributes['img'] = abstract_role['section'] let role_attributes['math'] = abstract_role['section'] let role_attributes['note'] = abstract_role['section'] let role_attributes['presentation'] = abstract_role['structure'] +let role_attributes['none'] = role_attributes['presentation'] let role_attributes['row'] = role_attributes['group'] + ['aria-level', 'aria-selected'] let role_attributes['rowheader'] = role_attributes['gridcell'] + abstract_role['sectionhead'] let role_attributes['separator'] = abstract_role['structure'] + ['aria-expanded'] +let role_attributes['table'] = abstract_role['section'] + ['aria-colcount', 'aria-rowcount'] +let role_attributes['term'] = abstract_role['section'] " Landmark Roles let role_attributes['application'] = abstract_role['landmark'] @@ -126,19 +321,30 @@ let role_attributes['search'] = abstract_role['landmark'] let aria_attributes_value = { \ 'aria-autocomplete': ['ID', ''], \ 'aria-checked': ['Token', ''], + \ 'aria-colcount': ['Number', ''], + \ 'aria-colindex': ['Number', ''], + \ 'aria-colspan': ['Number', ''], \ 'aria-disabled': ['true/false', ''], + \ 'aria-errormessage': ['ID', ''], \ 'aria-expanded': ['Token', ''], - \ 'aria-haspopup': ['true/false', ''], + \ 'aria-haspopup': ['Token', ''], \ 'aria-hidden': ['true/false', ''], \ 'aria-invalid': ['Token', ''], + \ 'aria-keyshortcuts': ['String', ''], \ 'aria-label': ['String', ''], \ 'aria-level': ['Int', ''], + \ 'aria-modal': ['true/false', ''], \ 'aria-multiline': ['true/false', ''], \ 'aria-multiselectable': ['true/false', ''], \ 'aria-orientation': ['Token', ''], + \ 'aria-placeholder': ['String', ''], \ 'aria-pressed': ['Token', ''], \ 'aria-readonly': ['true/false', ''], \ 'aria-required': ['true/false', ''], + \ 'aria-roledescription': ['String', ''], + \ 'aria-rowcount': ['Number', ''], + \ 'aria-rowindex': ['Number', ''], + \ 'aria-rowspan': ['Number', ''], \ 'aria-selected': ['Token', ''], \ 'aria-sort': ['Token', ''], \ 'aria-valuemax': ['Number', ''], diff --git a/autoload/xml/html5.vim b/autoload/xml/html5.vim index 12c61363..73b24a4c 100644 --- a/autoload/xml/html5.vim +++ b/autoload/xml/html5.vim @@ -80,6 +80,9 @@ let attributes_value = { \ 'accept-charset': ['Charset', ''], \ 'accesskey': ['Character', ''], \ 'action': ['URL', ''], + \ 'allowfullscreen': ['Bool', ''], + \ 'allowpaymentrequest': ['Bool', ''], + \ 'allowusermedia': ['Bool', ''], \ 'alt': ['Text', ''], \ 'async': ['Bool', ''], \ 'autocomplete': ['*Token', ''], @@ -142,6 +145,7 @@ let attributes_value = { \ 'optimum': ['Number', ''], \ 'pattern': ['Pattern', ''], \ 'placeholder': ['Text', ''], + \ 'playsinline': ['Bool', ''], \ 'poster': ['URL', ''], \ 'preload': ['Token', ''], \ 'pubdate': ['Bool', ''], @@ -315,10 +319,10 @@ if !exists('g:html5_aria_attributes_complete') let g:html5_aria_attributes_complete = 1 endif if g:html5_aria_attributes_complete == 1 - " Ref: http://www.w3.org/TR/wai-aria/roles - " Version: Draft 15 December 2009 - let widget_role = ['alert', 'alertdialog', 'button', 'checkbox', 'combobox', 'dialog', 'gridcell', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'radiogroup', 'scrollbar', 'slider', 'spinbutton', 'status', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'treeitem', 'combobox', 'grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'] - let document_structure = ['article', 'columnheader', 'definition', 'directory', 'document', 'group', 'heading', 'img', 'list', 'listitem', 'math', 'note', 'presentation', 'region', 'row', 'rowheader', 'separator'] + " Ref: https://www.w3.org/TR/wai-aria-1.1/#role_definitions + " Version: W3C Candidate Recommendation 27 October 2016 + let widget_role = ['alert', 'alertdialog', 'button', 'checkbox', 'combobox', 'dialog', 'gridcell', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'radiogroup', 'scrollbar', 'searchbox', 'slider', 'spinbutton', 'status', 'switch', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'treeitem', 'combobox', 'grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'] + let document_structure = ['article', 'cell', 'columnheader', 'definition', 'directory', 'document', 'feed', 'figure', 'group', 'heading', 'img', 'list', 'listitem', 'math', 'none', 'note', 'presentation', 'region', 'row', 'rowheader', 'separator', 'table', 'term'] let landmark_role = ['application', 'banner', 'complementary', 'contentinfo', 'form', 'main', 'navigation', 'search'] let dpub_role = ['dpub-abstract', 'dpub-afterword', 'dpub-appendix', 'dpub-biblioentry', 'dpub-bibliography', 'dpub-biblioref', 'dpub-chapter', 'dpub-cover', 'dpub-epilogue', 'dpub-footnote', 'dpub-footnotes', 'dpub-foreword', 'dpub-glossary', 'dpub-glossdef', 'dpub-glossref', 'dpub-glossterm', 'dpub-index', 'dpub-locator', 'dpub-noteref', 'dpub-notice', 'dpub-pagebreak', 'dpub-pagelist', 'dpub-part', 'dpub-preface', 'dpub-prologue', 'dpub-pullquote', 'dpub-qna', 'dpub-subtitle', 'dpub-tip', 'dpub-title', 'dpub-toc'] let role = extend(widget_role, document_structure) @@ -336,10 +340,33 @@ let metadata_elements = ['link', 'style', 'meta', 'script', 'noscript', 'command let flow_elements = phrasing_elements + ['p', 'hr', 'pre', 'ul', 'ol', 'dl', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'address', 'blockquote', 'ins', 'del', 'element', 'object', 'main', 'map', 'noscript', 'section', 'nav', 'article', 'aside', 'header', 'footer', 'video', 'audio', 'figure', 'table', 'template', 'form', 'fieldset', 'menu', 'canvas', 'details'] -" http://dev.w3.org/html5/spec/Overview.html#linkTypes -let linktypes = ['alternate', 'author', 'bookmark', 'external', 'help', 'icon', 'license', 'next', 'nofollow', 'noreferrer', 'pingback', 'prefetch', 'prev', 'search', 'stylesheet', 'sidebar', 'tag'] +" https://html.spec.whatwg.org/#linkTypes +let linktypes = ['alternate', 'author', 'bookmark', 'dns-prefetch', 'external', 'help', 'icon', 'license', 'next', 'nofollow', 'noreferrer', 'noopener', 'pingback', 'preconnect', 'prefetch', 'preload', 'prerender', 'prev', 'search', 'stylesheet', 'tag'] +" https://w3c.github.io/manifest/ +let linkreltypes = linktypes +let linkreltypes = linkreltypes + ['manifest'] " http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html -let linkreltypes = linktypes + ['canonical', 'import'] +" http://www.ysearchblog.com/2009/02/12/fighting-duplication-adding-more-arrows-to-your-quiver/ +" http://blogs.bing.com/webmaster/2009/02/12/partnering-to-help-solve-duplicate-content-issues +let linkreltypes = linkreltypes + ['canonical'] +" http://w3c.github.io/webcomponents/spec/imports/ +let linkreltypes = linkreltypes + ['import'] +" https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint +let linkreltypes = linkreltypes + ['webmention'] +" http://www.opensearch.org/Specifications/OpenSearch/1.1#Autodiscovery_in_HTML.2FXHTML +let linkreltypes = linkreltypes + ['search'] +" http://microformats.org/wiki/rel-sitemap +let linkreltypes = linkreltypes + ['sitemap'] +" https://www.ampproject.org/docs/get_started/create/prepare_for_discovery +let linkreltypes = linkreltypes + ['amphtml'] +" https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html +let linkreltypes = linkreltypes + ['apple-touch-icon', 'apple-touch-icon-precomposed', 'apple-touch-startup-image'] +" https://developer.chrome.com/webstore/inline_installation +let linkreltypes = linkreltypes + ['chrome-webstore-item'] +" http://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#rfc.section.4 +let linkreltypes = linkreltypes + ['hub'] +" https://golem.ph.utexas.edu/~distler/blog/archives/000320.html +let linkreltypes = linkreltypes + ['pgpkey'] " a and button are special elements for interactive, some element can't be its descendent let abutton_dec = 'details\\|embed\\|iframe\\|keygen\\|label\\|menu\\|select\\|textarea' @@ -551,7 +578,7 @@ let g:xmldata_html5 = { \ ], \ 'iframe': [ \ [], - \ extend(copy(global_attributes), {'src': [], 'srcdoc': [], 'name': [], 'width': [], 'height': [], 'sandbox': ['allow-same-origin', 'allow-forms', 'allow-scripts'], 'seamless': ['seamless', ''], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url']}) + \ extend(copy(global_attributes), {'src': [], 'srcdoc': [], 'name': [], 'width': [], 'height': [], 'sandbox': ['allow-same-origin', 'allow-forms', 'allow-scripts'], 'seamless': ['seamless', ''], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url'], 'allowfullscreen': [], 'allowpaymentrequest': [], 'allowusermedia': []}) \ ], \ 'img': [ \ [], @@ -807,7 +834,7 @@ let g:xmldata_html5 = { \ ], \ 'video': [ \ flow_elements + ['source', 'track'], - \ extend(copy(global_attributes), {'autoplay': ['autoplay', ''], 'preload': ['none', 'metadata', 'auto', ''], 'controls': ['controls', ''], 'loop': ['loop', ''], 'poster': [], 'height': [], 'width': [], 'src': []}) + \ extend(copy(global_attributes), {'autoplay': ['autoplay', ''], 'preload': ['none', 'metadata', 'auto', ''], 'controls': ['controls', ''], 'loop': ['loop', ''], 'playsinline': ['playsinline', ''], 'poster': [], 'height': [], 'width': [], 'src': []}) \ ], \ 'wbr': [ \ [], diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 56508dc8..edf87bb7 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -985,14 +985,17 @@ endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'toml') == -1 " Rust uses several TOML config files that are not named with .toml. -autocmd BufNewFile,BufRead *.toml,Cargo.lock,.cargo/config set filetype=toml +autocmd BufNewFile,BufRead *.toml,Cargo.lock,*/.cargo/config set filetype=toml endif " ftdetect/typescript.vim if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'typescript') == -1 -autocmd BufNewFile,BufRead *.ts,*.tsx setlocal filetype=typescript +" use `set filetype` to override default filetype=xml for *.ts files +autocmd BufNewFile,BufRead *.ts set filetype=typescript +" use `setfiletype` to not override any other plugins like ianks/vim-tsx +autocmd BufNewFile,BufRead *.tsx setfiletype typescript endif @@ -1018,6 +1021,20 @@ au BufRead,BufNewFile *.vm set ft=velocity syntax=velocity endif +" ftdetect/vim-literate-coffeescript.vim +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'coffee-script') == -1 + +" Language: Literate CoffeeScript +" Maintainer: Michael Smith <michael@diglumi.com> +" URL: https://github.com/mintplant/vim-literate-coffeescript +" License: MIT + +autocmd BufNewFile,BufRead *.litcoffee set filetype=litcoffee +autocmd BufNewFile,BufRead *.coffee.md set filetype=litcoffee + + +endif + " ftdetect/vue.vim if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vue') == -1 diff --git a/ftplugin/blade.vim b/ftplugin/blade.vim index 68e80883..34879610 100644 --- a/ftplugin/blade.vim +++ b/ftplugin/blade.vim @@ -23,7 +23,8 @@ setlocal comments+=s:{{--,m:\ \ \ \ ,e:--}} if exists('loaded_matchit') && exists('b:match_words') " Append to html matchit words let b:match_words .= ',' . - \ '@\%(section\|if\|unless\|foreach\|forelse\|for\|while\|push\|can\|cannot\|hasSection\|php\|verbatim\)\>' . + \ '@\%(section\s*([^\,]*)\|if\|unless\|foreach\|forelse\|for\|while\|push\|can\|cannot\|hasSection\|' . + \ 'php\s*(\@!\|verbatim\|component\|slot\|prepend\)' . \ ':' . \ '@\%(else\|elseif\|empty\|break\|continue\|elsecan\|elsecannot\)\>' . \ ':' . diff --git a/ftplugin/dart.vim b/ftplugin/dart.vim index 9b2e8d32..b3b7291d 100644 --- a/ftplugin/dart.vim +++ b/ftplugin/dart.vim @@ -25,7 +25,9 @@ let &l:errorformat = \ '%m' \ ], ',') +setlocal includeexpr=dart#resolveUri(v:fname) +setlocal isfname+=: -let b:undo_ftplugin = 'setl et< fo< sw< sts< com< cms<' +let b:undo_ftplugin = 'setl et< fo< sw< sts< com< cms< inex< isf<' endif diff --git a/after/ftplugin/vue.vim b/ftplugin/litcoffee.vim index fd786923..ef4aee21 100644 --- a/after/ftplugin/vue.vim +++ b/ftplugin/litcoffee.vim @@ -1,5 +1,5 @@ -if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vue') == -1 +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'coffee-script') == -1 -setlocal suffixesadd+=.vue +runtime ftplugin/coffee.vim endif diff --git a/ftplugin/nginx.vim b/ftplugin/nginx.vim index efcccbd0..5ae81d88 100644 --- a/ftplugin/nginx.vim +++ b/ftplugin/nginx.vim @@ -2,4 +2,8 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nginx') == -1 setlocal commentstring=#\ %s +setlocal iskeyword+=. +setlocal iskeyword+=/ +setlocal iskeyword+=: + endif diff --git a/ftplugin/vue.vim b/ftplugin/vue.vim index 9b4ec9b1..4bb5ae20 100644 --- a/ftplugin/vue.vim +++ b/ftplugin/vue.vim @@ -11,4 +11,6 @@ endif runtime! ftplugin/html.vim +setlocal suffixesadd+=.vue + endif diff --git a/indent/blade.vim b/indent/blade.vim index 97f7f293..95cc00a4 100644 --- a/indent/blade.vim +++ b/indent/blade.vim @@ -4,22 +4,22 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'blade') == -1 " Language: Blade (Laravel) " Maintainer: Jason Walton <jwalton512@gmail.com> -if exists("b:did_indent") +if exists('b:did_indent') finish endif runtime! indent/html.vim let s:htmlindent = &indentexpr -unlet! b:did_indent +unlet! b:did_indent runtime! indent/php.vim let s:phpindent = &indentexpr -unlet! b:did_indent let b:did_indent = 1 " Doesn't include 'foreach' and 'forelse' because these already get matched by 'for'. -let s:directives_start = 'if\|else\|unless\|for\|while\|empty\|push\|section\|can\|hasSection\|verbatim' +let s:directives_start = 'if\|else\|unless\|for\|while\|empty\|push\|section\|can\|hasSection\|verbatim\|php\|' . + \ 'component\|slot\|prepend' let s:directives_end = 'else\|end\|empty\|show\|stop\|append\|overwrite' if exists('g:blade_custom_directives_pairs') @@ -29,55 +29,71 @@ endif setlocal autoindent setlocal indentexpr=GetBladeIndent() -exe "setlocal indentkeys=o,O,<>>,!^F,0=}},0=!!},=@" . substitute(s:directives_end, '\\|', ',=@', 'g') +exe 'setlocal indentkeys=o,O,<>>,!^F,0=}},0=!!},=@' . substitute(s:directives_end, '\\|', ',=@', 'g') " Only define the function once. -if exists("*GetBladeIndent") +if exists('*GetBladeIndent') finish endif +function! s:IsStartingDelimiter(lnum) + let line = getline(a:lnum) + return line =~# '\%(\w\|@\)\@<!@\%(' . s:directives_start . '\)\%(.*@end\|.*@stop\)\@!' + \ || line =~# '{{\%(.*}}\)\@!' + \ || line =~# '{!!\%(.*!!}\)\@!' + \ || line =~# '<?\%(.*?>\)\@!' +endfunction + function! GetBladeIndent() - let lnum = prevnonblank(v:lnum-1) + let lnum = prevnonblank(v:lnum - 1) if lnum == 0 return 0 endif - let line = substitute(substitute(getline(lnum), '\s\+$', '', ''), '^\s\+', '', '') - let cline = substitute(substitute(getline(v:lnum), '\s\+$', '', ''), '^\s\+', '', '') + let line = getline(lnum) + let cline = getline(v:lnum) let indent = indent(lnum) - if cline =~# '@\%(' . s:directives_end . '\)' || - \ cline =~# '\%(<?.*\)\@<!?>\|\%({{.*\)\@<!}}\|\%({!!.*\)\@<!!!}' - let indent = indent - &sw - elseif line =~# '<?\%(.*?>\)\@!\|@php\%(\s*(\)\@!' - let indent = indent + &sw - else - if exists("*GetBladeIndentCustom") - let hindent = GetBladeIndentCustom() - " Don't use PHP indentation if line is a comment - elseif line !~# '^\s*\%(#\|//\)\|\*/\s*$' && ( - \ searchpair('@include\%(If\)\?\s*(', '', ')', 'bWr') || - \ searchpair('{!!', '', '!!}', 'bWr') || - \ searchpair('{{', '', '}}', 'bWr') || - \ searchpair('<?', '', '?>', 'bWr') || - \ searchpair('@php\%(\s*(\)\@!', '', '@endphp', 'bWr') ) - execute 'let hindent = ' . s:phpindent - else - execute 'let hindent = ' . s:htmlindent - endif - if hindent > -1 - let indent = hindent - endif - endif - let increase = indent + &sw - if line =~# '@\%(section\)\%(.*@end\)\@!' && line !~# '@\%(section\)\s*([^,]*)' - return indent - elseif line =~# '@\%(' . s:directives_start . '\)\%(.*@end\|.*@stop\)\@!' || - \ line =~# '{{\%(.*}}\)\@!' || line =~# '{!!\%(.*!!}\)\@!' - return increase - else + " 1. Check for special directives + " @section is a single-line directive if it has a second argument. + " @php is a single-line directive if it is followed by parentheses. + if (line =~# '@section\%(.*@end\)\@!' && line !~# '@section\s*([^,]*)') + \ || line =~# '@php\s*(' return indent endif + + " 2. When the current line is an ending delimiter: decrease indentation + " if the previous line wasn't a starting delimiter. + if cline =~# '^\s*@\%(' . s:directives_end . '\)' + \ || cline =~# '\%(<?.*\)\@<!?>' + \ || cline =~# '\%({{.*\)\@<!}}' + \ || cline =~# '\%({!!.*\)\@<!!!}' + return s:IsStartingDelimiter(lnum) ? indent : indent - &sw + endif + + " 3. Increase indentation if the line contains a starting delimiter. + if s:IsStartingDelimiter(lnum) + return indent + &sw + endif + + " 4. External indent scripts (PHP and HTML) + execute 'let indent = ' . s:htmlindent + + if exists('*GetBladeIndentCustom') + let indent = GetBladeIndentCustom() + elseif line !~# '^\s*\%(#\|//\)\|\*/\s*$' && ( + \ searchpair('@include\%(If\)\?\s*(', '', ')', 'bWr') || + \ searchpair('{!!', '', '!!}', 'bWr') || + \ searchpair('{{', '', '}}', 'bWr') || + \ searchpair('<?', '', '?>', 'bWr') || + \ searchpair('@php\s*(\@!', '', '@endphp', 'bWr') ) + " Only use PHP's indent if the region spans multiple lines + if !s:IsStartingDelimiter(v:lnum) + execute 'let indent = ' . s:phpindent + endif + endif + + return indent endfunction endif diff --git a/indent/erlang.vim b/indent/erlang.vim index b1186ca8..64525bbd 100644 --- a/indent/erlang.vim +++ b/indent/erlang.vim @@ -6,9 +6,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'erlang') == -1 " Contributors: Edwin Fine <efine145_nospam01 at usa dot net> " Pawel 'kTT' Salata <rockplayer.pl@gmail.com> " Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" Last Update: 2013-Jul-21 +" Last Update: 2017-Feb-28 " License: Vim license -" URL: https://github.com/hcs42/vim-erlang +" URL: https://github.com/vim-erlang/vim-erlang-runtime " Note About Usage: " This indentation script works best with the Erlang syntax file created by @@ -528,7 +528,9 @@ endfunction " ok. % IsLineAtomContinuation = false function! s:IsLineAtomContinuation(lnum) if has('syntax_items') - return synIDattr(synID(a:lnum, 1, 0), 'name') =~# '^erlangQuotedAtom' + let syn_name = synIDattr(synID(a:lnum, 1, 0), 'name') + return syn_name =~# '^erlangQuotedAtom' || + \ syn_name =~# '^erlangQuotedRecord' else return 0 endif @@ -682,7 +684,7 @@ function! s:BeginningOfClauseFound(stack, token, stored_vcol, lnum, i) call s:Pop(a:stack) if empty(a:stack) call s:Log(' Stack is ["when"], so LTI is in a guard -> return') - return [1, a:stored_vcol + &sw + 2] + return [1, a:stored_vcol + shiftwidth() + 2] else return [1, s:UnexpectedToken(a:token, a:stack)] endif @@ -691,7 +693,7 @@ function! s:BeginningOfClauseFound(stack, token, stored_vcol, lnum, i) call s:Pop(a:stack) if empty(a:stack) call s:Log(' Stack is ["->"], so LTI is in function body -> return') - return [1, a:stored_vcol + &sw] + return [1, a:stored_vcol + shiftwidth()] elseif a:stack[0] ==# ';' call s:Pop(a:stack) @@ -843,7 +845,7 @@ function! s:ErlangCalcIndent2(lnum, stack) elseif token ==# 'begin' let [ret, res] = s:BeginElementFound(stack, token, curr_vcol, - \stored_vcol, 'end', &sw) + \stored_vcol, 'end', shiftwidth()) if ret | return res | endif " case EXPR of BRANCHES end @@ -894,11 +896,11 @@ function! s:ErlangCalcIndent2(lnum, stack) elseif stack == ['->'] call s:Log(' LTI is in a branch after ' . \'"of/receive/after/if/catch" -> return') - return stored_vcol + &sw + return stored_vcol + shiftwidth() elseif stack == ['when'] call s:Log(' LTI is in a guard after ' . \'"of/receive/after/if/catch" -> return') - return stored_vcol + &sw + return stored_vcol + shiftwidth() else return s:UnexpectedToken(token, stack) endif @@ -934,7 +936,7 @@ function! s:ErlangCalcIndent2(lnum, stack) if empty(stack) call s:Log(' LTI is in a condition; matching ' . \'"case/if/try/receive" found') - let stored_vcol = curr_vcol + &sw + let stored_vcol = curr_vcol + shiftwidth() elseif stack[0] ==# 'align_to_begin_element' call s:Pop(stack) let stored_vcol = curr_vcol @@ -943,23 +945,23 @@ function! s:ErlangCalcIndent2(lnum, stack) \'"case/if/try/receive" found') call s:Pop(stack) call s:Pop(stack) - let stored_vcol = curr_vcol + &sw + let stored_vcol = curr_vcol + shiftwidth() elseif stack[0] ==# '->' call s:Log(' LTI is in a branch; matching ' . \'"case/if/try/receive" found') call s:Pop(stack) - let stored_vcol = curr_vcol + 2 * &sw + let stored_vcol = curr_vcol + 2 * shiftwidth() elseif stack[0] ==# 'when' call s:Log(' LTI is in a guard; matching ' . \'"case/if/try/receive" found') call s:Pop(stack) - let stored_vcol = curr_vcol + 2 * &sw + 2 + let stored_vcol = curr_vcol + 2 * shiftwidth() + 2 endif endif let [ret, res] = s:BeginElementFound(stack, token, curr_vcol, - \stored_vcol, 'end', &sw) + \stored_vcol, 'end', shiftwidth()) if ret | return res | endif elseif token ==# 'fun' @@ -985,7 +987,7 @@ function! s:ErlangCalcIndent2(lnum, stack) " stack = ['when'] => LTI is in a guard if empty(stack) call s:Log(' LTI is in a condition; matching "fun" found') - let stored_vcol = curr_vcol + &sw + let stored_vcol = curr_vcol + shiftwidth() elseif len(stack) > 1 && stack[0] ==# '->' && stack[1] ==# ';' call s:Log(' LTI is in a condition; matching "fun" found') call s:Pop(stack) @@ -993,15 +995,15 @@ function! s:ErlangCalcIndent2(lnum, stack) elseif stack[0] ==# '->' call s:Log(' LTI is in a branch; matching "fun" found') call s:Pop(stack) - let stored_vcol = curr_vcol + 2 * &sw + let stored_vcol = curr_vcol + 2 * shiftwidth() elseif stack[0] ==# 'when' call s:Log(' LTI is in a guard; matching "fun" found') call s:Pop(stack) - let stored_vcol = curr_vcol + 2 * &sw + 2 + let stored_vcol = curr_vcol + 2 * shiftwidth() + 2 endif let [ret, res] = s:BeginElementFound(stack, token, curr_vcol, - \stored_vcol, 'end', &sw) + \stored_vcol, 'end', shiftwidth()) if ret | return res | endif else " Pass: we have a function reference (e.g. "fun f/0") @@ -1275,7 +1277,7 @@ function! s:ErlangCalcIndent2(lnum, stack) " when A, " LTI let [ret, res] = s:BeginElementFoundIfEmpty(stack, token, curr_vcol, - \stored_vcol, &sw) + \stored_vcol, shiftwidth()) if ret | return res | endif else " Example: @@ -1307,7 +1309,7 @@ function! s:ErlangCalcIndent2(lnum, stack) " If LTI is between an 'after' and the corresponding " 'end', then let's return let [ret, res] = s:BeginElementFoundIfEmpty(stack, token, curr_vcol, - \stored_vcol, &sw) + \stored_vcol, shiftwidth()) if ret | return res | endif endif diff --git a/indent/eruby.vim b/indent/eruby.vim index 3736f529..5b21ab91 100644 --- a/indent/eruby.vim +++ b/indent/eruby.vim @@ -97,6 +97,7 @@ function! GetErubyIndent(...) let ind = ind + sw endif if line !~# '^\s*<%' && line =~# '%>\s*$' && line !~# '^\s*end\>' + \ && synID(v:lnum, match(cline, '\S') + 1, 1) != hlID('htmlEndTag') let ind = ind - sw endif if cline =~# '^\s*[-=]\=%>\s*$' diff --git a/indent/haskell.vim b/indent/haskell.vim index b1e1bdc4..43dc97a6 100644 --- a/indent/haskell.vim +++ b/indent/haskell.vim @@ -13,12 +13,16 @@ if exists('b:did_indent') finish endif -let b:did_indent = 1 - if !exists('g:haskell_indent_disable') let g:haskell_indent_disable = 0 endif +if g:haskell_indent_disable != 0 + finish +endif + +let b:did_indent = 1 + if !exists('g:haskell_indent_if') " if x " >>>then ... @@ -63,22 +67,16 @@ if !exists('g:haskell_indent_guard') let g:haskell_indent_guard = 2 endif -if exists("g:haskell_indent_disable") && g:haskell_indent_disable == 0 - setlocal indentexpr=GetHaskellIndent() - setlocal indentkeys=0{,0},0(,0),0[,0],!^F,o,O,0\=,0=where,0=let,0=deriving,<space> -else - setlocal nocindent - setlocal nosmartindent - setlocal autoindent -endif +setlocal indentexpr=GetHaskellIndent() +setlocal indentkeys=0},0),0],!^F,o,O,0\=,0=where,0=let,0=deriving,<space> function! s:isInBlock(hlstack) - return index(a:hlstack, 'haskellParens') > -1 || index(a:hlstack, 'haskellBrackets') > -1 || index(a:hlstack, 'haskellBlock') > -1 || index(a:hlstack, 'haskellBlockComment') > -1 || index(a:hlstack, 'haskellPragma') > -1 + return index(a:hlstack, 'haskellDelimiter') > -1 || index(a:hlstack, 'haskellParens') > -1 || index(a:hlstack, 'haskellBrackets') > -1 || index(a:hlstack, 'haskellBlock') > -1 || index(a:hlstack, 'haskellBlockComment') > -1 || index(a:hlstack, 'haskellPragma') > -1 endfunction -function! s:stripTrailingComment(line) - if a:line =~ '^\s*--\(-\+\|\s\+\)' || a:line =~ '^\s*{-' - return a:line +function! s:stripComment(line) + if a:line =~ '^\s*--\(-*\s\+\|$\)' + return '' else let l:stripped = split(a:line, '-- ') if len(l:stripped) > 1 @@ -144,7 +142,7 @@ function! GetHaskellIndent() return -1 endif - let l:prevline = s:stripTrailingComment(getline(v:lnum - 1)) + let l:prevline = s:stripComment(getline(v:lnum - 1)) let l:line = getline(v:lnum) " indent multiline strings @@ -161,13 +159,14 @@ function! GetHaskellIndent() return 0 endif - " comment indentation - if l:line =~ '^\s*--' - return match(l:prevline, '-- ') - endif - if l:prevline =~ '^\s*--' - return match(l:prevline, '\S') - endif + " " comment indentation + " if l:line =~ '^\s*--' + " let l:s = match(l:prevline, '-- ') + " if l:s > -1 + " endif + " " if l:prevline =~ '^\s*--' + " " return match(l:prevline, '\S') + " " endif " { foo :: Int " >>, @@ -176,7 +175,7 @@ function! GetHaskellIndent() " ... " >>, if l:line =~ '^\s*,' - if s:isInBlock(l:hlstack) + if s:isInBlock(s:getHLStack(line('.'), col('.'))) normal! 0 call search(',', 'cW') let l:n = s:getNesting(s:getHLStack(line('.'), col('.'))) @@ -395,7 +394,7 @@ function! GetHaskellIndent() " foo " >>{ - if l:line =~ '^\s*{' && l:prevline !~ '^{' + if l:line =~ '^\s*{ ' let l:s = match(l:prevline, '\S') if l:s >= 0 return l:s + &shiftwidth @@ -477,16 +476,7 @@ function! GetHaskellIndent() return s:indentMatching(']') endif - " do not reindent indented lines - if match(l:prevline, '\S') < match(l:line, '\S') - return -1 - endif - - if l:line !~ '^\s*[=-]>\s' && l:line =~ '^\s*[!#$%&*+./<>?@\\^|~-]\+' - return -1 - endif - - return match(l:prevline, '\S') + return -1 endfunction endif diff --git a/indent/javascript.vim b/indent/javascript.vim index e5fc7c9f..2237b4b9 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -4,7 +4,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == " Language: Javascript " Maintainer: Chris Paul ( https://github.com/bounceme ) " URL: https://github.com/pangloss/vim-javascript -" Last Change: January 24, 2017 +" Last Change: March 9, 2017 " Only load this indent file when no other was loaded. if exists('b:did_indent') @@ -16,6 +16,10 @@ let b:did_indent = 1 setlocal indentexpr=GetJavascriptIndent() setlocal autoindent nolisp nosmartindent setlocal indentkeys+=0],0) +" Testable with something like: +" vim -eNs "+filetype plugin indent on" "+syntax on" "+set ft=javascript" \ +" "+norm! gg=G" '+%print' '+:q!' testfile.js \ +" | diff -uBZ testfile.js - let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys<' @@ -34,10 +38,14 @@ if exists('*shiftwidth') endfunction else function s:sw() - return &sw + return &l:shiftwidth == 0 ? &l:tabstop : &l:shiftwidth endfunction endif +" Performance for forwards search(): start search at pos rather than masking +" matches before pos. +let s:z = has('patch-7.4.984') ? 'z' : '' + " searchpair() wrapper if has('reltime') function s:GetPair(start,end,flags,skip,time,...) @@ -51,34 +59,40 @@ endif " Regex of syntax group names that are or delimit string or are comments. let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template\%(braces\)\@!' -let s:syng_str = 'string\|template' +let s:syng_str = 'string\|template\|special' let s:syng_com = 'comment\|doc' " Expression used to check whether we should skip a match with searchpair(). let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" +function s:parse_cino(f) abort + return float2nr(eval(substitute(substitute(join(split( + \ matchstr(&cino,'\C.*'.a:f.'\zs[^,]*'), 's',1), '*'.s:W) + \ , '^-\=\zs\*','',''), '^-\=\zs\.','0.',''))) +endfunction + function s:skip_func() - if !s:free || search('\m`\|\${\|\*\/','nW',s:looksyn) - let s:free = !eval(s:skip_expr) - let s:looksyn = line('.') - return !s:free + if getline('.') =~ '\%<'.col('.').'c\/.\{-}\/\|\%>'.col('.').'c[''"]\|\\$' + return eval(s:skip_expr) + elseif s:checkIn || search('\m`\|\${\|\*\/','nW'.s:z,s:looksyn) + let s:checkIn = eval(s:skip_expr) endif let s:looksyn = line('.') - return getline('.') =~ '\%<'.col('.').'c\/.\{-}\/\|\%>'.col('.').'c[''"]\|\\$' && - \ eval(s:skip_expr) + return s:checkIn endfunction function s:alternatePair(stop) let pos = getpos('.')[1:2] - while search('\m[][(){}]','bW',a:stop) - if !s:skip_func() - let idx = stridx('])}',s:looking_at()) - if idx + 1 - if s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop) <= 0 - break - endif - else - return + let pat = '[][(){};]' + while search('\m'.pat,'bW',a:stop) + if s:skip_func() | continue | endif + let idx = stridx('])};',s:looking_at()) + if idx is 3 | let pat = '[{}()]' | continue | endif + if idx + 1 + if s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop) <= 0 + break endif + else + return endif endwhile call call('cursor',pos) @@ -104,14 +118,12 @@ function s:token() endfunction function s:previous_token() - let l:n = line('.') - if (s:looking_at() !~ '\k' || search('\m\<','cbW')) && search('\m\S','bW') - if (getline('.')[col('.')-2:col('.')-1] == '*/' || line('.') != l:n && + let l:pos = getpos('.')[1:2] + if search('\m\k\{1,}\|\S','ebW') + if (getline('.')[col('.')-2:col('.')-1] == '*/' || line('.') != l:pos[0] && \ getline('.') =~ '\%<'.col('.').'c\/\/') && s:syn_at(line('.'),col('.')) =~? s:syng_com - while search('\m\/\ze[/*]','cbW') - if !search('\m\S','bW') - break - elseif s:syn_at(line('.'),col('.')) !~? s:syng_com + while search('\m\S\ze\_s*\/[/*]','bW') + if s:syn_at(line('.'),col('.')) !~? s:syng_com return s:token() endif endwhile @@ -119,73 +131,77 @@ function s:previous_token() return s:token() endif endif + call call('cursor',l:pos) return '' endfunction -function s:others(p) - return "((line2byte(line('.')) + col('.')) <= ".(line2byte(a:p[0]) + a:p[1]).") || ".s:skip_expr -endfunction - -function s:tern_skip(p) - return s:GetPair('{','}','nbW',s:others(a:p),200,a:p[0]) > 0 -endfunction - -function s:tern_col(p) - return s:GetPair('?',':\@<!::\@!','nbW',s:others(a:p) - \ .' || s:tern_skip('.string(a:p).')',200,a:p[0]) > 0 -endfunction - -function s:label_col() - let pos = getpos('.')[1:2] - let [s:looksyn,s:free] = pos - call s:alternatePair(0) - if s:save_pos('s:IsBlock') - let poss = getpos('.')[1:2] - return call('cursor',pos) || !s:tern_col(poss) - elseif s:looking_at() == ':' - return !s:tern_col([0,0]) +function s:expr_col() + if getline('.')[col('.')-2] == ':' + return 1 endif + let bal = 0 + while search('\m[{}?:;]','bW') + if eval(s:skip_expr) | continue | endif + " switch (looking_at()) + exe { '}': "if s:GetPair('{','}','bW',s:skip_expr,200) <= 0 | return | endif", + \ ';': "return", + \ '{': "return getpos('.')[1:2] != b:js_cache[1:] && !s:IsBlock()", + \ ':': "let bal -= getline('.')[max([col('.')-2,0]):col('.')] !~ '::'", + \ '?': "let bal += 1 | if bal > 0 | return 1 | endif" }[s:looking_at()] + endwhile endfunction " configurable regexes that define continuation lines, not including (, {, or [. let s:opfirst = '^' . get(g:,'javascript_opfirst', - \ '\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)') + \ '\C\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)') let s:continuation = get(g:,'javascript_continuation', - \ '\%([-+<>=,.~!?/*^%|&:]\|\<\%(typeof\|delete\|void\|in\|instanceof\)\)') . '$' + \ '\C\%([-+<>=,.~!?/*^%|&:]\|\<\%(typeof\|new\|delete\|void\|in\|instanceof\|await\)\)') . '$' function s:continues(ln,con) - return !cursor(a:ln, match(' '.a:con,s:continuation)) && - \ eval( (['s:syn_at(line("."),col(".")) !~? "regex"'] + - \ repeat(['getline(".")[col(".")-2] != tr(s:looking_at(),">","=")'],3) + - \ repeat(['s:previous_token() != "."'],5) + [1])[ - \ index(split('/ > - + typeof in instanceof void delete'),s:token())]) + if !cursor(a:ln, match(' '.a:con,s:continuation)) + let teol = s:looking_at() + if teol == '/' + return s:syn_at(line('.'),col('.')) !~? 'regex' + elseif teol =~ '[-+>]' + return getline('.')[col('.')-2] != tr(teol,'>','=') + elseif teol =~ '\l' + return s:previous_token() != '.' + elseif teol == ':' + return s:expr_col() + endif + return 1 + endif endfunction " get the line of code stripped of comments and move cursor to the last " non-comment char. function s:Trim(ln) - call cursor(a:ln+1,1) - call s:previous_token() - return strpart(getline('.'),0,col('.')) + let pline = substitute(getline(a:ln),'\s*$','','') + let l:max = max([strridx(pline,'//'), strridx(pline,'/*')]) + while l:max != -1 && s:syn_at(a:ln, strlen(pline)) =~? s:syng_com + let pline = pline[: l:max] + let l:max = max([strridx(pline,'//'), strridx(pline,'/*')]) + let pline = substitute(pline[:-2],'\s*$','','') + endwhile + return pline is '' || cursor(a:ln,strlen(pline)) ? pline : pline endfunction " Find line above 'lnum' that isn't empty or in a comment function s:PrevCodeLine(lnum) - let l:n = prevnonblank(a:lnum) + let [l:pos, l:n] = [getpos('.')[1:2], prevnonblank(a:lnum)] while l:n - if getline(l:n) =~ '^\s*\/[/*]' - if (stridx(getline(l:n),'`') > 0 || getline(l:n-1)[-1:] == '\') && - \ s:syn_at(l:n,1) =~? s:syng_str - return l:n - endif + if getline(l:n) =~ '^\s*\/[/*]' let l:n = prevnonblank(l:n-1) - elseif s:syn_at(l:n,1) =~? s:syng_com - let l:n = s:save_pos('eval', - \ 'cursor('.l:n.',1) + search(''\m\/\*'',"bW")') + elseif stridx(getline(l:n), '*/') + 1 && s:syn_at(l:n,1) =~? s:syng_com + call cursor(l:n,1) + keepjumps norm! [* + let l:n = search('\m\S','nbW') else - return l:n + break endif endwhile + call call('cursor',l:pos) + return l:n endfunction " Check if line 'lnum' has a balanced amount of parentheses. @@ -200,7 +216,9 @@ function s:Balanced(lnum) return endif endif - let pos = match(l:line, '[][(){}]', pos + 1) + let pos = match(l:line, (l:open ? + \ '['.escape(tr(l:line[pos],'({[]})',')}][{(').l:line[pos],']').']' : + \ '[][(){}]'), pos + 1) endwhile return !l:open endfunction @@ -209,11 +227,11 @@ function s:OneScope(lnum) let pline = s:Trim(a:lnum) let kw = 'else do' if pline[-1:] == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0 - call s:previous_token() - let kw = 'for if let while with' - if index(split('await each'),s:token()) + 1 + if s:previous_token() =~# '^\%(await\|each\)$' call s:previous_token() let kw = 'for' + else + let kw = 'for if let while with' endif endif return pline[-2:] == '=>' || index(split(kw),s:token()) + 1 && @@ -245,18 +263,22 @@ function s:IsBlock() if s:looking_at() == '{' let l:n = line('.') let char = s:previous_token() - let syn = char =~ '[{>/]' ? s:syn_at(line('.'),col('.')-(char == '{')) : '' - if syn =~? 'xml\|jsx' + if match(s:stack,'\cxml\|jsx') + 1 && s:syn_at(line('.'),col('.')-1) =~? 'xml\|jsx' return char != '{' elseif char =~ '\k' - return index(split('return const let import export yield default delete var await void typeof throw case new in instanceof') - \ ,char) < (line('.') != l:n) || s:previous_token() == '.' + if char ==# 'type' + return s:previous_token() !~# '^\%(im\|ex\)port$' + endif + return index(split('return const let import export extends yield default delete var await void typeof throw case new of in instanceof') + \ ,char) < (line('.') != l:n) || s:save_pos('s:previous_token') == '.' elseif char == '>' - return getline('.')[col('.')-2] == '=' || syn =~? '^jsflow' + return getline('.')[col('.')-2] == '=' || s:syn_at(line('.'),col('.')) =~? '^jsflow' elseif char == ':' - return getline('.')[col('.')-2] != ':' && s:label_col() + return !s:save_pos('s:expr_col') + elseif char == '/' + return s:syn_at(line('.'),col('.')) =~? 'regex' endif - return syn =~? 'regex' || char !~ '[=~!<*,/?^%|&([]' && + return char !~ '[=~!<*,?^%|&([]' && \ (char !~ '[-+]' || l:n != line('.') && getline('.')[col('.')-2] == char) endif endfunction @@ -266,7 +288,9 @@ function GetJavascriptIndent() " Get the current line. call cursor(v:lnum,1) let l:line = getline('.') - let syns = s:syn_at(v:lnum, 1) + " use synstack as it validates syn state and works in an empty line + let s:stack = map(synstack(v:lnum,1),"synIDattr(v:val,'name')") + let syns = get(s:stack,-1,'') " start with strings,comments,etc. if syns =~? s:syng_com @@ -275,7 +299,7 @@ function GetJavascriptIndent() elseif l:line !~ '^\s*\/[/*]' return -1 endif - elseif syns =~? s:syng_str && l:line !~ '^[''"]' + elseif syns =~? s:syng_str if b:js_cache[0] == v:lnum - 1 && s:Balanced(v:lnum-1) let b:js_cache[0] = v:lnum endif @@ -300,11 +324,11 @@ function GetJavascriptIndent() \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum)) call call('cursor',b:js_cache[1:]) else - let [s:looksyn, s:free, top] = [v:lnum - 1, 1, (!indent(l:lnum) && + let [s:looksyn, s:checkIn, top] = [v:lnum - 1, 0, (!indent(l:lnum) && \ s:syn_at(l:lnum,1) !~? s:syng_str) * l:lnum] if idx + 1 - call s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,top) - elseif indent(v:lnum) && syns =~? 'block' + call s:GetPair(['\[','(','{'][idx],'])}'[idx],'bW','s:skip_func()',2000,top) + elseif getline(v:lnum) !~ '^\S' && syns =~? 'block' call s:GetPair('{','}','bW','s:skip_func()',2000,top) else call s:alternatePair(top) @@ -324,31 +348,27 @@ function GetJavascriptIndent() if &cino !~ ':' let switch_offset = s:W else - let cinc = matchlist(&cino,'.*:\zs\(-\)\=\(\d*\)\(\.\d\+\)\=\(s\)\=\C') - let switch_offset = max([cinc[0] is '' ? 0 : (cinc[1].1) * - \ ((strlen(cinc[2].cinc[3]) ? str2nr(cinc[2].str2nr(cinc[3][1])) : 10) * - \ (cinc[4] is '' ? 1 : s:W)) / 10, -indent(num)]) + let switch_offset = max([-indent(num),s:parse_cino(':')]) endif if pline[-1:] != '.' && l:line =~# '^\%(default\|case\)\>' return indent(num) + switch_offset endif endif endif - if idx < 0 && pline !~ '[{;]$' - if pline =~# ':\@<!:$' - call cursor(l:lnum,strlen(pline)) - let isOp = s:tern_col(b:js_cache[1:2]) * s:W - else - let isOp = (l:line =~# s:opfirst || s:continues(l:lnum,pline)) * s:W - endif + if idx < 0 && pline[-1:] !~ '[{;]' + let isOp = (l:line =~# s:opfirst || s:continues(l:lnum,pline)) * s:W let bL = s:iscontOne(l:lnum,b:js_cache[1],isOp) let bL -= (bL && l:line[0] == '{') * s:W endif + elseif idx < 0 && getline(b:js_cache[1])[b:js_cache[2]-1] == '(' && &cino =~ '(' + let pval = s:parse_cino('(') + return !pval ? (s:parse_cino('w') ? 0 : -(!!search('\m\S','W'.s:z,num))) + virtcol('.') : + \ max([indent('.') + pval + (s:GetPair('(',')','nbrmW',s:skip_expr,100,num) * s:W),0]) endif " main return - if idx + 1 || l:line[:1] == '|}' - return indent(num) + if l:line =~ '^\%([])}]\||}\)' + return max([indent(num),0]) elseif num return indent(num) + s:W + switch_offset + bL + isOp endif diff --git a/indent/litcoffee.vim b/indent/litcoffee.vim new file mode 100644 index 00000000..55398462 --- /dev/null +++ b/indent/litcoffee.vim @@ -0,0 +1,26 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'coffee-script') == -1 + +if exists('b:did_indent') + finish +endif + +runtime! indent/coffee.vim + +let b:did_indent = 1 + +setlocal indentexpr=GetLitCoffeeIndent() + +if exists('*GetLitCoffeeIndent') + finish +endif + +function GetLitCoffeeIndent() + if searchpair('^ \|\t', '', '$', 'bWnm') > 0 + return GetCoffeeIndent(v:lnum) + else + return -1 + endif +endfunc + + +endif diff --git a/indent/ruby.vim b/indent/ruby.vim index 84067fe9..8fa929be 100644 --- a/indent/ruby.vim +++ b/indent/ruby.vim @@ -20,6 +20,11 @@ if !exists('g:ruby_indent_access_modifier_style') let g:ruby_indent_access_modifier_style = 'normal' endif +if !exists('g:ruby_indent_assignment_style') + " Possible values: "variable", "hanging" + let g:ruby_indent_assignment_style = 'hanging' +endif + if !exists('g:ruby_indent_block_style') " Possible values: "expression", "do" let g:ruby_indent_block_style = 'expression' @@ -144,7 +149,507 @@ let s:block_continuation_regex = '^\s*[^])}\t ].*'.s:block_regex " Regex that describes a leading operator (only a method call's dot for now) let s:leading_operator_regex = '^\s*[.]' -" 2. Auxiliary Functions {{{1 +" 2. GetRubyIndent Function {{{1 +" ========================= + +function GetRubyIndent(...) + " 2.1. Setup {{{2 + " ---------- + + let indent_info = {} + + " The value of a single shift-width + if exists('*shiftwidth') + let indent_info.sw = shiftwidth() + else + let indent_info.sw = &sw + endif + + " For the current line, use the first argument if given, else v:lnum + let indent_info.clnum = a:0 ? a:1 : v:lnum + let indent_info.cline = getline(indent_info.clnum) + + " Set up variables for restoring position in file. Could use clnum here. + let indent_info.col = col('.') + + " 2.2. Work on the current line {{{2 + " ----------------------------- + let indent_callback_names = [ + \ 's:AccessModifier', + \ 's:ClosingBracketOnEmptyLine', + \ 's:BlockComment', + \ 's:DeindentingKeyword', + \ 's:MultilineStringOrLineComment', + \ 's:ClosingHeredocDelimiter', + \ 's:LeadingOperator', + \ ] + + for callback_name in indent_callback_names +" Decho "Running: ".callback_name + let indent = call(function(callback_name), [indent_info]) + + if indent >= 0 +" Decho "Match: ".callback_name." indent=".indent." info=".string(indent_info) + return indent + endif + endfor + + " 2.3. Work on the previous line. {{{2 + " ------------------------------- + let indent_callback_names = [ + \ 's:EmptyInsideString', + \ 's:StartOfFile', + \ 's:AfterAccessModifier', + \ 's:ContinuedLine', + \ 's:AfterBlockOpening', + \ 's:AfterHangingSplat', + \ 's:AfterUnbalancedBracket', + \ 's:AfterLeadingOperator', + \ 's:AfterEndKeyword', + \ 's:AfterIndentKeyword', + \ ] + + " Previous line number + let indent_info.plnum = s:PrevNonBlankNonString(indent_info.clnum - 1) + let indent_info.pline = getline(indent_info.plnum) + + for callback_name in indent_callback_names +" Decho "Running: ".callback_name + let indent = call(function(callback_name), [indent_info]) + + if indent >= 0 +" Decho "Match: ".callback_name." indent=".indent." info=".string(indent_info) + return indent + endif + endfor + + " 2.4. Work on the MSL line. {{{2 + " -------------------------- + let indent_callback_names = [ + \ 's:PreviousNotMSL', + \ 's:IndentingKeywordInMSL', + \ 's:ContinuedHangingOperator', + \ ] + + " Most Significant line based on the previous one -- in case it's a + " contination of something above + let indent_info.plnum_msl = s:GetMSL(indent_info.plnum) + + for callback_name in indent_callback_names +" Decho "Running: ".callback_name + let indent = call(function(callback_name), [indent_info]) + + if indent >= 0 +" Decho "Match: ".callback_name." indent=".indent." info=".string(indent_info) + return indent + endif + endfor + + " }}}2 + + " By default, just return the previous line's indent +" Decho "Default case matched" + return indent(indent_info.plnum) +endfunction + +" 3. Indenting Logic Callbacks {{{1 +" ============================ + +function! s:AccessModifier(cline_info) + let info = a:cline_info + + " If this line is an access modifier keyword, align according to the closest + " class declaration. + if g:ruby_indent_access_modifier_style == 'indent' + if s:Match(info.clnum, s:access_modifier_regex) + let class_lnum = s:FindContainingClass() + if class_lnum > 0 + return indent(class_lnum) + info.sw + endif + endif + elseif g:ruby_indent_access_modifier_style == 'outdent' + if s:Match(info.clnum, s:access_modifier_regex) + let class_lnum = s:FindContainingClass() + if class_lnum > 0 + return indent(class_lnum) + endif + endif + endif + + return -1 +endfunction + +function! s:ClosingBracketOnEmptyLine(cline_info) + let info = a:cline_info + + " If we got a closing bracket on an empty line, find its match and indent + " according to it. For parentheses we indent to its column - 1, for the + " others we indent to the containing line's MSL's level. Return -1 if fail. + let col = matchend(info.cline, '^\s*[]})]') + + if col > 0 && !s:IsInStringOrComment(info.clnum, col) + call cursor(info.clnum, col) + let closing_bracket = info.cline[col - 1] + let bracket_pair = strpart('(){}[]', stridx(')}]', closing_bracket) * 2, 2) + + if searchpair(escape(bracket_pair[0], '\['), '', bracket_pair[1], 'bW', s:skip_expr) > 0 + if closing_bracket == ')' && col('.') != col('$') - 1 + let ind = virtcol('.') - 1 + elseif g:ruby_indent_block_style == 'do' + let ind = indent(line('.')) + else " g:ruby_indent_block_style == 'expression' + let ind = indent(s:GetMSL(line('.'))) + endif + endif + + return ind + endif + + return -1 +endfunction + +function! s:BlockComment(cline_info) + " If we have a =begin or =end set indent to first column. + if match(a:cline_info.cline, '^\s*\%(=begin\|=end\)$') != -1 + return 0 + endif + return -1 +endfunction + +function! s:DeindentingKeyword(cline_info) + let info = a:cline_info + + " If we have a deindenting keyword, find its match and indent to its level. + " TODO: this is messy + if s:Match(info.clnum, s:ruby_deindent_keywords) + call cursor(info.clnum, 1) + + if searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW', + \ s:end_skip_expr) > 0 + let msl = s:GetMSL(line('.')) + let line = getline(line('.')) + + if s:IsAssignment(line, col('.')) && + \ strpart(line, col('.') - 1, 2) !~ 'do' + " assignment to case/begin/etc, on the same line + if g:ruby_indent_assignment_style == 'hanging' + " hanging indent + let ind = virtcol('.') - 1 + else + " align with variable + let ind = indent(line('.')) + endif + elseif g:ruby_indent_block_style == 'do' + " align to line of the "do", not to the MSL + let ind = indent(line('.')) + elseif getline(msl) =~ '=\s*\(#.*\)\=$' + " in the case of assignment to the MSL, align to the starting line, + " not to the MSL + let ind = indent(line('.')) + else + " align to the MSL + let ind = indent(msl) + endif + endif + return ind + endif + + return -1 +endfunction + +function! s:MultilineStringOrLineComment(cline_info) + let info = a:cline_info + + " If we are in a multi-line string or line-comment, don't do anything to it. + if s:IsInStringOrDocumentation(info.clnum, matchend(info.cline, '^\s*') + 1) + return indent(info.clnum) + endif + return -1 +endfunction + +function! s:ClosingHeredocDelimiter(cline_info) + let info = a:cline_info + + " If we are at the closing delimiter of a "<<" heredoc-style string, set the + " indent to 0. + if info.cline =~ '^\k\+\s*$' + \ && s:IsInStringDelimiter(info.clnum, 1) + \ && search('\V<<'.info.cline, 'nbW') > 0 + return 0 + endif + + return -1 +endfunction + +function! s:LeadingOperator(cline_info) + " If the current line starts with a leading operator, add a level of indent. + if s:Match(a:cline_info.clnum, s:leading_operator_regex) + return indent(s:GetMSL(a:cline_info.clnum)) + a:cline_info.sw + endif + return -1 +endfunction + +function! s:EmptyInsideString(pline_info) + " If the line is empty and inside a string (plnum would not be the real + " prevnonblank in that case), use the previous line's indent + let info = a:pline_info + + if info.cline =~ '^\s*$' && info.plnum != prevnonblank(info.clnum - 1) + return indent(prevnonblank(info.clnum)) + endif + return -1 +endfunction + +function! s:StartOfFile(pline_info) + " At the start of the file use zero indent. + if a:pline_info.plnum == 0 + return 0 + endif + return -1 +endfunction + +function! s:AfterAccessModifier(pline_info) + let info = a:pline_info + + if g:ruby_indent_access_modifier_style == 'indent' + " If the previous line was a private/protected keyword, add a + " level of indent. + if s:Match(info.plnum, s:indent_access_modifier_regex) + return indent(info.plnum) + info.sw + endif + elseif g:ruby_indent_access_modifier_style == 'outdent' + " If the previous line was a private/protected/public keyword, add + " a level of indent, since the keyword has been out-dented. + if s:Match(info.plnum, s:access_modifier_regex) + return indent(info.plnum) + info.sw + endif + endif + return -1 +endfunction + +" Example: +" +" if foo || bar || +" baz || bing +" puts "foo" +" end +" +function! s:ContinuedLine(pline_info) + let info = a:pline_info + + let col = s:Match(info.plnum, s:ruby_indent_keywords) + if s:Match(info.plnum, s:continuable_regex) && + \ s:Match(info.plnum, s:continuation_regex) + if col > 0 && s:IsAssignment(info.pline, col) + if g:ruby_indent_assignment_style == 'hanging' + " hanging indent + let ind = col - 1 + else + " align with variable + let ind = indent(info.plnum) + endif + else + let ind = indent(s:GetMSL(info.plnum)) + endif + return ind + info.sw + info.sw + endif + return -1 +endfunction + +function! s:AfterBlockOpening(pline_info) + let info = a:pline_info + + " If the previous line ended with a block opening, add a level of indent. + if s:Match(info.plnum, s:block_regex) + if g:ruby_indent_block_style == 'do' + " don't align to the msl, align to the "do" + let ind = indent(info.plnum) + info.sw + else + let plnum_msl = s:GetMSL(info.plnum) + + if getline(plnum_msl) =~ '=\s*\(#.*\)\=$' + " in the case of assignment to the msl, align to the starting line, + " not to the msl + let ind = indent(info.plnum) + info.sw + else + let ind = indent(plnum_msl) + info.sw + endif + endif + + return ind + endif + + return -1 +endfunction + +function! s:AfterLeadingOperator(pline_info) + " If the previous line started with a leading operator, use its MSL's level + " of indent + if s:Match(a:pline_info.plnum, s:leading_operator_regex) + return indent(s:GetMSL(a:pline_info.plnum)) + endif + return -1 +endfunction + +function! s:AfterHangingSplat(pline_info) + let info = a:pline_info + + " If the previous line ended with the "*" of a splat, add a level of indent + if info.pline =~ s:splat_regex + return indent(info.plnum) + info.sw + endif + return -1 +endfunction + +function! s:AfterUnbalancedBracket(pline_info) + let info = a:pline_info + + " If the previous line contained unclosed opening brackets and we are still + " in them, find the rightmost one and add indent depending on the bracket + " type. + " + " If it contained hanging closing brackets, find the rightmost one, find its + " match and indent according to that. + if info.pline =~ '[[({]' || info.pline =~ '[])}]\s*\%(#.*\)\=$' + let [opening, closing] = s:ExtraBrackets(info.plnum) + + if opening.pos != -1 + if opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + if col('.') + 1 == col('$') + return indent(info.plnum) + info.sw + else + return virtcol('.') + endif + else + let nonspace = matchend(info.pline, '\S', opening.pos + 1) - 1 + return nonspace > 0 ? nonspace : indent(info.plnum) + info.sw + endif + elseif closing.pos != -1 + call cursor(info.plnum, closing.pos + 1) + normal! % + + if s:Match(line('.'), s:ruby_indent_keywords) + return indent('.') + info.sw + else + return indent(s:GetMSL(line('.'))) + endif + else + call cursor(info.clnum, info.col) + end + endif + + return -1 +endfunction + +function! s:AfterEndKeyword(pline_info) + let info = a:pline_info + " If the previous line ended with an "end", match that "end"s beginning's + " indent. + let col = s:Match(info.plnum, '\%(^\|[^.:@$]\)\<end\>\s*\%(#.*\)\=$') + if col > 0 + call cursor(info.plnum, col) + if searchpair(s:end_start_regex, '', s:end_end_regex, 'bW', + \ s:end_skip_expr) > 0 + let n = line('.') + let ind = indent('.') + let msl = s:GetMSL(n) + if msl != n + let ind = indent(msl) + end + return ind + endif + end + return -1 +endfunction + +function! s:AfterIndentKeyword(pline_info) + let info = a:pline_info + let col = s:Match(info.plnum, s:ruby_indent_keywords) + + if col > 0 + call cursor(info.plnum, col) + let ind = virtcol('.') - 1 + info.sw + " TODO: make this better (we need to count them) (or, if a searchpair + " fails, we know that something is lacking an end and thus we indent a + " level + if s:Match(info.plnum, s:end_end_regex) + let ind = indent('.') + elseif s:IsAssignment(info.pline, col) + if g:ruby_indent_assignment_style == 'hanging' + " hanging indent + let ind = col + info.sw - 1 + else + " align with variable + let ind = indent(info.plnum) + info.sw + endif + endif + return ind + endif + + return -1 +endfunction + +function! s:PreviousNotMSL(msl_info) + let info = a:msl_info + + " If the previous line wasn't a MSL + if info.plnum != info.plnum_msl + " If previous line ends bracket and begins non-bracket continuation decrease indent by 1. + if s:Match(info.plnum, s:bracket_switch_continuation_regex) + " TODO (2016-10-07) Wrong/unused? How could it be "1"? + return indent(info.plnum) - 1 + " If previous line is a continuation return its indent. + " TODO: the || s:IsInString() thing worries me a bit. + elseif s:Match(info.plnum, s:non_bracket_continuation_regex) || s:IsInString(info.plnum, strlen(line)) + return indent(info.plnum) + endif + endif + + return -1 +endfunction + +function! s:IndentingKeywordInMSL(msl_info) + let info = a:msl_info + " If the MSL line had an indenting keyword in it, add a level of indent. + " TODO: this does not take into account contrived things such as + " module Foo; class Bar; end + let col = s:Match(info.plnum_msl, s:ruby_indent_keywords) + if col > 0 + let ind = indent(info.plnum_msl) + info.sw + if s:Match(info.plnum_msl, s:end_end_regex) + let ind = ind - info.sw + elseif s:IsAssignment(getline(info.plnum_msl), col) + if g:ruby_indent_assignment_style == 'hanging' + " hanging indent + let ind = col + info.sw - 1 + else + " align with variable + let ind = indent(info.plnum_msl) + info.sw + endif + endif + return ind + endif + return -1 +endfunction + +function! s:ContinuedHangingOperator(msl_info) + let info = a:msl_info + + " If the previous line ended with [*+/.,-=], but wasn't a block ending or a + " closing bracket, indent one extra level. + if s:Match(info.plnum_msl, s:non_bracket_continuation_regex) && !s:Match(info.plnum_msl, '^\s*\([\])}]\|end\)') + if info.plnum_msl == info.plnum + let ind = indent(info.plnum_msl) + info.sw + else + let ind = indent(info.plnum_msl) + endif + return ind + endif + + return -1 +endfunction + +" 4. Auxiliary Functions {{{1 " ====================== " Check if the character at lnum:col is inside a string, comment, or is ascii. @@ -167,6 +672,10 @@ function s:IsInStringDelimiter(lnum, col) return synIDattr(synID(a:lnum, a:col, 1), 'name') == 'rubyStringDelimiter' endfunction +function s:IsAssignment(str, pos) + return strpart(a:str, 0, a:pos - 1) =~ '=\s*$' +endfunction + " Find line above 'lnum' that isn't empty, in a comment, or in a string. function s:PrevNonBlankNonString(lnum) let in_block = 0 @@ -196,7 +705,6 @@ endfunction function s:GetMSL(lnum) " Start on the line we're at and use its indent. let msl = a:lnum - let msl_body = getline(msl) let lnum = s:PrevNonBlankNonString(a:lnum - 1) while lnum > 0 " If we have a continuation line, or we're in a string, use line as MSL. @@ -293,7 +801,6 @@ function s:GetMSL(lnum) endif endif - let msl_body = getline(msl) let lnum = s:PrevNonBlankNonString(lnum - 1) endwhile return msl @@ -398,301 +905,6 @@ function! s:FindContainingClass() return 0 endfunction -" 3. GetRubyIndent Function {{{1 -" ========================= - -function GetRubyIndent(...) - " 3.1. Setup {{{2 - " ---------- - - " The value of a single shift-width - if exists('*shiftwidth') - let sw = shiftwidth() - else - let sw = &sw - endif - - " For the current line, use the first argument if given, else v:lnum - let clnum = a:0 ? a:1 : v:lnum - - " Set up variables for restoring position in file. Could use clnum here. - let vcol = col('.') - - " 3.2. Work on the current line {{{2 - " ----------------------------- - - " Get the current line. - let line = getline(clnum) - let ind = -1 - - " If this line is an access modifier keyword, align according to the closest - " class declaration. - if g:ruby_indent_access_modifier_style == 'indent' - if s:Match(clnum, s:access_modifier_regex) - let class_line = s:FindContainingClass() - if class_line > 0 - return indent(class_line) + sw - endif - endif - elseif g:ruby_indent_access_modifier_style == 'outdent' - if s:Match(clnum, s:access_modifier_regex) - let class_line = s:FindContainingClass() - if class_line > 0 - return indent(class_line) - endif - endif - endif - - " If we got a closing bracket on an empty line, find its match and indent - " according to it. For parentheses we indent to its column - 1, for the - " others we indent to the containing line's MSL's level. Return -1 if fail. - let col = matchend(line, '^\s*[]})]') - if col > 0 && !s:IsInStringOrComment(clnum, col) - call cursor(clnum, col) - let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) - if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 - if line[col-1]==')' && col('.') != col('$') - 1 - let ind = virtcol('.') - 1 - elseif g:ruby_indent_block_style == 'do' - let ind = indent(line('.')) - else " g:ruby_indent_block_style == 'expression' - let ind = indent(s:GetMSL(line('.'))) - endif - endif - return ind - endif - - " If we have a =begin or =end set indent to first column. - if match(line, '^\s*\%(=begin\|=end\)$') != -1 - return 0 - endif - - " If we have a deindenting keyword, find its match and indent to its level. - " TODO: this is messy - if s:Match(clnum, s:ruby_deindent_keywords) - call cursor(clnum, 1) - if searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW', - \ s:end_skip_expr) > 0 - let msl = s:GetMSL(line('.')) - let line = getline(line('.')) - - if strpart(line, 0, col('.') - 1) =~ '=\s*$' && - \ strpart(line, col('.') - 1, 2) !~ 'do' - " assignment to case/begin/etc, on the same line, hanging indent - let ind = virtcol('.') - 1 - elseif g:ruby_indent_block_style == 'do' - " align to line of the "do", not to the MSL - let ind = indent(line('.')) - elseif getline(msl) =~ '=\s*\(#.*\)\=$' - " in the case of assignment to the MSL, align to the starting line, - " not to the MSL - let ind = indent(line('.')) - else - " align to the MSL - let ind = indent(msl) - endif - endif - return ind - endif - - " If we are in a multi-line string or line-comment, don't do anything to it. - if s:IsInStringOrDocumentation(clnum, matchend(line, '^\s*') + 1) - return indent('.') - endif - - " If we are at the closing delimiter of a "<<" heredoc-style string, set the - " indent to 0. - if line =~ '^\k\+\s*$' - \ && s:IsInStringDelimiter(clnum, 1) - \ && search('\V<<'.line, 'nbW') > 0 - return 0 - endif - - " If the current line starts with a leading operator, add a level of indent. - if s:Match(clnum, s:leading_operator_regex) - return indent(s:GetMSL(clnum)) + sw - endif - - " 3.3. Work on the previous line. {{{2 - " ------------------------------- - - " Find a non-blank, non-multi-line string line above the current line. - let lnum = s:PrevNonBlankNonString(clnum - 1) - - " If the line is empty and inside a string, use the previous line. - if line =~ '^\s*$' && lnum != prevnonblank(clnum - 1) - return indent(prevnonblank(clnum)) - endif - - " At the start of the file use zero indent. - if lnum == 0 - return 0 - endif - - " Set up variables for the previous line. - let line = getline(lnum) - let ind = indent(lnum) - - if g:ruby_indent_access_modifier_style == 'indent' - " If the previous line was a private/protected keyword, add a - " level of indent. - if s:Match(lnum, s:indent_access_modifier_regex) - return indent(lnum) + sw - endif - elseif g:ruby_indent_access_modifier_style == 'outdent' - " If the previous line was a private/protected/public keyword, add - " a level of indent, since the keyword has been out-dented. - if s:Match(lnum, s:access_modifier_regex) - return indent(lnum) + sw - endif - endif - - if s:Match(lnum, s:continuable_regex) && s:Match(lnum, s:continuation_regex) - return indent(s:GetMSL(lnum)) + sw + sw - endif - - " If the previous line ended with a block opening, add a level of indent. - if s:Match(lnum, s:block_regex) - let msl = s:GetMSL(lnum) - - if g:ruby_indent_block_style == 'do' - " don't align to the msl, align to the "do" - let ind = indent(lnum) + sw - elseif getline(msl) =~ '=\s*\(#.*\)\=$' - " in the case of assignment to the msl, align to the starting line, - " not to the msl - let ind = indent(lnum) + sw - else - let ind = indent(msl) + sw - endif - return ind - endif - - " If the previous line started with a leading operator, use its MSL's level - " of indent - if s:Match(lnum, s:leading_operator_regex) - return indent(s:GetMSL(lnum)) - endif - - " If the previous line ended with the "*" of a splat, add a level of indent - if line =~ s:splat_regex - return indent(lnum) + sw - endif - - " If the previous line contained unclosed opening brackets and we are still - " in them, find the rightmost one and add indent depending on the bracket - " type. - " - " If it contained hanging closing brackets, find the rightmost one, find its - " match and indent according to that. - if line =~ '[[({]' || line =~ '[])}]\s*\%(#.*\)\=$' - let [opening, closing] = s:ExtraBrackets(lnum) - - if opening.pos != -1 - if opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 - if col('.') + 1 == col('$') - return ind + sw - else - return virtcol('.') - endif - else - let nonspace = matchend(line, '\S', opening.pos + 1) - 1 - return nonspace > 0 ? nonspace : ind + sw - endif - elseif closing.pos != -1 - call cursor(lnum, closing.pos + 1) - normal! % - - if s:Match(line('.'), s:ruby_indent_keywords) - return indent('.') + sw - else - return indent(s:GetMSL(line('.'))) - endif - else - call cursor(clnum, vcol) - end - endif - - " If the previous line ended with an "end", match that "end"s beginning's - " indent. - let col = s:Match(lnum, '\%(^\|[^.:@$]\)\<end\>\s*\%(#.*\)\=$') - if col > 0 - call cursor(lnum, col) - if searchpair(s:end_start_regex, '', s:end_end_regex, 'bW', - \ s:end_skip_expr) > 0 - let n = line('.') - let ind = indent('.') - let msl = s:GetMSL(n) - if msl != n - let ind = indent(msl) - end - return ind - endif - end - - let col = s:Match(lnum, s:ruby_indent_keywords) - if col > 0 - call cursor(lnum, col) - let ind = virtcol('.') - 1 + sw - " TODO: make this better (we need to count them) (or, if a searchpair - " fails, we know that something is lacking an end and thus we indent a - " level - if s:Match(lnum, s:end_end_regex) - let ind = indent('.') - endif - return ind - endif - - " 3.4. Work on the MSL line. {{{2 - " -------------------------- - - " Set up variables to use and search for MSL to the previous line. - let p_lnum = lnum - let lnum = s:GetMSL(lnum) - - " If the previous line wasn't a MSL. - if p_lnum != lnum - " If previous line ends bracket and begins non-bracket continuation decrease indent by 1. - if s:Match(p_lnum, s:bracket_switch_continuation_regex) - return ind - 1 - " If previous line is a continuation return its indent. - " TODO: the || s:IsInString() thing worries me a bit. - elseif s:Match(p_lnum, s:non_bracket_continuation_regex) || s:IsInString(p_lnum,strlen(line)) - return ind - endif - endif - - " Set up more variables, now that we know we wasn't continuation bound. - let line = getline(lnum) - let msl_ind = indent(lnum) - - " If the MSL line had an indenting keyword in it, add a level of indent. - " TODO: this does not take into account contrived things such as - " module Foo; class Bar; end - if s:Match(lnum, s:ruby_indent_keywords) - let ind = msl_ind + sw - if s:Match(lnum, s:end_end_regex) - let ind = ind - sw - endif - return ind - endif - - " If the previous line ended with [*+/.,-=], but wasn't a block ending or a - " closing bracket, indent one extra level. - if s:Match(lnum, s:non_bracket_continuation_regex) && !s:Match(lnum, '^\s*\([\])}]\|end\)') - if lnum == p_lnum - let ind = msl_ind + sw - else - let ind = msl_ind - endif - return ind - endif - - " }}}2 - - return ind -endfunction - " }}}1 let &cpo = s:cpo_save diff --git a/indent/typescript.vim b/indent/typescript.vim index ed2e6c04..6dead67a 100644 --- a/indent/typescript.vim +++ b/indent/typescript.vim @@ -2,504 +2,362 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'typescript') == " Vim indent file " Language: Typescript -" Acknowledgement: Based off of vim-ruby maintained by Nikolai Weibull http://vim-ruby.rubyforge.org - -" 0. Initialization {{{1 -" ================= +" Acknowledgement: Almost direct copy from https://github.com/pangloss/vim-javascript " Only load this indent file when no other was loaded. -if exists("b:did_indent") +if exists('b:did_indent') || get(g:, 'typescript_indent_disable', 0) finish endif let b:did_indent = 1 -setlocal nosmartindent - " Now, set up our indentation expression and keys that trigger it. setlocal indentexpr=GetTypescriptIndent() -setlocal formatexpr=Fixedgq(v:lnum,v:count) -setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e +setlocal autoindent nolisp nosmartindent +setlocal indentkeys+=0],0) + +let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys<' " Only define the function once. -if exists("*GetTypescriptIndent") +if exists('*GetTypescriptIndent') finish endif let s:cpo_save = &cpo set cpo&vim -" 1. Variables {{{1 -" ============ +" Get shiftwidth value +if exists('*shiftwidth') + function s:sw() + return shiftwidth() + endfunction +else + function s:sw() + return &sw + endfunction +endif -let s:ts_keywords = '^\s*\(break\|case\|catch\|continue\|debugger\|default\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)' +" searchpair() wrapper +if has('reltime') + function s:GetPair(start,end,flags,skip,time,...) + return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 2000,0] + a:000),a:time) + endfunction +else + function s:GetPair(start,end,flags,skip,...) + return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 1000,get(a:000,1)])) + endfunction +endif " Regex of syntax group names that are or delimit string or are comments. -let s:syng_strcom = 'string\|regex\|comment\c' - -" Regex of syntax group names that are strings. -let s:syng_string = 'regex\c' - -" Regex of syntax group names that are strings or documentation. -let s:syng_multiline = 'comment\c' - -" Regex of syntax group names that are line comment. -let s:syng_linecom = 'linecomment\c' - +let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template\%(braces\)\@!' +let s:syng_str = 'string\|template\|special' +let s:syng_com = 'comment\|doc' " Expression used to check whether we should skip a match with searchpair(). -let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" - -let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' - -" Regex that defines continuation lines, not including (, {, or [. -let s:continuation_regex = '\%([\\*+/.:]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\|[^=]=[^=].*,\)' . s:line_term - -" Regex that defines continuation lines. -" TODO: this needs to deal with if ...: and so on -let s:msl_regex = s:continuation_regex - -let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term - -" Regex that defines blocks. -let s:block_regex = '\%([{[]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term - -let s:var_stmt = '^\s*var' - -let s:comma_first = '^\s*,' -let s:comma_last = ',\s*$' +let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" -let s:ternary = '^\s\+[?|:]' -let s:ternary_q = '^\s\+?' - -" 2. Auxiliary Functions {{{1 -" ====================== - -" Check if the character at lnum:col is inside a string, comment, or is ascii. -function s:IsInStringOrComment(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom +function s:skip_func() + if !s:free || search('\m`\|\${\|\*\/','nW',s:looksyn) + let s:free = !eval(s:skip_expr) + let s:looksyn = line('.') + return !s:free + endif + let s:looksyn = line('.') + return getline('.') =~ '\%<'.col('.').'c\/.\{-}\/\|\%>'.col('.').'c[''"]\|\\$' && + \ eval(s:skip_expr) endfunction -" Check if the character at lnum:col is inside a string. -function s:IsInString(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string +function s:alternatePair(stop) + let pos = getpos('.')[1:2] + while search('\m[][(){}]','bW',a:stop) + if !s:skip_func() + let idx = stridx('])}',s:looking_at()) + if idx + 1 + if s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop) <= 0 + break + endif + else + return + endif + endif + endwhile + call call('cursor',pos) endfunction -" Check if the character at lnum:col is inside a multi-line comment. -function s:IsInMultilineComment(lnum, col) - return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline +function s:save_pos(f,...) + let l:pos = getpos('.')[1:2] + let ret = call(a:f,a:000) + call call('cursor',l:pos) + return ret endfunction -" Check if the character at lnum:col is a line comment. -function s:IsLineComment(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_linecom +function s:syn_at(l,c) + return synIDattr(synID(a:l,a:c,0),'name') endfunction -" Find line above 'lnum' that isn't empty, in a comment, or in a string. -function s:PrevNonBlankNonString(lnum) - let in_block = 0 - let lnum = prevnonblank(a:lnum) - while lnum > 0 - " Go in and out of blocks comments as necessary. - " If the line isn't empty (with opt. comment) or in a string, end search. - let line = getline(lnum) - if line =~ '/\*' - if in_block - let in_block = 0 - else - break - endif - elseif !in_block && line =~ '\*/' - let in_block = 1 - elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) - break - endif - let lnum = prevnonblank(lnum - 1) - endwhile - return lnum +function s:looking_at() + return getline('.')[col('.')-1] endfunction -" Find line above 'lnum' that started the continuation 'lnum' may be part of. -function s:GetMSL(lnum, in_one_line_scope) - " Start on the line we're at and use its indent. - let msl = a:lnum - let lnum = s:PrevNonBlankNonString(a:lnum - 1) - while lnum > 0 - " If we have a continuation line, or we're in a string, use line as MSL. - " Otherwise, terminate search as we have found our MSL already. - let line = getline(lnum) - let col = match(line, s:msl_regex) + 1 - if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) - let msl = lnum - else - " Don't use lines that are part of a one line scope as msl unless the - " flag in_one_line_scope is set to 1 - " - if a:in_one_line_scope - break - end - let msl_one_line = s:Match(lnum, s:one_line_scope_regex) - if msl_one_line == 0 - break - endif - endif - let lnum = s:PrevNonBlankNonString(lnum - 1) - endwhile - return msl +function s:token() + return s:looking_at() =~ '\k' ? expand('<cword>') : s:looking_at() endfunction -function s:RemoveTrailingComments(content) - let single = '\/\/\(.*\)\s*$' - let multi = '\/\*\(.*\)\*\/\s*$' - return substitute(substitute(a:content, single, '', ''), multi, '', '') +function s:previous_token() + let l:n = line('.') + if (s:looking_at() !~ '\k' || search('\m\<','cbW')) && search('\m\S','bW') + if (getline('.')[col('.')-2:col('.')-1] == '*/' || line('.') != l:n && + \ getline('.') =~ '\%<'.col('.').'c\/\/') && s:syn_at(line('.'),col('.')) =~? s:syng_com + while search('\m\/\ze[/*]','cbW') + if !search('\m\S','bW') + break + elseif s:syn_at(line('.'),col('.')) !~? s:syng_com + return s:token() + endif + endwhile + else + return s:token() + endif + endif + return '' endfunction -" Find if the string is inside var statement (but not the first string) -function s:InMultiVarStatement(lnum) - let lnum = s:PrevNonBlankNonString(a:lnum - 1) - -" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') - - " loop through previous expressions to find a var statement - while lnum > 0 - let line = getline(lnum) - - " if the line is a ts keyword - if (line =~ s:ts_keywords) - " check if the line is a var stmt - " if the line has a comma first or comma last then we can assume that we - " are in a multiple var statement - if (line =~ s:var_stmt) - return lnum - endif - - " other ts keywords, not a var - return 0 - endif +function s:others(p) + return "((line2byte(line('.')) + col('.')) <= ".(line2byte(a:p[0]) + a:p[1]).") || ".s:skip_expr +endfunction - let lnum = s:PrevNonBlankNonString(lnum - 1) - endwhile +function s:tern_skip(p) + return s:GetPair('{','}','nbW',s:others(a:p),200,a:p[0]) > 0 +endfunction - " beginning of program, not a var - return 0 +function s:tern_col(p) + return s:GetPair('?',':\@<!::\@!','nbW',s:others(a:p) + \ .' || s:tern_skip('.string(a:p).')',200,a:p[0]) > 0 endfunction -" Find line above with beginning of the var statement or returns 0 if it's not -" this statement -function s:GetVarIndent(lnum) - let lvar = s:InMultiVarStatement(a:lnum) - let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) - - if lvar - let line = s:RemoveTrailingComments(getline(prev_lnum)) - - " if the previous line doesn't end in a comma, return to regular indent - if (line !~ s:comma_last) - return indent(prev_lnum) - &sw - else - return indent(lvar) + &sw - endif +function s:label_col() + let pos = getpos('.')[1:2] + let [s:looksyn,s:free] = pos + call s:alternatePair(0) + if s:save_pos('s:IsBlock') + let poss = getpos('.')[1:2] + return call('cursor',pos) || !s:tern_col(poss) + elseif s:looking_at() == ':' + return !s:tern_col([0,0]) endif +endfunction - return -1 +" configurable regexes that define continuation lines, not including (, {, or [. +let s:opfirst = '^' . get(g:,'typescript_opfirst', + \ '\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)') +let s:continuation = get(g:,'typescript_continuation', + \ '\%([-+<>=,.~!?/*^%|&:]\|\<\%(typeof\|delete\|void\|in\|instanceof\)\)') . '$' + +function s:continues(ln,con) + return !cursor(a:ln, match(' '.a:con,s:continuation)) && + \ eval( (['s:syn_at(line("."),col(".")) !~? "regex"'] + + \ repeat(['getline(".")[col(".")-2] != tr(s:looking_at(),">","=")'],3) + + \ repeat(['s:previous_token() != "."'],5) + [1])[ + \ index(split('/ > - + typeof in instanceof void delete'),s:token())]) endfunction +" get the line of code stripped of comments and move cursor to the last +" non-comment char. +function s:Trim(ln) + call cursor(a:ln+1,1) + call s:previous_token() + return strpart(getline('.'),0,col('.')) +endfunction -" Check if line 'lnum' has more opening brackets than closing ones. -function s:LineHasOpeningBrackets(lnum) - let open_0 = 0 - let open_2 = 0 - let open_4 = 0 - let line = getline(a:lnum) - let pos = match(line, '[][(){}]', 0) - while pos != -1 - if !s:IsInStringOrComment(a:lnum, pos + 1) - let idx = stridx('(){}[]', line[pos]) - if idx % 2 == 0 - let open_{idx} = open_{idx} + 1 - else - let open_{idx - 1} = open_{idx - 1} - 1 - endif - endif - let pos = match(line, '[][(){}]', pos + 1) +" Find line above 'lnum' that isn't empty or in a comment +function s:PrevCodeLine(lnum) + let l:n = prevnonblank(a:lnum) + while l:n + if getline(l:n) =~ '^\s*\/[/*]' + if (stridx(getline(l:n),'`') > 0 || getline(l:n-1)[-1:] == '\') && + \ s:syn_at(l:n,1) =~? s:syng_str + return l:n + endif + let l:n = prevnonblank(l:n-1) + elseif getline(l:n) =~ '\([/*]\)\1\@![/*]' && s:syn_at(l:n,1) =~? s:syng_com + let l:n = s:save_pos('eval', + \ 'cursor('.l:n.',1) + search(''\m\/\*'',"bW")') + else + return l:n + endif endwhile - return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) endfunction -function s:Match(lnum, regex) - let col = match(getline(a:lnum), a:regex) + 1 - return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +" Check if line 'lnum' has a balanced amount of parentheses. +function s:Balanced(lnum) + let l:open = 0 + let l:line = getline(a:lnum) + let pos = match(l:line, '[][(){}]', 0) + while pos != -1 + if s:syn_at(a:lnum,pos + 1) !~? s:syng_strcom + let l:open += match(' ' . l:line[pos],'[[({]') + if l:open < 0 + return + endif + endif + let pos = match(l:line, '[][(){}]', pos + 1) + endwhile + return !l:open endfunction -function s:IndentWithContinuation(lnum, ind, width) - " Set up variables to use and search for MSL to the previous line. - let p_lnum = a:lnum - let lnum = s:GetMSL(a:lnum, 1) - let line = getline(lnum) - - " If the previous line wasn't a MSL and is continuation return its indent. - " TODO: the || s:IsInString() thing worries me a bit. - if p_lnum != lnum - if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line)) - return a:ind - endif - endif - - " Set up more variables now that we know we aren't continuation bound. - let msl_ind = indent(lnum) - - " If the previous line ended with [*+/.-=], start a continuation that - " indents an extra level. - if s:Match(lnum, s:continuation_regex) - if lnum == p_lnum - return msl_ind + a:width - else - return msl_ind - endif +function s:OneScope(lnum) + let pline = s:Trim(a:lnum) + let kw = 'else do' + if pline[-1:] == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0 + call s:previous_token() + let kw = 'for if let while with' + if index(split('await each'),s:token()) + 1 + call s:previous_token() + let kw = 'for' + endif endif - - return a:ind + return pline[-2:] == '=>' || index(split(kw),s:token()) + 1 && + \ s:save_pos('s:previous_token') != '.' endfunction -function s:InOneLineScope(lnum) - let msl = s:GetMSL(a:lnum, 1) - if msl > 0 && s:Match(msl, s:one_line_scope_regex) - return msl - endif - return 0 +" returns braceless levels started by 'i' and above lines * &sw. 'num' is the +" lineNr which encloses the entire context, 'cont' if whether line 'i' + 1 is +" a continued expression, which could have started in a braceless context +function s:iscontOne(i,num,cont) + let [l:i, l:num, bL] = [a:i, a:num + !a:num, 0] + let pind = a:num ? indent(l:num) + s:W : 0 + let ind = indent(l:i) + (a:cont ? 0 : s:W) + while l:i >= l:num && (ind > pind || l:i == l:num) + if indent(l:i) < ind && s:OneScope(l:i) + let bL += s:W + let l:i = line('.') + elseif !a:cont || bL || ind < indent(a:i) + break + endif + let ind = min([ind, indent(l:i)]) + let l:i = s:PrevCodeLine(l:i - 1) + endwhile + return bL endfunction -function s:ExitingOneLineScope(lnum) - let msl = s:GetMSL(a:lnum, 1) - if msl > 0 - " if the current line is in a one line scope .. - if s:Match(msl, s:one_line_scope_regex) - return 0 - else - let prev_msl = s:GetMSL(msl - 1, 1) - if s:Match(prev_msl, s:one_line_scope_regex) - return prev_msl - endif - endif +" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader +function s:IsBlock() + if s:looking_at() == '{' + let l:n = line('.') + let char = s:previous_token() + if match(s:stack,'xml\|jsx') + 1 && s:syn_at(line('.'),col('.')-1) =~? 'xml\|jsx' + return char != '{' + elseif char =~ '\k' + return index(split('return const let import export yield default delete var await void typeof throw case new in instanceof') + \ ,char) < (line('.') != l:n) || s:previous_token() == '.' + elseif char == '>' + return getline('.')[col('.')-2] == '=' || s:syn_at(line('.'),col('.')) =~? '^jsflow' + elseif char == ':' + return getline('.')[col('.')-2] != ':' && s:label_col() + elseif char == '/' + return s:syn_at(line('.'),col('.')) =~? 'regex' + endif + return char !~ '[=~!<*,?^%|&([]' && + \ (char !~ '[-+]' || l:n != line('.') && getline('.')[col('.')-2] == char) endif - return 0 endfunction -" 3. GetTypescriptIndent Function {{{1 -" ========================= - function GetTypescriptIndent() - " 3.1. Setup {{{2 - " ---------- - - " Set up variables for restoring position in file. Could use v:lnum here. - let vcol = col('.') - - " 3.2. Work on the current line {{{2 - " ----------------------------- - - let ind = -1 + let b:js_cache = get(b:,'js_cache',[0,0,0]) " Get the current line. - let line = getline(v:lnum) - " previous nonblank line number - let prevline = prevnonblank(v:lnum - 1) - - " If we got a closing bracket on an empty line, find its match and indent - " according to it. For parentheses we indent to its column - 1, for the - " others we indent to the containing line's MSL's level. Return -1 if fail. - let col = matchend(line, '^\s*[],})]') - if col > 0 && !s:IsInStringOrComment(v:lnum, col) - call cursor(v:lnum, col) - - let lvar = s:InMultiVarStatement(v:lnum) - if lvar - let prevline_contents = s:RemoveTrailingComments(getline(prevline)) - - " check for comma first - if (line[col - 1] =~ ',') - " if the previous line ends in comma or semicolon don't indent - if (prevline_contents =~ '[;,]\s*$') - return indent(s:GetMSL(line('.'), 0)) - " get previous line indent, if it's comma first return prevline indent - elseif (prevline_contents =~ s:comma_first) - return indent(prevline) - " otherwise we indent 1 level - else - return indent(lvar) + &sw - endif - endif - endif - - - let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) - if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 - if line[col-1]==')' && col('.') != col('$') - 1 - let ind = virtcol('.')-1 - else - let ind = indent(s:GetMSL(line('.'), 0)) - endif - endif - return ind + call cursor(v:lnum,1) + let l:line = getline('.') + " use synstack as it validates syn state and works in an empty line + let s:stack = synstack(v:lnum,1) + let syns = synIDattr(get(s:stack,-1),'name') + + " start with strings,comments,etc. + if syns =~? s:syng_com + if l:line =~ '^\s*\*' + return cindent(v:lnum) + elseif l:line !~ '^\s*\/[/*]' + return -1 + endif + elseif syns =~? s:syng_str && l:line !~ '^[''"]' + if b:js_cache[0] == v:lnum - 1 && s:Balanced(v:lnum-1) + let b:js_cache[0] = v:lnum + endif + return -1 endif - - " If the line is comma first, dedent 1 level - if (getline(prevline) =~ s:comma_first) - return indent(prevline) - &sw + let l:lnum = s:PrevCodeLine(v:lnum - 1) + if !l:lnum + return endif - if (line =~ s:ternary) - if (getline(prevline) =~ s:ternary_q) - return indent(prevline) - else - return indent(prevline) + &sw - endif + let l:line = substitute(l:line,'^\s*','','') + if l:line[:1] == '/*' + let l:line = substitute(l:line,'^\%(\/\*.\{-}\*\/\s*\)*','','') endif - - " If we are in a multi-line comment, cindent does the right thing. - if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) - return cindent(v:lnum) + if l:line =~ '^\/[/*]' + let l:line = '' endif - " Check for multiple var assignments -" let var_indent = s:GetVarIndent(v:lnum) -" if var_indent >= 0 -" return var_indent -" endif - - " 3.3. Work on the previous line. {{{2 - " ------------------------------- - - " If the line is empty and the previous nonblank line was a multi-line - " comment, use that comment's indent. Deduct one char to account for the - " space in ' */'. - if line =~ '^\s*$' && s:IsInMultilineComment(prevline, 1) - return indent(prevline) - 1 - endif - - " Find a non-blank, non-multi-line string line above the current line. - let lnum = s:PrevNonBlankNonString(v:lnum - 1) - - " If the line is empty and inside a string, use the previous line. - if line =~ '^\s*$' && lnum != prevline - return indent(prevnonblank(v:lnum)) - endif - - " At the start of the file use zero indent. - if lnum == 0 - return 0 - endif - - " Set up variables for current line. - let line = getline(lnum) - let ind = indent(lnum) - - " If the previous line ended with a block opening, add a level of indent. - if s:Match(lnum, s:block_regex) - return indent(s:GetMSL(lnum, 0)) + &sw + " the containing paren, bracket, or curly. Many hacks for performance + let idx = index([']',')','}'],l:line[0]) + if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum && + \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum)) + call call('cursor',b:js_cache[1:]) + else + let [s:looksyn, s:free, top] = [v:lnum - 1, 1, (!indent(l:lnum) && + \ s:syn_at(l:lnum,1) !~? s:syng_str) * l:lnum] + if idx + 1 + call s:GetPair(['\[','(','{'][idx],'])}'[idx],'bW','s:skip_func()',2000,top) + elseif getline(v:lnum) !~ '^\S' && syns =~? 'block' + call s:GetPair('{','}','bW','s:skip_func()',2000,top) + else + call s:alternatePair(top) + endif endif - " If the previous line contained an opening bracket, and we are still in it, - " add indent depending on the bracket type. - if line =~ '[[({]' - let counts = s:LineHasOpeningBrackets(lnum) - if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 - if col('.') + 1 == col('$') - return ind + &sw - else - return virtcol('.') - endif - elseif counts[1] == '1' || counts[2] == '1' - return ind + &sw - else - call cursor(v:lnum, vcol) - end + let b:js_cache = [v:lnum] + (line('.') == v:lnum ? [0,0] : getpos('.')[1:2]) + let num = b:js_cache[1] + + let [s:W, isOp, bL, switch_offset] = [s:sw(),0,0,0] + if !num || s:IsBlock() + let ilnum = line('.') + let pline = s:save_pos('s:Trim',l:lnum) + if num && s:looking_at() == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0 + let num = ilnum == num ? line('.') : num + if idx < 0 && s:previous_token() ==# 'switch' && s:previous_token() != '.' + if &cino !~ ':' + let switch_offset = s:W + else + let cinc = matchlist(&cino,'.*:\zs\(-\)\=\(\d*\)\(\.\d\+\)\=\(s\)\=\C') + let switch_offset = max([cinc[0] is '' ? 0 : (cinc[1].1) * + \ ((strlen(cinc[2].cinc[3]) ? str2nr(cinc[2].str2nr(cinc[3][1])) : 10) * + \ (cinc[4] is '' ? 1 : s:W)) / 10, -indent(num)]) + endif + if pline[-1:] != '.' && l:line =~# '^\%(default\|case\)\>' + return indent(num) + switch_offset + endif + endif + endif + if idx < 0 && pline !~ '[{;]$' + if pline =~# ':\@<!:$' + call cursor(l:lnum,strlen(pline)) + let isOp = s:tern_col(b:js_cache[1:2]) * s:W + else + let isOp = (l:line =~# s:opfirst || s:continues(l:lnum,pline)) * s:W + endif + let bL = s:iscontOne(l:lnum,b:js_cache[1],isOp) + let bL -= (bL && l:line[0] == '{') * s:W + endif endif - " 3.4. Work on the MSL line. {{{2 - " -------------------------- - - let ind_con = ind - let ind = s:IndentWithContinuation(lnum, ind_con, &sw) - - " }}}2 - " - " - let ols = s:InOneLineScope(lnum) - if ols > 0 - let ind = ind + &sw - else - let ols = s:ExitingOneLineScope(lnum) - while ols > 0 && ind > 0 - let ind = ind - &sw - let ols = s:InOneLineScope(ols - 1) - endwhile + " main return + if idx + 1 || l:line[:1] == '|}' + return indent(num) + elseif num + return indent(num) + s:W + switch_offset + bL + isOp endif - - return ind + return bL + isOp endfunction -" }}}1 - let &cpo = s:cpo_save unlet s:cpo_save -function! Fixedgq(lnum, count) - let l:tw = &tw ? &tw : 80 - - let l:count = a:count - let l:first_char = indent(a:lnum) + 1 - - if mode() == 'i' " gq was not pressed, but tw was set - return 1 - endif - - " This gq is only meant to do code with strings, not comments - if s:IsLineComment(a:lnum, l:first_char) || s:IsInMultilineComment(a:lnum, l:first_char) - return 1 - endif - - if len(getline(a:lnum)) < l:tw && l:count == 1 " No need for gq - return 1 - endif - - " Put all the lines on one line and do normal spliting after that - if l:count > 1 - while l:count > 1 - let l:count -= 1 - normal J - endwhile - endif - - let l:winview = winsaveview() - - call cursor(a:lnum, l:tw + 1) - let orig_breakpoint = searchpairpos(' ', '', '\.', 'bcW', '', a:lnum) - call cursor(a:lnum, l:tw + 1) - let breakpoint = searchpairpos(' ', '', '\.', 'bcW', s:skip_expr, a:lnum) - - " No need for special treatment, normal gq handles edgecases better - if breakpoint[1] == orig_breakpoint[1] - call winrestview(l:winview) - return 1 - endif - - " Try breaking after string - if breakpoint[1] <= indent(a:lnum) - call cursor(a:lnum, l:tw + 1) - let breakpoint = searchpairpos('\.', '', ' ', 'cW', s:skip_expr, a:lnum) - endif - - - if breakpoint[1] != 0 - call feedkeys("r\<CR>") - else - let l:count = l:count - 1 - endif - - " run gq on new lines - if l:count == 1 - call feedkeys("gqq") - endif - - return 0 -endfunction endif diff --git a/syntax/blade.vim b/syntax/blade.vim index 4c04db75..7ae2786a 100644 --- a/syntax/blade.vim +++ b/syntax/blade.vim @@ -32,13 +32,13 @@ syn region bladeEcho matchgroup=bladeDelimiter start="{!!" end="!!}" con syn region bladeComment matchgroup=bladeDelimiter start="{{--" end="--}}" contains=bladeTodo containedin=ALLBUT,@bladeExempt keepend syn keyword bladeKeyword @if @elseif @foreach @forelse @for @while @can @cannot @elsecan @elsecannot @include - \ @includeIf @each @inject @extends @section @stack @push @unless @yield @parent @hasSection @break @continue - \ @unset @lang @choice @component @slot + \ @includeIf @each @inject @extends @section @stack @push @unless @yield @parent @hasSection @break @continue + \ @unset @lang @choice @component @slot @prepend \ nextgroup=bladePhpParenBlock skipwhite containedin=ALLBUT,@bladeExempt -syn keyword bladeKeyword @else @endif @endunless @endfor @endforeach @empty @endforelse @endwhile @endcan +syn keyword bladeKeyword @else @endif @endunless @endfor @endforeach @empty @endforelse @endwhile @endcan \ @endcannot @stop @append @endsection @endpush @show @overwrite @verbatim @endverbatim @endcomponent - \ @endslot + \ @endslot @endprepend \ containedin=ALLBUT,@bladeExempt if exists('g:blade_custom_directives') @@ -49,7 +49,7 @@ if exists('g:blade_custom_directives_pairs') exe "syn keyword bladeKeyword @" . join(values(g:blade_custom_directives_pairs), ' @') . " containedin=ALLBUT,@bladeExempt" endif -syn region bladePhpRegion matchgroup=bladeKeyword start="\<@php\>\%(\s*(\)\@!" end="\<@endphp\>" contains=@bladePhp containedin=ALLBUT,@bladeExempt keepend +syn region bladePhpRegion matchgroup=bladeKeyword start="\<@php\>\s*(\@!" end="\<@endphp\>" contains=@bladePhp containedin=ALLBUT,@bladeExempt keepend syn match bladeKeyword "@php\ze\s*(" nextgroup=bladePhpParenBlock skipwhite containedin=ALLBUT,@bladeExempt syn region bladePhpParenBlock matchgroup=bladeDelimiter start="\s*(" end=")" contains=@bladePhp,bladePhpParenBlock skipwhite contained diff --git a/syntax/coffee.vim b/syntax/coffee.vim index 589b8534..f11a7c50 100644 --- a/syntax/coffee.vim +++ b/syntax/coffee.vim @@ -34,7 +34,7 @@ hi def link coffeeConditional Conditional syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display hi def link coffeeException Exception -syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\)\>/ +syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\|await\)\>/ \ display " The `own` keyword is only a keyword after `for`. syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat diff --git a/syntax/erlang.vim b/syntax/erlang.vim index 57b0a6a6..c01c0b2f 100644 --- a/syntax/erlang.vim +++ b/syntax/erlang.vim @@ -4,9 +4,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'erlang') == -1 " Language: Erlang (http://www.erlang.org) " Maintainer: Csaba Hoch <csaba.hoch@gmail.com> " Contributor: Adam Rutkowski <hq@mtod.org> -" Last Update: 2013-Nov-23 +" Last Update: 2017-Mar-05 " License: Vim license -" URL: https://github.com/hcs42/vim-erlang +" URL: https://github.com/vim-erlang/vim-erlang-runtime " Acknowledgements: This script was originally created by Kresimir Marzic [1]. " The script was then revamped by Csaba Hoch [2]. During the revamp, the new @@ -31,11 +31,8 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'erlang') == -1 " " syn keyword erlangAttribute myattr1 myattr2 contained -" For version 5.x: Clear all syntax items -" For version 6.x: Quit when a syntax file was already loaded -if version < 600 - syntax clear -elseif exists("b:current_syntax") +" quit when a syntax file was already loaded +if exists("b:current_syntax") finish endif @@ -45,9 +42,7 @@ set cpo&vim " Case sensitive syn case match -if version >= 600 - setlocal iskeyword+=$,@-@ -endif +setlocal iskeyword+=$,@-@ " Comments syn match erlangComment '%.*$' contains=erlangCommentAnnotation,erlangTodo @@ -88,6 +83,7 @@ syn match erlangMacro '??\=[[:alnum:]_@]\+' syn match erlangMacro '\%(-define(\)\@<=[[:alnum:]_@]\+' syn match erlangMap '#' syn match erlangRecord '#\s*\l[[:alnum:]_@]*' +syn region erlangQuotedRecord start=/#\s*'/ end=/'/ contains=erlangQuotedAtomModifier " Shebang (this line has to be after the ErlangMap) syn match erlangShebang '^#!.*' @@ -153,118 +149,109 @@ let b:erlang_syntax_synced = 1 let s:old_style = (exists("g:erlang_old_style_highlight") && \g:erlang_old_style_highlight == 1) -" For version 5.7 and earlier: only when not done already -" For version 5.8 and later: only when an item doesn't have highlighting yet -if version >= 508 || !exists("did_erlang_inits") - if version < 508 - let did_erlang_inits = 1 - command -nargs=+ HiLink hi link <args> - else - command -nargs=+ HiLink hi def link <args> - endif - - " Comments - HiLink erlangComment Comment - HiLink erlangCommentAnnotation Special - HiLink erlangTodo Todo - HiLink erlangShebang Comment - - " Numbers - HiLink erlangNumberInteger Number - HiLink erlangNumberFloat Float - - " Strings, atoms, characters - HiLink erlangString String - - if s:old_style - HiLink erlangQuotedAtom Type - else - HiLink erlangQuotedAtom String - endif - - HiLink erlangStringModifier Special - HiLink erlangQuotedAtomModifier Special - HiLink erlangModifier Special - - " Operators, separators - HiLink erlangOperator Operator - HiLink erlangRightArrow Operator - if s:old_style - HiLink erlangBracket Normal - HiLink erlangPipe Normal - else - HiLink erlangBracket Delimiter - HiLink erlangPipe Delimiter - endif - - " Atoms, functions, variables, macros - if s:old_style - HiLink erlangAtom Normal - HiLink erlangLocalFuncCall Normal - HiLink erlangLocalFuncRef Normal - HiLink erlangGlobalFuncCall Function - HiLink erlangGlobalFuncRef Function - HiLink erlangVariable Normal - HiLink erlangMacro Normal - HiLink erlangRecord Normal - HiLink erlangMap Normal - else - HiLink erlangAtom String - HiLink erlangLocalFuncCall Normal - HiLink erlangLocalFuncRef Normal - HiLink erlangGlobalFuncCall Normal - HiLink erlangGlobalFuncRef Normal - HiLink erlangVariable Identifier - HiLink erlangMacro Macro - HiLink erlangRecord Structure - HiLink erlangMap Structure - endif - - " Bitstrings - if !s:old_style - HiLink erlangBitType Type - endif - - " Constants and Directives - if s:old_style - HiLink erlangAttribute Type - HiLink erlangMacroDef Type - HiLink erlangUnknownAttribute Normal - HiLink erlangInclude Type - HiLink erlangRecordDef Type - HiLink erlangDefine Type - HiLink erlangPreCondit Type - HiLink erlangType Type - else - HiLink erlangAttribute Keyword - HiLink erlangMacroDef Macro - HiLink erlangUnknownAttribute Normal - HiLink erlangInclude Include - HiLink erlangRecordDef Keyword - HiLink erlangDefine Define - HiLink erlangPreCondit PreCondit - HiLink erlangType Type - endif - - " Keywords - HiLink erlangKeyword Keyword - - " Build-in-functions (BIFs) - HiLink erlangBIF Function - - if s:old_style - HiLink erlangBoolean Statement - HiLink erlangExtra Statement - HiLink erlangSignal Statement - else - HiLink erlangBoolean Boolean - HiLink erlangExtra Statement - HiLink erlangSignal Statement - endif - - delcommand HiLink + +" Comments +hi def link erlangComment Comment +hi def link erlangCommentAnnotation Special +hi def link erlangTodo Todo +hi def link erlangShebang Comment + +" Numbers +hi def link erlangNumberInteger Number +hi def link erlangNumberFloat Float + +" Strings, atoms, characters +hi def link erlangString String + +if s:old_style +hi def link erlangQuotedAtom Type +else +hi def link erlangQuotedAtom String +endif + +hi def link erlangStringModifier Special +hi def link erlangQuotedAtomModifier Special +hi def link erlangModifier Special + +" Operators, separators +hi def link erlangOperator Operator +hi def link erlangRightArrow Operator +if s:old_style +hi def link erlangBracket Normal +hi def link erlangPipe Normal +else +hi def link erlangBracket Delimiter +hi def link erlangPipe Delimiter +endif + +" Atoms, functions, variables, macros +if s:old_style +hi def link erlangAtom Normal +hi def link erlangLocalFuncCall Normal +hi def link erlangLocalFuncRef Normal +hi def link erlangGlobalFuncCall Function +hi def link erlangGlobalFuncRef Function +hi def link erlangVariable Normal +hi def link erlangMacro Normal +hi def link erlangRecord Normal +hi def link erlangQuotedRecord Normal +hi def link erlangMap Normal +else +hi def link erlangAtom String +hi def link erlangLocalFuncCall Normal +hi def link erlangLocalFuncRef Normal +hi def link erlangGlobalFuncCall Normal +hi def link erlangGlobalFuncRef Normal +hi def link erlangVariable Identifier +hi def link erlangMacro Macro +hi def link erlangRecord Structure +hi def link erlangQuotedRecord Structure +hi def link erlangMap Structure endif +" Bitstrings +if !s:old_style +hi def link erlangBitType Type +endif + +" Constants and Directives +if s:old_style +hi def link erlangAttribute Type +hi def link erlangMacroDef Type +hi def link erlangUnknownAttribute Normal +hi def link erlangInclude Type +hi def link erlangRecordDef Type +hi def link erlangDefine Type +hi def link erlangPreCondit Type +hi def link erlangType Type +else +hi def link erlangAttribute Keyword +hi def link erlangMacroDef Macro +hi def link erlangUnknownAttribute Normal +hi def link erlangInclude Include +hi def link erlangRecordDef Keyword +hi def link erlangDefine Define +hi def link erlangPreCondit PreCondit +hi def link erlangType Type +endif + +" Keywords +hi def link erlangKeyword Keyword + +" Build-in-functions (BIFs) +hi def link erlangBIF Function + +if s:old_style +hi def link erlangBoolean Statement +hi def link erlangExtra Statement +hi def link erlangSignal Statement +else +hi def link erlangBoolean Boolean +hi def link erlangExtra Statement +hi def link erlangSignal Statement +endif + + let b:current_syntax = "erlang" let &cpo = s:cpo_save diff --git a/syntax/haskell.vim b/syntax/haskell.vim index bc86fbe7..e301742b 100644 --- a/syntax/haskell.vim +++ b/syntax/haskell.vim @@ -24,14 +24,14 @@ endif syn spell notoplevel syn match haskellRecordField contained containedin=haskellBlock - \ "[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\(\s*::\|\n\s\+::\)" + \ "[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\_s\+::\s" \ contains= \ haskellIdentifier, \ haskellOperators, \ haskellSeparator, \ haskellParens syn match haskellTypeSig - \ "^\s*\(where\s\+\|let\s\+\|default\s\+\)\?[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\(\s*::\|\n\s\+::\)" + \ "^\s*\(where\s\+\|let\s\+\|default\s\+\)\?[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\_s\+::\s" \ contains= \ haskellWhere, \ haskellLet, @@ -47,7 +47,7 @@ syn match haskellDecl "\<\(type\|data\)\>\s\+\(\<family\>\)\?" syn keyword haskellDefault default syn keyword haskellImportKeywords import qualified safe as hiding contained syn keyword haskellForeignKeywords foreign export import ccall safe unsafe interruptible capi prim contained -syn region haskellForeignImport start="\<foreign\>" end="::" keepend +syn region haskellForeignImport start="\<foreign\>" end="\_s\+::\s" keepend \ contains= \ haskellString, \ haskellOperators, diff --git a/syntax/html.vim b/syntax/html.vim index da9117dc..3f58cf02 100644 --- a/syntax/html.vim +++ b/syntax/html.vim @@ -2,8 +2,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 " Vim syntax file " Language: HTML (version 5.1) -" SVG (SVG 1.1 (Second Edition) ) -" Last Change: 2016 Jan 20 +" SVG (SVG 1.1 Second Edition) +" MathML (MathML 3.0 Second Edition) +" Last Change: 2017 Mar 07 " License: Public domain " (but let me know if you like :) ) " @@ -18,6 +19,15 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 " Modified: htdebeer <H.T.de.Beer@gmail.com> " Changes: add common SVG elements and attributes for inline SVG +" Patch 7.4.1142 +if has("patch-7.4-1142") + if has("win32") + syn iskeyword @,48-57,_,128-167,224-235,- + else + syn iskeyword @,48-57,_,192-255,- + endif +endif + " HTML 5 tags syn keyword htmlTagName contained article aside audio canvas command syn keyword htmlTagName contained datalist details dialog embed figcaption figure footer @@ -90,7 +100,7 @@ syn keyword htmlArg contained xml:lang xml:space xml:base xmlns syn keyword htmlArg contained onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload syn keyword htmlArg contained onmessage onoffline ononline onpopstate onredo onresize onstorage onundo onunload " <video>, <audio>, <source>, <track> -syn keyword htmlArg contained autoplay preload controls loop poster media kind charset srclang track +syn keyword htmlArg contained autoplay preload controls loop poster media kind charset srclang track playsinline " <form>, <input>, <button> syn keyword htmlArg contained form autocomplete autofocus list min max step syn keyword htmlArg contained formaction autofocus formenctype formmethod formtarget formnovalidate @@ -102,7 +112,7 @@ syn keyword htmlArg contained async " <content> syn keyword htmlArg contained select " <iframe> -syn keyword htmlArg contained seamless srcdoc sandbox allowfullscreen +syn keyword htmlArg contained seamless srcdoc sandbox allowfullscreen allowusermedia allowpaymentrequest " <picture> syn keyword htmlArg contained srcset sizes " <a> @@ -117,11 +127,11 @@ syn keyword htmlArg contained integrity crossorigin " Custom Data Attributes " http://w3c.github.io/html/single-page.html#embedding-custom-non-visible-data-with-the-data-attributes -syn match htmlArg "\<\(data\-\([a-z_][a-z0-9_.\-]*\)\+\)\{1,}\>" contained +syn match htmlArg "\<data[-.0-9_a-z]*-[-.0-9_a-z]*\>" contained " Vendor Extension Attributes " http://w3c.github.io/html/single-page.html#conformance-requirements-extensibility -syn match htmlArg "\<\(x\-\([a-z_][a-z0-9_.\-]*\)\+\)\{2,}\>" contained +syn match htmlArg "\<x[-.0-9_a-z]*-[-.0-9_a-z]*\>" contained " Microdata " http://dev.w3.org/html5/md/ diff --git a/syntax/html/aria.vim b/syntax/html/aria.vim index 28cf34c0..3bb377ea 100644 --- a/syntax/html/aria.vim +++ b/syntax/html/aria.vim @@ -1,16 +1,15 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 " Vim syntax file -" Language: WAI-ARIA +" Language: WAI-ARIA " Maintainer: othree <othree@gmail.com> -" URL: http://github.com/othree/html5-syntax.vim -" Last Change: 2014-05-02 +" URL: https://github.com/othree/html5.vim +" Last Change: 2017-03-07 " License: MIT -" Changes: Add match rules -" update to Draft 16 September 2010 +" Changes: update to Candidate Recommendation 27 October 2016 " WAI-ARIA States and Properties -" http://www.w3.org/TR/wai-aria/states_and_properties +" https://www.w3.org/TR/wai-aria-1.1/#states_and_properties syn keyword htmlArg contained role " Global States and Properties @@ -18,6 +17,8 @@ syn keyword htmlArg contained aria-atomic aria-busy aria-controls aria-describe syn keyword htmlArg contained aria-disabled aria-dropeffect aria-flowto aria-grabbed syn keyword htmlArg contained aria-haspopup aria-hidden aria-invalid aria-label syn keyword htmlArg contained aria-labelledby aria-live aria-owns aria-relevant +" 1.1 +syn keyword htmlArg contained aria-current aria-details aria-keyshortcuts aria-roledescription " Widget Attributes syn keyword htmlArg contained aria-autocomplete aria-checked aria-disabled aria-expanded @@ -25,6 +26,8 @@ syn keyword htmlArg contained aria-haspopup aria-hidden aria-invalid aria-label syn keyword htmlArg contained aria-level aria-multiline aria-multiselectable aria-orientation syn keyword htmlArg contained aria-pressed aria-readonly aria-required aria-selected syn keyword htmlArg contained aria-sort aria-valuemax aria-valuemin aria-valuenow aria-valuetext +" 1.1 +syn keyword htmlArg contained aria-errormessage aria-hasgroup aria-modal aria-placeholder " Live Region Attributes syn keyword htmlArg contained aria-atomic aria-busy aria-live aria-relevant @@ -35,6 +38,9 @@ syn keyword htmlArg contained aria-dropeffect aria-grabbed " Relationship Attributes syn keyword htmlArg contained aria-activedescendant aria-controls aria-describedby aria-flowto syn keyword htmlArg contained aria-labelledby aria-owns aria-posinset aria-setsize +" 1.1 +syn keyword htmlArg contained aria-colcount aria-colindex aria-colspan +syn keyword htmlArg contained aria-rowcount aria-rowindex aria-rowspan " Use match: https://github.com/othree/html5.vim/issues/39 @@ -44,6 +50,8 @@ syn match htmlArg contained "\<aria-\%(\|atomic\|busy\|controls\|describedby\ syn match htmlArg contained "\<aria-\%(\|disabled\|dropeffect\|flowto\|grabbed\)\>" syn match htmlArg contained "\<aria-\%(\|haspopup\|hidden\|invalid\|label\)\>" syn match htmlArg contained "\<aria-\%(\|labelledby\|live\|owns\|relevant\)\>" +" 1.1 +syn match htmlArg contained "\<aria-\%(\|current\|details\|keyshortcuts\|roledescription\)\>" " Widget Attributes syn match htmlArg contained "\<aria-\%(\|autocomplete\|checked\|disabled\|expanded\)\>" @@ -51,6 +59,8 @@ syn match htmlArg contained "\<aria-\%(\|haspopup\|hidden\|invalid\|label\)\> syn match htmlArg contained "\<aria-\%(\|level\|multiline\|multiselectable\|orientation\)\>" syn match htmlArg contained "\<aria-\%(\|pressed\|readonly\|required\|selected\)\>" syn match htmlArg contained "\<aria-\%(\|sort\|valuemax\|valuemin\|valuenow\|valuetext\)\>" +" 1.1 +syn match htmlArg contained "\<aria-\%(\|errormessage\|hasgroup\|modal\|placeholder\)\>" " Live Region Attributes syn match htmlArg contained "\<aria-\%(\|atomic\|busy\|live\|relevant\)\>" @@ -61,6 +71,9 @@ syn match htmlArg contained "\<aria-\%(\|dropeffect\|grabbed\)\>" " Relationship Attributes syn match htmlArg contained "\<aria-\%(\|activedescendant\|controls\|describedby\|flowto\)\>" syn match htmlArg contained "\<aria-\%(\|labelledby\|owns\|posinset\|setsize\)\>" +" 1.1 +syn match htmlArg contained "\<aria-\%(\|colcount\|colindex\|colspan\)\>" +syn match htmlArg contained "\<aria-\%(\|rowcount\|rowindex\|rowspan\)\>" endif diff --git a/syntax/html/electron.vim b/syntax/html/electron.vim new file mode 100644 index 00000000..35e60dd4 --- /dev/null +++ b/syntax/html/electron.vim @@ -0,0 +1,19 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'html5') == -1 + +" Vim syntax file +" Language: Electron +" Maintainer: othree <othree@gmail.com> +" URL: https://github.com/othree/html5.vim +" Last Change: 2017-03-15 +" License: MIT + +" <webview> https://electron.atom.io/docs/api/webview-tag/ +syn keyword htmlTagName contained webview + +syn keyword htmlArg contained autosize nodeintegration plugins preload httpreferrer +syn keyword htmlArg contained useragent disablewebsecurity partition allowpopups +syn keyword htmlArg contained webpreferences blinkfeatures disableblinkfeatures +syn keyword htmlArg contained guestinstance disableguestresize + + +endif diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 5742bdc9..76d1267f 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -27,7 +27,8 @@ syntax sync fromstart syntax case match syntax match jsNoise /[:,\;]\{1}/ -syntax match jsNoise /[\.]\{1}/ skipwhite skipempty nextgroup=jsObjectProp +syntax match jsNoise /[\.]\{1}/ skipwhite skipempty nextgroup=jsObjectProp,jsFuncCall +syntax match jsObjectProp contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>/ syntax match jsFuncCall /\k\+\%(\s*(\)\@=/ syntax match jsParensError /[)}\]]/ @@ -54,7 +55,7 @@ syntax match jsModuleComma contained /,/ skipwhite skipempty nextgroup= " Strings, Templates, Numbers syntax region jsString start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@Spell extend syntax region jsString start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell extend -syntax region jsTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=jsTemplateExpression,jsSpecial extend +syntax region jsTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=jsTemplateExpression,jsSpecial,@Spell extend syntax match jsTaggedTemplate /\k\+\%(`\)\@=/ nextgroup=jsTemplateString syntax match jsNumber /\<\d\+\%([eE][+-]\=\d\+\)\=\>\|\<0[bB][01]\+\>\|\<0[oO]\o\+\>\|\<0[xX]\x\+\>/ syntax keyword jsNumber Infinity @@ -71,9 +72,9 @@ syntax match jsRegexpOr contained "\v\<@!\|" syntax match jsRegexpMod contained "\v\(@<=\?[:=!>]" syntax region jsRegexpGroup contained start="\\\@<!(" skip="\\.\|\[\(\\.\|[^]]\)*\]" end="\\\@<!)" contains=jsRegexpCharClass,@jsRegexpSpecial keepend if v:version > 703 || v:version == 603 && has("patch1088") - syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimy]\{,4}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend + syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimyu]\{,5}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend else - syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimy]\{,4}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend + syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimyu]\{,5}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend endif syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod @@ -105,7 +106,7 @@ syntax match jsBlockLabelKey contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\%(\s*\%(; syntax keyword jsStatement contained with yield debugger syntax keyword jsStatement contained break continue skipwhite skipempty nextgroup=jsBlockLabelKey syntax keyword jsConditional if skipwhite skipempty nextgroup=jsParenIfElse -syntax keyword jsConditional else skipwhite skipempty nextgroup=jsCommentMisc,jsIfElseBlock +syntax keyword jsConditional else skipwhite skipempty nextgroup=jsCommentIfElse,jsIfElseBlock syntax keyword jsConditional switch skipwhite skipempty nextgroup=jsParenSwitch syntax keyword jsRepeat while for skipwhite skipempty nextgroup=jsParenRepeat,jsForAwait syntax keyword jsDo do skipwhite skipempty nextgroup=jsRepeatBlock @@ -143,9 +144,9 @@ syntax keyword jsHtmlEvents onblur onclick oncontextmenu ondblclick onfocus " Code blocks syntax region jsBracket matchgroup=jsBrackets start=/\[/ end=/\]/ contains=@jsExpression,jsSpreadExpression extend fold syntax region jsParen matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll extend fold -syntax region jsParenDecorator contained matchgroup=jsParensDecorator start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc extend fold -syntax region jsParenIfElse contained matchgroup=jsParensIfElse start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsIfElseBlock extend fold -syntax region jsParenRepeat contained matchgroup=jsParensRepeat start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsRepeatBlock extend fold +syntax region jsParenDecorator contained matchgroup=jsParensDecorator start=/(/ end=/)/ contains=@jsAll extend fold +syntax region jsParenIfElse contained matchgroup=jsParensIfElse start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentIfElse,jsIfElseBlock extend fold +syntax region jsParenRepeat contained matchgroup=jsParensRepeat start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentRepeat,jsRepeatBlock extend fold syntax region jsParenSwitch contained matchgroup=jsParensSwitch start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsSwitchBlock extend fold syntax region jsParenCatch contained matchgroup=jsParensCatch start=/(/ end=/)/ skipwhite skipempty nextgroup=jsTryCatchBlock extend fold syntax region jsFuncArgs contained matchgroup=jsFuncParens start=/(/ end=/)/ contains=jsFuncArgCommas,jsComment,jsFuncArgExpression,jsDestructuringBlock,jsDestructuringArray,jsRestExpression,jsFlowArgumentDef skipwhite skipempty nextgroup=jsCommentFunction,jsFuncBlock,jsFlowReturn extend fold @@ -217,13 +218,14 @@ syntax region jsCommentFunction contained start=/\/\// end=/$/ contains=j syntax region jsCommentFunction contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturn fold extend keepend syntax region jsCommentClass contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsClassBlock,jsFlowClassGroup extend keepend syntax region jsCommentClass contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsClassBlock,jsFlowClassGroup fold extend keepend -syntax region jsCommentMisc contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsBlock extend keepend -syntax region jsCommentMisc contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsBlock fold extend keepend +syntax region jsCommentIfElse contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsIfElseBlock extend keepend +syntax region jsCommentIfElse contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsIfElseBlock fold extend keepend +syntax region jsCommentRepeat contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsRepeatBlock extend keepend +syntax region jsCommentRepeat contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsRepeatBlock fold extend keepend " Decorators syntax match jsDecorator /^\s*@/ nextgroup=jsDecoratorFunction syntax match jsDecoratorFunction contained /[a-zA-Z_][a-zA-Z0-9_.]*/ nextgroup=jsParenDecorator -syntax match jsObjectProp contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>/ if exists("javascript_plugin_jsdoc") runtime extras/jsdoc.vim @@ -364,7 +366,8 @@ if version >= 508 || !exists("did_javascript_syn_inits") HiLink jsCommentFunction jsComment HiLink jsCommentClass jsComment - HiLink jsCommentMisc jsComment + HiLink jsCommentIfElse jsComment + HiLink jsCommentRepeat jsComment HiLink jsDomErrNo Constant HiLink jsDomNodeConsts Constant diff --git a/syntax/javascript/html5.vim b/syntax/javascript/html5.vim index f9462dee..f950d6c5 100644 --- a/syntax/javascript/html5.vim +++ b/syntax/javascript/html5.vim @@ -44,4 +44,7 @@ syn keyword javascriptDomElemAttrs videoWidth videoHeight poster " drag and drop syn keyword javascriptDomElemAttrs onDragStart onDragEnd onDragEnter onDragLeave onDragOver onDrag onDrop draggable dropzone +" <checkbox> +syn keyword javascriptDomElemAttrs indeterminate + endif diff --git a/syntax/layout/nginx.vim b/syntax/layout/nginx.vim index daff064a..677ff8ca 100644 --- a/syntax/layout/nginx.vim +++ b/syntax/layout/nginx.vim @@ -7,25 +7,20 @@ if exists("b:current_syntax") finish end +" Patch 7.4.1142 if has("patch-7.4-1142") if has("win32") syn iskeyword @,48-57,_,128-167,224-235,.,/,: else syn iskeyword @,48-57,_,192-255,.,/,: endif -else - setlocal iskeyword+=. - setlocal iskeyword+=/ - setlocal iskeyword+=: endif syn match ngxVariable '\$\(\w\+\|{\w\+}\)' syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained syn match ngxComment ' *#.*$' -syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxURI skipwhite -syn match ngxURI /\S\+/ contained contains=ngxVariableString skipwhite -syn match ngxLocationPath /[^ {]\+/ contained -syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString +syn match ngxLocationPath /\S\+/ contained +syn region ngxString start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString syn keyword ngxBoolean on syn keyword ngxBoolean off @@ -37,9 +32,9 @@ syn keyword ngxDirectiveBlock events syn keyword ngxDirectiveBlock server syn keyword ngxDirectiveBlock stream syn keyword ngxDirectiveBlock types -syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained nextgroup=ngxLocationPath,ngxString skipwhite +syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained nextgroup=ngxLocationPath,ngxString skipwhite skipempty syn match ngxLocationNamedLoc /@\w\+/ -syn keyword ngxDirectiveBlock location nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString skipwhite +syn keyword ngxDirectiveBlock location nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString skipwhite skipempty syn keyword ngxDirectiveBlock upstream syn keyword ngxDirectiveBlock charset_map syn keyword ngxDirectiveBlock limit_except @@ -52,7 +47,8 @@ syn keyword ngxDirectiveImportant include syn keyword ngxDirectiveImportant root syn keyword ngxDirectiveImportant server syn keyword ngxDirectiveImportant server_name -syn keyword ngxDirectiveImportant listen +syn keyword ngxDirectiveImportant listen contained +syn region ngxDirectiveImportantListen matchgroup=ngxDirectiveImportant start=+listen+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxListenOptions,ngxString syn keyword ngxDirectiveImportant internal syn keyword ngxDirectiveImportant proxy_pass syn keyword ngxDirectiveImportant memcached_pass @@ -61,19 +57,48 @@ syn keyword ngxDirectiveImportant scgi_pass syn keyword ngxDirectiveImportant uwsgi_pass syn keyword ngxDirectiveImportant try_files +syn keyword ngxListenOptions default_server contained +syn keyword ngxListenOptions ssl contained +syn keyword ngxListenOptions http2 contained +syn keyword ngxListenOptions spdy contained +syn keyword ngxListenOptions proxy_protocol contained +syn keyword ngxListenOptions setfib contained +syn keyword ngxListenOptions fastopen contained +syn keyword ngxListenOptions backlog contained +syn keyword ngxListenOptions rcvbuf contained +syn keyword ngxListenOptions sndbuf contained +syn keyword ngxListenOptions accept_filter contained +syn keyword ngxListenOptions deferred contained +syn keyword ngxListenOptions bind contained +syn keyword ngxListenOptions ipv6only contained +syn keyword ngxListenOptions reuseport contained +syn keyword ngxListenOptions so_keepalive contained +syn keyword ngxListenOptions keepidle contained + syn keyword ngxDirectiveControl break -syn keyword ngxDirectiveControl return -syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite +syn keyword ngxDirectiveControl return nextgroup=ngxStatusCode skipwhite skipempty +syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite skipempty syn keyword ngxDirectiveControl set -syn keyword ngxRewriteFlag last -syn keyword ngxRewriteFlag break -syn keyword ngxRewriteFlag redirect -syn keyword ngxRewriteFlag permanent +syn match ngxStatusCode /\d\d\d/ contained +syn match ngxStatusCodes /\d\d\d/ contained contains=ngxStatusCode nextgroup=ngxStatusCode skipwhite skipempty + +syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxRewritedURI skipwhite skipempty +syn region ngxRewriteURI start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString nextgroup=ngxRewritedURI skipwhite skipempty +syn match ngxRewritedURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxRewriteFlag skipwhite skipempty +syn region ngxRewritedURI start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString nextgroup=ngxRewriteFlag skipwhite skipempty + +syn keyword ngxRewriteFlag last contained +syn keyword ngxRewriteFlag break contained +syn keyword ngxRewriteFlag redirect contained +syn keyword ngxRewriteFlag permanent contained -syn keyword ngxDirectiveError error_page +syn keyword ngxDirectiveError error_page nextgroup=ngxErrorStatusCode skipwhite skipempty syn keyword ngxDirectiveError post_action +syn match ngxErrorStatusCode /\d\d\d/ contained contains=ngxStatusCode nextgroup=ngxErrorResponseCode skipwhite skipempty +syn match ngxErrorResponseCode /=\d\d\d/ contained contains=ngxStatusCode + syn keyword ngxDirectiveDeprecated connections syn keyword ngxDirectiveDeprecated imap syn keyword ngxDirectiveDeprecated limit_zone @@ -82,14 +107,6 @@ syn keyword ngxDirectiveDeprecated open_file_cache_retest syn keyword ngxDirectiveDeprecated optimize_server_names syn keyword ngxDirectiveDeprecated satisfy_any syn keyword ngxDirectiveDeprecated so_keepalive -syn keyword ngxDirectiveDeprecated spdy_chunk_size -syn keyword ngxDirectiveDeprecated spdy_headers_comp -syn keyword ngxDirectiveDeprecated spdy_keepalive_timeout -syn keyword ngxDirectiveDeprecated spdy_max_concurrent_streams -syn keyword ngxDirectiveDeprecated spdy_pool_size -syn keyword ngxDirectiveDeprecated spdy_recv_buffer_size -syn keyword ngxDirectiveDeprecated spdy_recv_timeout -syn keyword ngxDirectiveDeprecated spdy_streams_index_size syn keyword ngxDirective absolute_redirect syn keyword ngxDirective accept_mutex @@ -235,7 +252,6 @@ syn keyword ngxDirective hls_forward_args syn keyword ngxDirective hls_fragment syn keyword ngxDirective hls_mp4_buffer_size syn keyword ngxDirective hls_mp4_max_buffer_size -syn keyword ngxDirective http2 " Not a real directive syn keyword ngxDirective http2_chunk_size syn keyword ngxDirective http2_body_preread_size syn keyword ngxDirective http2_idle_timeout @@ -277,13 +293,13 @@ syn keyword ngxDirective least_conn syn keyword ngxDirective least_time syn keyword ngxDirective limit_conn syn keyword ngxDirective limit_conn_log_level -syn keyword ngxDirective limit_conn_status +syn keyword ngxDirective limit_conn_status nextgroup=ngxStatusCode skipwhite skipempty syn keyword ngxDirective limit_conn_zone syn keyword ngxDirective limit_rate syn keyword ngxDirective limit_rate_after syn keyword ngxDirective limit_req syn keyword ngxDirective limit_req_log_level -syn keyword ngxDirective limit_req_status +syn keyword ngxDirective limit_req_status nextgroup=ngxStatusCode skipwhite skipempty syn keyword ngxDirective limit_req_zone syn keyword ngxDirective lingering_close syn keyword ngxDirective lingering_time @@ -343,8 +359,8 @@ syn keyword ngxDirective postpone_gzipping syn keyword ngxDirective postpone_output syn keyword ngxDirective preread_buffer_size syn keyword ngxDirective preread_timeout -syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite -syn keyword ngxMailProtocol imap pop3 smtp +syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite skipempty +syn keyword ngxMailProtocol imap pop3 smtp contained syn keyword ngxDirective proxy syn keyword ngxDirective proxy_bind syn keyword ngxDirective proxy_buffer @@ -366,7 +382,7 @@ syn keyword ngxDirective proxy_cache_path syn keyword ngxDirective proxy_cache_purge syn keyword ngxDirective proxy_cache_revalidate syn keyword ngxDirective proxy_cache_use_stale -syn keyword ngxDirective proxy_cache_valid +syn keyword ngxDirective proxy_cache_valid nextgroup=ngxStatusCodes skipwhite skipempty syn keyword ngxDirective proxy_connect_timeout syn keyword ngxDirective proxy_cookie_domain syn keyword ngxDirective proxy_cookie_path @@ -406,7 +422,7 @@ syn keyword ngxDirective proxy_ssl_ciphers syn keyword ngxDirective proxy_ssl_crl syn keyword ngxDirective proxy_ssl_name syn keyword ngxDirective proxy_ssl_password_file -syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective proxy_ssl_server_name syn keyword ngxDirective proxy_ssl_session_reuse syn keyword ngxDirective proxy_ssl_trusted_certificate @@ -499,6 +515,14 @@ syn keyword ngxDirective smtp_capabilities syn keyword ngxDirective smtp_client_buffer syn keyword ngxDirective smtp_greeting_delay syn keyword ngxDirective source_charset +syn keyword ngxDirective spdy_chunk_size +syn keyword ngxDirective spdy_headers_comp +syn keyword ngxDirective spdy_keepalive_timeout +syn keyword ngxDirective spdy_max_concurrent_streams +syn keyword ngxDirective spdy_pool_size +syn keyword ngxDirective spdy_recv_buffer_size +syn keyword ngxDirective spdy_recv_timeout +syn keyword ngxDirective spdy_streams_index_size syn keyword ngxDirective ssi syn keyword ngxDirective ssi_ignore_recycled_buffers syn keyword ngxDirective ssi_last_modified @@ -520,8 +544,8 @@ syn keyword ngxDirective ssl_handshake_timeout syn keyword ngxDirective ssl_password_file syn keyword ngxDirective ssl_prefer_server_ciphers syn keyword ngxDirective ssl_preread -syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxSSLProtocol SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 +syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty +syn keyword ngxSSLProtocol SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 contained nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective ssl_session_cache syn keyword ngxDirective ssl_session_ticket_key syn keyword ngxDirective ssl_session_tickets @@ -612,7 +636,7 @@ syn keyword ngxDirective uwsgi_ssl_ciphers syn keyword ngxDirective uwsgi_ssl_crl syn keyword ngxDirective uwsgi_ssl_name syn keyword ngxDirective uwsgi_ssl_password_file -syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective uwsgi_ssl_server_name syn keyword ngxDirective uwsgi_ssl_session_reuse syn keyword ngxDirective uwsgi_ssl_trusted_certificate @@ -660,6 +684,7 @@ hi link ngxLocationPath String hi link ngxLocationNamedLoc Identifier hi link ngxBoolean Boolean +hi link ngxStatusCode Number hi link ngxRewriteFlag Boolean hi link ngxDirectiveBlock Statement hi link ngxDirectiveImportant Type @@ -669,6 +694,12 @@ hi link ngxDirectiveDeprecated Error hi link ngxDirective Identifier hi link ngxDirectiveThirdParty Special +hi link ngxListenOptions Keyword +hi link ngxMailProtocol Keyword +hi link ngxSSLProtocol Keyword + +hi link ngxThirdPartyKeyword keyword + let b:current_syntax = "nginx" diff --git a/syntax/litcoffee.vim b/syntax/litcoffee.vim new file mode 100644 index 00000000..555518fa --- /dev/null +++ b/syntax/litcoffee.vim @@ -0,0 +1,27 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'coffee-script') == -1 + +" Language: Literate CoffeeScript +" Maintainer: Michael Smith <michael@diglumi.com> +" URL: https://github.com/mintplant/vim-literate-coffeescript +" License: MIT + +if exists('b:current_syntax') && b:current_syntax == 'litcoffee' + finish +endif + +syn include @markdown syntax/markdown.vim +syn include @coffee syntax/coffee.vim + +" Partition the file into notCoffee and inlineCoffee. Each line will match +" exactly one of these regions. notCoffee matches with a zero-width +" look-behind. +syn region notCoffee start='^\%( \|\t\)\@<!' end='$' contains=@markdown +syn region inlineCoffee start='^ \|\t' end='$' contains=@coffee + +" We defined notCoffee as a region so we can highlight every element in it +" that doesn't have it's own explicit rule. +highlight default link notCoffee Comment + +let b:current_syntax = "litcoffee" + +endif diff --git a/syntax/markdown.vim b/syntax/markdown.vim index 0545156d..71d2264e 100644 --- a/syntax/markdown.vim +++ b/syntax/markdown.vim @@ -63,7 +63,7 @@ execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic start="\%(^\|\s\)\zs syn region mkdFootnotes matchgroup=mkdDelimiter start="\[^" end="\]" execute 'syn region mkdID matchgroup=mkdDelimiter start="\[" end="\]" contained oneline' . s:conceal execute 'syn region mkdURL matchgroup=mkdDelimiter start="(" end=")" contained oneline' . s:conceal -execute 'syn region mkdLink matchgroup=mkdDelimiter start="\\\@<!!\?\[" end="\n\{-,1}[^]]\{-}\zs\]\ze[[(]" contains=@mkdNonListItem,@Spell nextgroup=mkdURL,mkdID skipwhite oneline' . s:concealends +execute 'syn region mkdLink matchgroup=mkdDelimiter start="\\\@<!!\?\[\ze[^]\n]*\n\?[^]\n]*\][[(]" end="\]" contains=@mkdNonListItem,@Spell nextgroup=mkdURL,mkdID skipwhite' . s:concealends " Autolink without angle brackets. " mkd inline links: protocol optional user:pass@ sub/domain .com, .co.uk, etc optional port path/querystring/hash fragment @@ -77,7 +77,7 @@ syn region mkdInlineURL matchgroup=mkdDelimiter start="(\(https\?:\/\/\(\w\+\(: syn region mkdInlineURL matchgroup=mkdDelimiter start="\\\@<!<\ze[a-z][a-z0-9,.-]\{1,22}:\/\/[^> ]*>" end=">" " Link definitions: [id]: URL (Optional Title) -syn region mkdLinkDef matchgroup=mkdDelimiter start="^ \{,3}\zs\[" end="]:" oneline nextgroup=mkdLinkDefTarget skipwhite +syn region mkdLinkDef matchgroup=mkdDelimiter start="^ \{,3}\zs\[\^\@!" end="]:" oneline nextgroup=mkdLinkDefTarget skipwhite syn region mkdLinkDefTarget start="<\?\zs\S" excludenl end="\ze[>[:space:]\n]" contained nextgroup=mkdLinkTitle,mkdLinkDef skipwhite skipnl oneline syn region mkdLinkTitle matchgroup=mkdDelimiter start=+"+ end=+"+ contained syn region mkdLinkTitle matchgroup=mkdDelimiter start=+'+ end=+'+ contained diff --git a/syntax/modules/afcgi.vim b/syntax/modules/afcgi.vim index 32d7fd25..fdf85725 100644 --- a/syntax/modules/afcgi.vim +++ b/syntax/modules/afcgi.vim @@ -35,8 +35,8 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nginx') == -1 " syn keyword ngxDirectiveThirdParty fastcgi_store_access " syn keyword ngxDirectiveThirdParty fastcgi_temp_file_write_size " syn keyword ngxDirectiveThirdParty fastcgi_temp_path -syn keyword ngxDirectiveThirdParty fastcgi_upstream_fail_timeout -syn keyword ngxDirectiveThirdParty fastcgi_upstream_max_fails +syn keyword ngxDirectiveDeprecated fastcgi_upstream_fail_timeout +syn keyword ngxDirectiveDeprecated fastcgi_upstream_max_fails endif diff --git a/syntax/modules/geoip2.vim b/syntax/modules/geoip2.vim index c6d7822c..6a5189a8 100644 --- a/syntax/modules/geoip2.vim +++ b/syntax/modules/geoip2.vim @@ -2,7 +2,48 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nginx') == -1 " GeoIP 2 Module <https://github.com/leev/ngx_http_geoip2_module> " Creates variables with values from the maxmind geoip2 databases based on the client IP -syn keyword ngxDirectiveThirdParty geoip2 +syn keyword ngxDirectiveThirdParty geoip2 nextgroup=ngxThirdPartyGeoIP2Database skipwhite skipempty +syn match ngxThirdPartyGeoIP2Database /\S\+/ contained nextgroup=ngxThirdPartyGeoIP2Block skipwhite skipempty +syn region ngxThirdPartyGeoIP2Block start=/{/ end=/}/ contained contains=ngxThirdPartyGeoIP2Keyword,ngxVariable +syn keyword ngxThirdPartyGeoIP2Keyword de en es fr ja pt-BR ru zh-CN contained +syn match ngxThirdPartyGeoIP2Keyword /pt-BR|zh-CN/ contained +syn keyword ngxThirdPartyGeoIP2Keyword default source contained +" Common Keys +syn keyword ngxThirdPartyGeoIP2Keyword code confidence geoname_id names iso_code contained +" /Common Keys +syn keyword ngxThirdPartyGeoIP2Keyword city contained +syn keyword ngxThirdPartyGeoIP2Keyword continent contained +syn keyword ngxThirdPartyGeoIP2Keyword country contained +syn keyword ngxThirdPartyGeoIP2Keyword location contained +" Location Keys +syn keyword ngxThirdPartyGeoIP2Keyword accuracy_radius contained +syn keyword ngxThirdPartyGeoIP2Keyword average_income contained +syn keyword ngxThirdPartyGeoIP2Keyword latitude contained +syn keyword ngxThirdPartyGeoIP2Keyword longitude contained +syn keyword ngxThirdPartyGeoIP2Keyword metro_code contained +syn keyword ngxThirdPartyGeoIP2Keyword population_density contained +syn keyword ngxThirdPartyGeoIP2Keyword time_zone contained +syn keyword ngxThirdPartyGeoIP2Keyword postal contained +" /Location Keys +syn keyword ngxThirdPartyGeoIP2Keyword registered_country contained +syn keyword ngxThirdPartyGeoIP2Keyword represented_country contained +" Represented Country Keys +syn keyword ngxThirdPartyGeoIP2Keyword type contained +" /Represented Country Keys +syn keyword ngxThirdPartyGeoIP2Keyword subdivisions contained +syn keyword ngxThirdPartyGeoIP2Keyword traits contained +" Traits Keys +syn keyword ngxThirdPartyGeoIP2Keyword autonomous_system_number contained +syn keyword ngxThirdPartyGeoIP2Keyword autonomous_system_organization contained +syn keyword ngxThirdPartyGeoIP2Keyword domain contained +syn keyword ngxThirdPartyGeoIP2Keyword ip_address contained +syn keyword ngxThirdPartyGeoIP2Keyword is_anonymous_proxy contained +syn keyword ngxThirdPartyGeoIP2Keyword is_satellite_provider contained +syn keyword ngxThirdPartyGeoIP2Keyword isp contained +syn keyword ngxThirdPartyGeoIP2Keyword organization contained +syn keyword ngxThirdPartyGeoIP2Keyword user_type contained +" /Traits Keys +hi link ngxThirdPartyGeoIP2Keyword ngxThirdPartyKeyword endif diff --git a/syntax/nginx.vim b/syntax/nginx.vim index 5039a8c3..e20d49ef 100644 --- a/syntax/nginx.vim +++ b/syntax/nginx.vim @@ -7,25 +7,20 @@ if exists("b:current_syntax") finish end +" Patch 7.4.1142 if has("patch-7.4-1142") if has("win32") syn iskeyword @,48-57,_,128-167,224-235,.,/,: else syn iskeyword @,48-57,_,192-255,.,/,: endif -else - setlocal iskeyword+=. - setlocal iskeyword+=/ - setlocal iskeyword+=: endif syn match ngxVariable '\$\(\w\+\|{\w\+}\)' syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained syn match ngxComment ' *#.*$' -syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxURI skipwhite -syn match ngxURI /\S\+/ contained contains=ngxVariableString skipwhite -syn match ngxLocationPath /[^ {]\+/ contained -syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString +syn match ngxLocationPath /\S\+/ contained +syn region ngxString start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString syn keyword ngxBoolean on syn keyword ngxBoolean off @@ -37,9 +32,9 @@ syn keyword ngxDirectiveBlock events syn keyword ngxDirectiveBlock server syn keyword ngxDirectiveBlock stream syn keyword ngxDirectiveBlock types -syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained nextgroup=ngxLocationPath,ngxString skipwhite +syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained nextgroup=ngxLocationPath,ngxString skipwhite skipempty syn match ngxLocationNamedLoc /@\w\+/ -syn keyword ngxDirectiveBlock location nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString skipwhite +syn keyword ngxDirectiveBlock location nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString skipwhite skipempty syn keyword ngxDirectiveBlock upstream syn keyword ngxDirectiveBlock charset_map syn keyword ngxDirectiveBlock limit_except @@ -52,7 +47,8 @@ syn keyword ngxDirectiveImportant include syn keyword ngxDirectiveImportant root syn keyword ngxDirectiveImportant server syn keyword ngxDirectiveImportant server_name -syn keyword ngxDirectiveImportant listen +syn keyword ngxDirectiveImportant listen contained +syn region ngxDirectiveImportantListen matchgroup=ngxDirectiveImportant start=+listen+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxListenOptions,ngxString syn keyword ngxDirectiveImportant internal syn keyword ngxDirectiveImportant proxy_pass syn keyword ngxDirectiveImportant memcached_pass @@ -61,19 +57,48 @@ syn keyword ngxDirectiveImportant scgi_pass syn keyword ngxDirectiveImportant uwsgi_pass syn keyword ngxDirectiveImportant try_files +syn keyword ngxListenOptions default_server contained +syn keyword ngxListenOptions ssl contained +syn keyword ngxListenOptions http2 contained +syn keyword ngxListenOptions spdy contained +syn keyword ngxListenOptions proxy_protocol contained +syn keyword ngxListenOptions setfib contained +syn keyword ngxListenOptions fastopen contained +syn keyword ngxListenOptions backlog contained +syn keyword ngxListenOptions rcvbuf contained +syn keyword ngxListenOptions sndbuf contained +syn keyword ngxListenOptions accept_filter contained +syn keyword ngxListenOptions deferred contained +syn keyword ngxListenOptions bind contained +syn keyword ngxListenOptions ipv6only contained +syn keyword ngxListenOptions reuseport contained +syn keyword ngxListenOptions so_keepalive contained +syn keyword ngxListenOptions keepidle contained + syn keyword ngxDirectiveControl break -syn keyword ngxDirectiveControl return -syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite +syn keyword ngxDirectiveControl return nextgroup=ngxStatusCode skipwhite skipempty +syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite skipempty syn keyword ngxDirectiveControl set -syn keyword ngxRewriteFlag last -syn keyword ngxRewriteFlag break -syn keyword ngxRewriteFlag redirect -syn keyword ngxRewriteFlag permanent +syn match ngxStatusCode /\d\d\d/ contained +syn match ngxStatusCodes /\d\d\d/ contained contains=ngxStatusCode nextgroup=ngxStatusCode skipwhite skipempty + +syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxRewritedURI skipwhite skipempty +syn region ngxRewriteURI start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString nextgroup=ngxRewritedURI skipwhite skipempty +syn match ngxRewritedURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxRewriteFlag skipwhite skipempty +syn region ngxRewritedURI start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString nextgroup=ngxRewriteFlag skipwhite skipempty + +syn keyword ngxRewriteFlag last contained +syn keyword ngxRewriteFlag break contained +syn keyword ngxRewriteFlag redirect contained +syn keyword ngxRewriteFlag permanent contained -syn keyword ngxDirectiveError error_page +syn keyword ngxDirectiveError error_page nextgroup=ngxErrorStatusCode skipwhite skipempty syn keyword ngxDirectiveError post_action +syn match ngxErrorStatusCode /\d\d\d/ contained contains=ngxStatusCode nextgroup=ngxErrorResponseCode skipwhite skipempty +syn match ngxErrorResponseCode /=\d\d\d/ contained contains=ngxStatusCode + syn keyword ngxDirectiveDeprecated connections syn keyword ngxDirectiveDeprecated imap syn keyword ngxDirectiveDeprecated limit_zone @@ -82,14 +107,6 @@ syn keyword ngxDirectiveDeprecated open_file_cache_retest syn keyword ngxDirectiveDeprecated optimize_server_names syn keyword ngxDirectiveDeprecated satisfy_any syn keyword ngxDirectiveDeprecated so_keepalive -syn keyword ngxDirectiveDeprecated spdy_chunk_size -syn keyword ngxDirectiveDeprecated spdy_headers_comp -syn keyword ngxDirectiveDeprecated spdy_keepalive_timeout -syn keyword ngxDirectiveDeprecated spdy_max_concurrent_streams -syn keyword ngxDirectiveDeprecated spdy_pool_size -syn keyword ngxDirectiveDeprecated spdy_recv_buffer_size -syn keyword ngxDirectiveDeprecated spdy_recv_timeout -syn keyword ngxDirectiveDeprecated spdy_streams_index_size syn keyword ngxDirective absolute_redirect syn keyword ngxDirective accept_mutex @@ -235,7 +252,6 @@ syn keyword ngxDirective hls_forward_args syn keyword ngxDirective hls_fragment syn keyword ngxDirective hls_mp4_buffer_size syn keyword ngxDirective hls_mp4_max_buffer_size -syn keyword ngxDirective http2 " Not a real directive syn keyword ngxDirective http2_chunk_size syn keyword ngxDirective http2_body_preread_size syn keyword ngxDirective http2_idle_timeout @@ -277,13 +293,13 @@ syn keyword ngxDirective least_conn syn keyword ngxDirective least_time syn keyword ngxDirective limit_conn syn keyword ngxDirective limit_conn_log_level -syn keyword ngxDirective limit_conn_status +syn keyword ngxDirective limit_conn_status nextgroup=ngxStatusCode skipwhite skipempty syn keyword ngxDirective limit_conn_zone syn keyword ngxDirective limit_rate syn keyword ngxDirective limit_rate_after syn keyword ngxDirective limit_req syn keyword ngxDirective limit_req_log_level -syn keyword ngxDirective limit_req_status +syn keyword ngxDirective limit_req_status nextgroup=ngxStatusCode skipwhite skipempty syn keyword ngxDirective limit_req_zone syn keyword ngxDirective lingering_close syn keyword ngxDirective lingering_time @@ -343,8 +359,8 @@ syn keyword ngxDirective postpone_gzipping syn keyword ngxDirective postpone_output syn keyword ngxDirective preread_buffer_size syn keyword ngxDirective preread_timeout -syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite -syn keyword ngxMailProtocol imap pop3 smtp +syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite skipempty +syn keyword ngxMailProtocol imap pop3 smtp contained syn keyword ngxDirective proxy syn keyword ngxDirective proxy_bind syn keyword ngxDirective proxy_buffer @@ -366,7 +382,7 @@ syn keyword ngxDirective proxy_cache_path syn keyword ngxDirective proxy_cache_purge syn keyword ngxDirective proxy_cache_revalidate syn keyword ngxDirective proxy_cache_use_stale -syn keyword ngxDirective proxy_cache_valid +syn keyword ngxDirective proxy_cache_valid nextgroup=ngxStatusCodes skipwhite skipempty syn keyword ngxDirective proxy_connect_timeout syn keyword ngxDirective proxy_cookie_domain syn keyword ngxDirective proxy_cookie_path @@ -406,7 +422,7 @@ syn keyword ngxDirective proxy_ssl_ciphers syn keyword ngxDirective proxy_ssl_crl syn keyword ngxDirective proxy_ssl_name syn keyword ngxDirective proxy_ssl_password_file -syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective proxy_ssl_server_name syn keyword ngxDirective proxy_ssl_session_reuse syn keyword ngxDirective proxy_ssl_trusted_certificate @@ -499,6 +515,14 @@ syn keyword ngxDirective smtp_capabilities syn keyword ngxDirective smtp_client_buffer syn keyword ngxDirective smtp_greeting_delay syn keyword ngxDirective source_charset +syn keyword ngxDirective spdy_chunk_size +syn keyword ngxDirective spdy_headers_comp +syn keyword ngxDirective spdy_keepalive_timeout +syn keyword ngxDirective spdy_max_concurrent_streams +syn keyword ngxDirective spdy_pool_size +syn keyword ngxDirective spdy_recv_buffer_size +syn keyword ngxDirective spdy_recv_timeout +syn keyword ngxDirective spdy_streams_index_size syn keyword ngxDirective ssi syn keyword ngxDirective ssi_ignore_recycled_buffers syn keyword ngxDirective ssi_last_modified @@ -520,8 +544,8 @@ syn keyword ngxDirective ssl_handshake_timeout syn keyword ngxDirective ssl_password_file syn keyword ngxDirective ssl_prefer_server_ciphers syn keyword ngxDirective ssl_preread -syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxSSLProtocol SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 +syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty +syn keyword ngxSSLProtocol SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 contained nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective ssl_session_cache syn keyword ngxDirective ssl_session_ticket_key syn keyword ngxDirective ssl_session_tickets @@ -612,7 +636,7 @@ syn keyword ngxDirective uwsgi_ssl_ciphers syn keyword ngxDirective uwsgi_ssl_crl syn keyword ngxDirective uwsgi_ssl_name syn keyword ngxDirective uwsgi_ssl_password_file -syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite skipempty syn keyword ngxDirective uwsgi_ssl_server_name syn keyword ngxDirective uwsgi_ssl_session_reuse syn keyword ngxDirective uwsgi_ssl_trusted_certificate @@ -694,8 +718,8 @@ syn keyword ngxDirectiveDeprecated accesskey_signature " syn keyword ngxDirectiveThirdParty fastcgi_store_access " syn keyword ngxDirectiveThirdParty fastcgi_temp_file_write_size " syn keyword ngxDirectiveThirdParty fastcgi_temp_path -syn keyword ngxDirectiveThirdParty fastcgi_upstream_fail_timeout -syn keyword ngxDirectiveThirdParty fastcgi_upstream_max_fails +syn keyword ngxDirectiveDeprecated fastcgi_upstream_fail_timeout +syn keyword ngxDirectiveDeprecated fastcgi_upstream_max_fails " Akamai G2O Module <https://github.com/kaltura/nginx_mod_akamai_g2o> " Nginx Module for Authenticating Akamai G2O requests @@ -924,7 +948,48 @@ syn keyword ngxDirectiveDeprecated geoip_country_file " GeoIP 2 Module <https://github.com/leev/ngx_http_geoip2_module> " Creates variables with values from the maxmind geoip2 databases based on the client IP -syn keyword ngxDirectiveThirdParty geoip2 +syn keyword ngxDirectiveThirdParty geoip2 nextgroup=ngxThirdPartyGeoIP2Database skipwhite skipempty +syn match ngxThirdPartyGeoIP2Database /\S\+/ contained nextgroup=ngxThirdPartyGeoIP2Block skipwhite skipempty +syn region ngxThirdPartyGeoIP2Block start=/{/ end=/}/ contained contains=ngxThirdPartyGeoIP2Keyword,ngxVariable +syn keyword ngxThirdPartyGeoIP2Keyword de en es fr ja pt-BR ru zh-CN contained +syn match ngxThirdPartyGeoIP2Keyword /pt-BR|zh-CN/ contained +syn keyword ngxThirdPartyGeoIP2Keyword default source contained +" Common Keys +syn keyword ngxThirdPartyGeoIP2Keyword code confidence geoname_id names iso_code contained +" /Common Keys +syn keyword ngxThirdPartyGeoIP2Keyword city contained +syn keyword ngxThirdPartyGeoIP2Keyword continent contained +syn keyword ngxThirdPartyGeoIP2Keyword country contained +syn keyword ngxThirdPartyGeoIP2Keyword location contained +" Location Keys +syn keyword ngxThirdPartyGeoIP2Keyword accuracy_radius contained +syn keyword ngxThirdPartyGeoIP2Keyword average_income contained +syn keyword ngxThirdPartyGeoIP2Keyword latitude contained +syn keyword ngxThirdPartyGeoIP2Keyword longitude contained +syn keyword ngxThirdPartyGeoIP2Keyword metro_code contained +syn keyword ngxThirdPartyGeoIP2Keyword population_density contained +syn keyword ngxThirdPartyGeoIP2Keyword time_zone contained +syn keyword ngxThirdPartyGeoIP2Keyword postal contained +" /Location Keys +syn keyword ngxThirdPartyGeoIP2Keyword registered_country contained +syn keyword ngxThirdPartyGeoIP2Keyword represented_country contained +" Represented Country Keys +syn keyword ngxThirdPartyGeoIP2Keyword type contained +" /Represented Country Keys +syn keyword ngxThirdPartyGeoIP2Keyword subdivisions contained +syn keyword ngxThirdPartyGeoIP2Keyword traits contained +" Traits Keys +syn keyword ngxThirdPartyGeoIP2Keyword autonomous_system_number contained +syn keyword ngxThirdPartyGeoIP2Keyword autonomous_system_organization contained +syn keyword ngxThirdPartyGeoIP2Keyword domain contained +syn keyword ngxThirdPartyGeoIP2Keyword ip_address contained +syn keyword ngxThirdPartyGeoIP2Keyword is_anonymous_proxy contained +syn keyword ngxThirdPartyGeoIP2Keyword is_satellite_provider contained +syn keyword ngxThirdPartyGeoIP2Keyword isp contained +syn keyword ngxThirdPartyGeoIP2Keyword organization contained +syn keyword ngxThirdPartyGeoIP2Keyword user_type contained +" /Traits Keys +hi link ngxThirdPartyGeoIP2Keyword ngxThirdPartyKeyword " GridFS Module <https://github.com/mdirolf/nginx-gridfs> " Nginx module for serving files from MongoDB's GridFS @@ -2131,6 +2196,7 @@ hi link ngxLocationPath String hi link ngxLocationNamedLoc Identifier hi link ngxBoolean Boolean +hi link ngxStatusCode Number hi link ngxRewriteFlag Boolean hi link ngxDirectiveBlock Statement hi link ngxDirectiveImportant Type @@ -2140,6 +2206,12 @@ hi link ngxDirectiveDeprecated Error hi link ngxDirective Identifier hi link ngxDirectiveThirdParty Special +hi link ngxListenOptions Keyword +hi link ngxMailProtocol Keyword +hi link ngxSSLProtocol Keyword + +hi link ngxThirdPartyKeyword keyword + let b:current_syntax = "nginx" diff --git a/syntax/plantuml.vim b/syntax/plantuml.vim index e3527dd2..45308ee8 100644 --- a/syntax/plantuml.vim +++ b/syntax/plantuml.vim @@ -130,7 +130,7 @@ syntax keyword plantumlSkinparamKeyword ActorFontSize ActorFontStyle ActorStereo syntax keyword plantumlSkinparamKeyword ActorStereotypeFontSize ActorStereotypeFontStyle ArrowColor ArrowFontColor syntax keyword plantumlSkinparamKeyword ArrowFontName ArrowFontSize ArrowFontStyle AttributeFontColor AttributeFontName syntax keyword plantumlSkinparamKeyword AttributeFontSize AttributeFontStyle AttributeIconSize BarColor -syntax keyword plantumlSkinparamKeyword BorderColor CharacterFontColor CharacterFontName CharacterFontSize +syntax keyword plantumlSkinparamKeyword BorderColor BoxPadding CharacterFontColor CharacterFontName CharacterFontSize syntax keyword plantumlSkinparamKeyword CharacterFontStyle CharacterRadius Color DividerBackgroundColor syntax keyword plantumlSkinparamKeyword DividerFontColor DividerFontName DividerFontSize DividerFontStyle EndColor syntax keyword plantumlSkinparamKeyword FontColor FontName FontSize FontStyle GroupBackgroundColor GroupingFontColor @@ -139,7 +139,7 @@ syntax keyword plantumlSkinparamKeyword GroupingHeaderFontName GroupingHeaderFon syntax keyword plantumlSkinparamKeyword InterfaceBackgroundColor InterfaceBorderColor LifeLineBackgroundColor syntax keyword plantumlSkinparamKeyword LifeLineBorderColor ParticipantBackgroundColor ParticipantBorderColor syntax keyword plantumlSkinparamKeyword ParticipantFontColor ParticipantFontName ParticipantFontSize -syntax keyword plantumlSkinparamKeyword ParticipantFontStyle StartColor StereotypeFontColor +syntax keyword plantumlSkinparamKeyword ParticipantFontStyle ParticipantPadding StartColor StereotypeFontColor syntax keyword plantumlSkinparamKeyword StereotypeFontName StereotypeFontSize StereotypeFontStyle " Highlight diff --git a/syntax/pug.vim b/syntax/pug.vim index 85cfbcd8..03f62707 100644 --- a/syntax/pug.vim +++ b/syntax/pug.vim @@ -32,12 +32,12 @@ syn region pugJavascript matchgroup=pugJavascriptOutputChar start="[!&]\==\|\~" syn region pugJavascript matchgroup=pugJavascriptChar start="-" skip=",\s*$" end="$" contained contains=@htmlJavascript keepend syn cluster pugTop contains=pugBegin,pugComment,pugHtmlComment,pugJavascript syn match pugBegin "^\s*\%([<>]\|&[^=~ ]\)\@!" nextgroup=pugTag,pugClassChar,pugIdChar,pugPlainChar,pugJavascript,pugScriptConditional,pugScriptStatement,pugPipedText -syn match pugTag "+\?\w\+\%(:\w\+\)\=" contained contains=htmlTagName,htmlSpecialTagName nextgroup=@pugComponent +syn match pugTag "+\?[[:alnum:]_-]\+\%(:\w\+\)\=" contained contains=htmlTagName,htmlSpecialTagName nextgroup=@pugComponent syn cluster pugComponent contains=pugAttributes,pugIdChar,pugBlockExpansionChar,pugClassChar,pugPlainChar,pugJavascript,pugTagBlockChar,pugTagInlineText syntax keyword pugCommentTodo contained TODO FIXME XXX TBD -syn match pugComment '\(\s\+\|^\)\/\/.*$' contains=pugCommentTodo -syn region pugCommentBlock start="\z(\s\+\|^\)\/\/.*$" end="^\%(\z1\s\|\s*$\)\@!" contains=pugCommentTodo keepend -syn region pugHtmlConditionalComment start="<!--\%(.*\)>" end="<!\%(.*\)-->" contains=pugCommentTodo +syn match pugComment '\(\s\+\|^\)\/\/.*$' contains=pugCommentTodo,@Spell +syn region pugCommentBlock start="\z(\s\+\|^\)\/\/.*$" end="^\%(\z1\s\|\s*$\)\@!" contains=pugCommentTodo,@Spell keepend +syn region pugHtmlConditionalComment start="<!--\%(.*\)>" end="<!\%(.*\)-->" contains=pugCommentTodo,@Spell syn region pugAngular2 start="(" end=")" contains=htmlEvent syn region pugAttributes matchgroup=pugAttributesDelimiter start="(" end=")" contained contains=@htmlJavascript,pugHtmlArg,pugAngular2,htmlArg,htmlEvent,htmlCssDefinition nextgroup=@pugComponent syn match pugClassChar "\." containedin=htmlTagName nextgroup=pugClass @@ -54,10 +54,10 @@ syn keyword pugHtmlArg contained href title syn match pugPlainChar "\\" contained syn region pugInterpolation matchgroup=pugInterpolationDelimiter start="[#!]{" end="}" contains=@htmlJavascript syn match pugInterpolationEscape "\\\@<!\%(\\\\\)*\\\%(\\\ze#{\|#\ze{\)" -syn match pugTagInlineText "\s.*$" contained contains=pugInterpolation,pugTextInlinePug +syn match pugTagInlineText "\s.*$" contained contains=pugInterpolation,pugTextInlinePug,@Spell syn region pugPipedText matchgroup=pugPipeChar start="|" end="$" contained contains=pugInterpolation,pugTextInlinePug nextgroup=pugPipedText skipnl syn match pugTagBlockChar "\.$" contained nextgroup=pugTagBlockText,pugTagBlockEnd skipnl -syn region pugTagBlockText start="\%(\s*\)\S" end="\ze\n" contained contains=pugInterpolation,pugTextInlinePug nextgroup=pugTagBlockText,pugTagBlockEnd skipnl +syn region pugTagBlockText start="\%(\s*\)\S" end="\ze\n" contained contains=pugInterpolation,pugTextInlinePug,@Spell nextgroup=pugTagBlockText,pugTagBlockEnd skipnl syn region pugTagBlockEnd start="\s*\S" end="$" contained contains=pugInterpolation,pugTextInlinePug nextgroup=pugBegin skipnl syn region pugTextInlinePug matchgroup=pugInlineDelimiter start="#\[" end="]" contains=pugTag keepend diff --git a/syntax/swift.vim b/syntax/swift.vim index 009c5b45..cd5177b4 100644 --- a/syntax/swift.vim +++ b/syntax/swift.vim @@ -243,7 +243,7 @@ syntax keyword swiftPreprocessor syntax match swiftComment "\v\/\/.*$" \ contains=swiftTodos,swiftDocString,swiftMarker,@Spell oneline syntax region swiftComment start="/\*" end="\*/" - \ contains=swiftTodos,swiftDocString,swiftMarker,swiftComment,@Spell fold + \ contains=swiftTodos,swiftDocString,swiftMarker,@Spell fold " Set highlights diff --git a/syntax/terraform.vim b/syntax/terraform.vim index 0ae9e191..a06eeb9d 100644 --- a/syntax/terraform.vim +++ b/syntax/terraform.vim @@ -14,26 +14,39 @@ syn keyword terraValueBool true false on off yes no """ data syn keyword terraDataTypeBI + \ alicloud_images + \ alicloud_instance_types + \ alicloud_regions + \ alicloud_zones \ archive_file \ atlas_artifact \ aws_acm_certificate \ aws_alb \ aws_alb_listener \ aws_ami + \ aws_autoscaling_groups \ aws_availability_zone \ aws_availability_zones \ aws_billing_service_account \ aws_caller_identity + \ aws_canonical_user_id \ aws_cloudformation_stack + \ aws_db_instance \ aws_ebs_snapshot \ aws_ebs_volume + \ aws_ecs_cluster \ aws_ecs_container_definition + \ aws_ecs_task_definition \ aws_eip + \ aws_elb_hosted_zone_id \ aws_elb_service_account \ aws_iam_account_alias \ aws_iam_policy_document \ aws_iam_server_certificate + \ aws_instance \ aws_ip_ranges + \ aws_kms_secret + \ aws_partition \ aws_prefix_list \ aws_redshift_service_account \ aws_region @@ -43,17 +56,23 @@ syn keyword terraDataTypeBI \ aws_security_group \ aws_subnet \ aws_vpc + \ aws_vpc_endpoint \ aws_vpc_endpoint_service \ aws_vpc_peering_connection + \ aws_vpn_gateway \ azurerm_client_config \ consul_keys \ docker_registry_image \ external \ fastly_ip_ranges + \ google_compute_zones \ google_iam_policy \ newrelic_application + \ ns1_datasource \ null_data_source \ opsgenie_user + \ pagerduty_escalation_policy + \ pagerduty_schedule \ pagerduty_user \ pagerduty_vendor \ scaleway_bootscript @@ -65,6 +84,20 @@ syn keyword terraDataTypeBI """ resource syn keyword terraResourceTypeBI + \ alicloud_disk + \ alicloud_disk_attachment + \ alicloud_eip + \ alicloud_eip_association + \ alicloud_instance + \ alicloud_nat_gateway + \ alicloud_route_entry + \ alicloud_security_group + \ alicloud_security_group_rule + \ alicloud_slb + \ alicloud_slb_attachment + \ alicloud_subnet + \ alicloud_vpc + \ alicloud_vswitch \ arukas_container \ atlas_artifact \ aws_alb @@ -110,11 +143,16 @@ syn keyword terraResourceTypeBI \ aws_cloudwatch_log_stream \ aws_cloudwatch_log_subscription_filter \ aws_cloudwatch_metric_alarm + \ aws_codebuild_project \ aws_codecommit_repository \ aws_codecommit_trigger \ aws_codedeploy_app \ aws_codedeploy_deployment_config \ aws_codedeploy_deployment_group + \ aws_config_config_rule + \ aws_config_configuration_recorder + \ aws_config_configuration_recorder_status + \ aws_config_delivery_channel \ aws_customer_gateway \ aws_db_event_subscription \ aws_db_instance @@ -126,6 +164,11 @@ syn keyword terraResourceTypeBI \ aws_default_route_table \ aws_default_security_group \ aws_directory_service_directory + \ aws_dms_certificate + \ aws_dms_endpoint + \ aws_dms_replication_instance + \ aws_dms_replication_subnet_group + \ aws_dms_replication_task \ aws_dynamodb_table \ aws_ebs_snapshot \ aws_ebs_volume @@ -147,6 +190,7 @@ syn keyword terraResourceTypeBI \ aws_elasticache_security_group \ aws_elasticache_subnet_group \ aws_elasticsearch_domain + \ aws_elasticsearch_domain_policy \ aws_elastictranscoder_pipeline \ aws_elastictranscoder_preset \ aws_elb @@ -174,6 +218,9 @@ syn keyword terraResourceTypeBI \ aws_iam_user_policy \ aws_iam_user_policy_attachment \ aws_iam_user_ssh_key + \ aws_inspector_assessment_target + \ aws_inspector_assessment_template + \ aws_inspector_resource_group \ aws_instance \ aws_internet_gateway \ aws_key_pair @@ -244,6 +291,8 @@ syn keyword terraResourceTypeBI \ aws_ses_receipt_filter \ aws_ses_receipt_rule \ aws_ses_receipt_rule_set + \ aws_sfn_activity + \ aws_sfn_state_machine \ aws_simpledb_domain \ aws_snapshot_create_volume_permission \ aws_sns_topic @@ -265,6 +314,7 @@ syn keyword terraResourceTypeBI \ aws_vpc_endpoint \ aws_vpc_endpoint_route_table_association \ aws_vpc_peering_connection + \ aws_vpc_peering_connection_accepter \ aws_vpn_connection \ aws_vpn_connection_route \ aws_vpn_gateway @@ -296,6 +346,7 @@ syn keyword terraResourceTypeBI \ azurerm_cdn_endpoint \ azurerm_cdn_profile \ azurerm_container_registry + \ azurerm_container_service \ azurerm_dns_a_record \ azurerm_dns_aaaa_record \ azurerm_dns_cname_record @@ -455,6 +506,8 @@ syn keyword terraResourceTypeBI \ google_dns_managed_zone \ google_dns_record_set \ google_project + \ google_project_iam_policy + \ google_project_services \ google_pubsub_subscription \ google_pubsub_topic \ google_service_account @@ -539,6 +592,7 @@ syn keyword terraResourceTypeBI \ packet_project \ packet_ssh_key \ packet_volume + \ pagerduty_addon \ pagerduty_escalation_policy \ pagerduty_schedule \ pagerduty_service @@ -550,6 +604,14 @@ syn keyword terraResourceTypeBI \ postgresql_role \ postgresql_schema \ powerdns_record + \ profitbricks_datacenter + \ profitbricks_firewall + \ profitbricks_ipblock + \ profitbricks_lan + \ profitbricks_loadbalancer + \ profitbricks_nic + \ profitbricks_server + \ profitbricks_volume \ rabbitmq_binding \ rabbitmq_exchange \ rabbitmq_permissions @@ -642,7 +704,7 @@ syn match terraBraces "[{}\[\]]" syn region terraValueString start=/"/ skip=/\\\+"/ end=/"/ contains=terraStringInterp syn region terraStringInterp matchgroup=terraBrackets start=/\${/ end=/}/ contains=terraValueFunction contained "" TODO match keywords here, not a-z+ -syn region terraValueFunction matchgroup=terraBrackets start=/[a-z]\+(/ end=/)/ contains=terraValueString,terraValueFunction contained +syn region terraValueFunction matchgroup=terraBrackets start=/[0-9a-z]\+(/ end=/)/ contains=terraValueString,terraValueFunction contained hi def link terraComment Comment hi def link terraTodo Todo diff --git a/syntax/typescript.vim b/syntax/typescript.vim index f129731f..9e5d08be 100644 --- a/syntax/typescript.vim +++ b/syntax/typescript.vim @@ -124,7 +124,7 @@ syntax keyword typescriptGlobalObjects Array Boolean Date Function Infinity Math syntax keyword typescriptExceptions try catch throw finally Error EvalError RangeError ReferenceError SyntaxError TypeError URIError -syntax keyword typescriptReserved constructor declare as interface module abstract enum int short export interface static byte extends long super char final native synchronized class float package throws goto private transient debugger implements protected volatile double import public type namespace from get set +syntax keyword typescriptReserved constructor declare as interface module abstract enum int short export interface static byte extends long super char final native synchronized class float package throws goto private transient debugger implements protected volatile double import public type namespace from get set keyof "}}} "" typescript/DOM/HTML/CSS specified things"{{{ @@ -134,7 +134,7 @@ syntax keyword typescriptReserved constructor declare as interface module abstra syn match typescriptParameters "([a-zA-Z0-9_?.$][\w?.$]*)\s*:\s*([a-zA-Z0-9_?.$][\w?.$]*)" contained skipwhite "}}} " DOM2 Objects"{{{ - syntax keyword typescriptType DOMImplementation DocumentFragment Node NodeList NamedNodeMap CharacterData Attr Element Text Comment CDATASection DocumentType Notation Entity EntityReference ProcessingInstruction void any string boolean number symbol never + syntax keyword typescriptType DOMImplementation DocumentFragment Node NodeList NamedNodeMap CharacterData Attr Element Text Comment CDATASection DocumentType Notation Entity EntityReference ProcessingInstruction void any string boolean number symbol never object syntax keyword typescriptExceptions DOMException "}}} " DOM2 CONSTANT"{{{ diff --git a/syntax/vala.vim b/syntax/vala.vim index 52359f87..5c43c73f 100644 --- a/syntax/vala.vim +++ b/syntax/vala.vim @@ -7,7 +7,6 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vala') == -1 " pancake <pancake@nopcode.org> " Sebastian Reichel <sre@ring0.de> " Adrià Arrufat <adria.arrufat@protonmail.ch> -" Last Change: 2016-10-20 " Filenames: *.vala *.vapi *.valadoc " " REFERENCES: @@ -53,11 +52,13 @@ syn keyword valaUnspecifiedStatement as base construct delete get in is lock new " Arrays and Lists syn match valaArray "\(\w\(\w\)*\(\s\+\)\?<\)\+\(\(\s\+\)\?\w\(\w\)*\(?\|\*\)\?\(\,\)\?\)\+>\+" " Methods -syn match valaMethod "\w\(\w\)*\(\s\+\)\?("he=e-1,me=e-1 +syn match valaMethod "\(@\)\?\w\(\w\)*\(\s\+\)\?("he=e-1,me=e-1 " Operators syn match valaOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\|?\)=\?" " Delimiters syn match valaDelimiter display "(\|)\|\[\|\]\|,\|;\|:\|{\|}\|\k\@<!_\k\@!\|[[:punct:]]\@<!@[[:punct:]]\@!" +" Enum Fields +syn match valaEnumField "\.\([A-Z_]\)\+\([A-Z_]\)\+"hs=s+1 " ensure there are at least 2 CAPS " Comments syn cluster valaCommentGroup contains=valaTodo @@ -67,9 +68,9 @@ syn keyword valaTodo contained TODO FIXME XXX NOTE if !exists("vala_ignore_valadoc") syn cluster valaDocCommentGroup contains=valaDocTags,valaDocSeeTag syn region valaDocTags contained start="{@\(link\|inherit[Dd]oc\)" end="}" - syn match valaDocTags contained "@\(param\|exception\|throws\|since\)\s\+\S\+" contains=valaDocParam + syn match valaDocTags contained "@\(param\|exception\|throws\|since\|[Vv]ersion\)\s\+\S\+" contains=valaDocParam syn match valaDocParam contained "\s\S\+" - syn match valaDocTags contained "@\(return\|deprecated\)\>" + syn match valaDocTags contained "@\(return\)\>" syn region valaDocSeeTag contained matchgroup=valaDocTags start="@see\s\+" matchgroup=NONE end="\_."re=e-1 contains=valaDocSeeTagParam syn match valaDocSeeTagParam contained @"\_[^"]\+"\|<a\s\+\_.\{-}</a>\|\(\k\|\.\)*\(#\k\+\((\_[^)]\+)\)\=\)\=@ extend endif @@ -110,6 +111,9 @@ syntax match valaCommentStartError display "/\*"me=e-1 contained " match the special comment /**/ syn match valaComment "/\*\*/" +" comment script lines +syn region valaScript start="^#!" end="$" + " Vala Code Attributes syn region valaAttribute start="^\s*\[" end="\]" contains=valaComment,valaString keepend syn region valaAttribute start="\[CCode" end="\]" contains=valaComment,valaString @@ -175,6 +179,7 @@ hi def link valaArray StorageClass hi def link valaMethod Function hi def link valaOperator Operator hi def link valaDelimiter Delimiter +hi def link valaEnumField Constant hi def link valaCommentError Error hi def link valaCommentStartError Error @@ -187,6 +192,7 @@ hi def link valaCommentL valaComment hi def link valaCommentStart valaComment hi def link valaCommentSkip valaComment hi def link valaComment Comment +hi def link valaScript Comment hi def link valaDocComment Comment hi def link valaDocTags Special hi def link valaDocParam Function diff --git a/syntax/vue.vim b/syntax/vue.vim index 89b5b794..a3ab794c 100644 --- a/syntax/vue.vim +++ b/syntax/vue.vim @@ -27,84 +27,70 @@ if !exists("s:syntaxes") return syntaxes endfunction - let s:syntaxes = s:search_syntaxes('pug', 'slm', 'coffee', 'stylus', 'sass', 'scss', 'less') + let s:syntaxes = s:search_syntaxes('pug', 'slm', 'coffee', 'stylus', 'sass', 'scss', 'less', 'typescript') endif syntax include @HTML syntax/html.vim -if exists("b:current_syntax") - unlet b:current_syntax -endif -syntax region html keepend start=/^<template>/ end=/^<\/template>/ contains=@HTML fold +unlet! b:current_syntax +syntax region html keepend start=/^<template\_[^>]*>/ end=/^<\/template>/ contains=@HTML fold if s:syntaxes.pug syntax include @PUG syntax/pug.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif + unlet! b:current_syntax syntax region pug keepend start=/<template lang=\("\|'\)[^\1]*pug[^\1]*\1>/ end="</template>" contains=@PUG fold syntax region pug keepend start=/<template lang=\("\|'\)[^\1]*jade[^\1]*\1>/ end="</template>" contains=@PUG fold endif if s:syntaxes.slm syntax include @SLM syntax/slm.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif + unlet! b:current_syntax syntax region slm keepend start=/<template lang=\("\|'\)[^\1]*slm[^\1]*\1>/ end="</template>" contains=@SLM fold endif syntax include @JS syntax/javascript.vim -if exists("b:current_syntax") - unlet b:current_syntax -endif +unlet! b:current_syntax syntax region javascript keepend matchgroup=Delimiter start=/<script\( lang="babel"\)\?\( type="text\/babel"\)\?>/ end="</script>" contains=@JS fold +if s:syntaxes.typescript + syntax include @TS syntax/typescript.vim + unlet! b:current_syntax + syntax region typescript keepend matchgroup=Delimiter start=/<script \_[^>]*\(lang=\("\|'\)[^\2]*\(ts\|typescript\)[^\2]*\2\|ts\)\_[^>]*>/ end="</script>" contains=@TS fold +endif + if s:syntaxes.coffee syntax include @COFFEE syntax/coffee.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif + unlet! b:current_syntax " Matchgroup seems to be necessary for coffee syntax region coffee keepend matchgroup=Delimiter start="<script lang=\"coffee\">" end="</script>" contains=@COFFEE fold endif syntax include @CSS syntax/css.vim -if exists("b:current_syntax") - unlet b:current_syntax -endif -syntax region css keepend start=/<style\( \+scoped\)\?>/ end="</style>" contains=@CSS fold +unlet! b:current_syntax +syntax region css keepend start=/<style\_[^>]*>/ end="</style>" contains=@CSS fold if s:syntaxes.stylus syntax include @stylus syntax/stylus.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif - syntax region stylus keepend start=/<style lang=\("\|'\)[^\1]*stylus[^\1]*\1\( \+scoped\)\?>/ end="</style>" contains=@stylus fold + unlet! b:current_syntax + syntax region stylus keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*stylus[^\1]*\1\_[^>]*>/ end="</style>" contains=@stylus fold endif if s:syntaxes.sass syntax include @sass syntax/sass.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif - syntax region sass keepend start=/<style\( \+scoped\)\? lang=\("\|'\)[^\1]*sass[^\1]*\1\( \+scoped\)\?>/ end="</style>" contains=@sass fold + unlet! b:current_syntax + syntax region sass keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*sass[^\1]*\1\_[^>]*>/ end="</style>" contains=@sass fold endif if s:syntaxes.scss syntax include @scss syntax/scss.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif - syntax region scss keepend start=/<style\( \+scoped\)\? lang=\("\|'\)[^\1]*scss[^\1]*\1\( \+scoped\)\?>/ end="</style>" contains=@scss fold + unlet! b:current_syntax + syntax region scss keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*scss[^\1]*\1\_[^>]*>/ end="</style>" contains=@scss fold endif if s:syntaxes.less syntax include @less syntax/less.vim - if exists("b:current_syntax") - unlet b:current_syntax - endif - syntax region less keepend matchgroup=PreProc start=/<style\%( \+scoped\)\? lang=\("\|'\)[^\1]*less[^\1]*\1\%( \+scoped\)\?>/ end="</style>" contains=@less fold + unlet! b:current_syntax + syntax region less keepend matchgroup=PreProc start=/<style \_[^>]*lang=\("\|'\)[^\1]*less[^\1]*\1\_[^>]*>/ end="</style>" contains=@less fold endif let b:current_syntax = "vue" |