From af870100716f20ee4daef9cc527a9ecf41b54114 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 17 May 2017 11:07:28 +0200 Subject: Update --- after/ftplugin/terraform.vim | 33 ++++ after/syntax/yaml.vim | 4 +- autoload/elixir/indent.vim | 442 ++++++++++++++++++++++++++++--------------- autoload/elixir/util.vim | 58 ++---- autoload/xml/html5.vim | 9 +- compiler/eslint.vim | 5 + compiler/rake.vim | 8 +- ftdetect/polyglot.vim | 33 ++-- ftplugin/eelixir.vim | 4 +- ftplugin/elixir.vim | 39 +--- ftplugin/plantuml.vim | 15 +- ftplugin/ps1.vim | 2 + ftplugin/ps1xml.vim | 2 + ftplugin/ruby.vim | 45 ++--- ftplugin/vue.vim | 7 + indent/ansible.vim | 5 + indent/elixir.vim | 127 ++++--------- indent/haskell.vim | 90 +++++---- indent/javascript.vim | 262 ++++++++++++++++--------- indent/plantuml.vim | 4 +- indent/ruby.vim | 96 +++++----- indent/vue.vim | 59 ++++-- syntax/c.vim | 4 +- syntax/crystal.vim | 2 +- syntax/glsl.vim | 14 +- syntax/gotexttmpl.vim | 4 +- syntax/haskell.vim | 42 ++-- syntax/html.vim | 4 +- syntax/javascript.vim | 8 +- syntax/markdown.vim | 4 +- syntax/nginx.vim | 41 ++-- syntax/plantuml.vim | 314 +++++++++++++++++++++--------- syntax/pug.vim | 5 +- syntax/ruby.vim | 12 +- syntax/swift.vim | 9 +- syntax/terraform.vim | 62 ++++++ syntax/tmux.vim | 16 +- syntax/vue.vim | 129 +++++-------- 38 files changed, 1212 insertions(+), 807 deletions(-) diff --git a/after/ftplugin/terraform.vim b/after/ftplugin/terraform.vim index 17115b1b..add09445 100644 --- a/after/ftplugin/terraform.vim +++ b/after/ftplugin/terraform.vim @@ -18,6 +18,38 @@ if g:terraform_align && exists(':Tabularize') endfunction endif + +function! TerraformFolds() + let thisline = getline(v:lnum) + if match(thisline, '^resource') >= 0 + return ">1" + elseif match(thisline, '^provider') >= 0 + return ">1" + elseif match(thisline, '^module') >= 0 + return ">1" + elseif match(thisline, '^variable') >= 0 + return ">1" + elseif match(thisline, '^output') >= 0 + return ">1" + else + return "=" + endif +endfunction +setlocal foldmethod=expr +setlocal foldexpr=TerraformFolds() +setlocal foldlevel=1 + +function! TerraformFoldText() + let foldsize = (v:foldend-v:foldstart) + return getline(v:foldstart).' ('.foldsize.' lines)' +endfunction +setlocal foldtext=TerraformFoldText() + +"inoremap za +nnoremap za +onoremap za +vnoremap zf + " 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 @@ -25,4 +57,5 @@ if get(g:, "terraform_align", 1) setlocal shiftwidth=2 endif + endif diff --git a/after/syntax/yaml.vim b/after/syntax/yaml.vim index 78983cc2..d429da68 100644 --- a/after/syntax/yaml.vim +++ b/after/syntax/yaml.vim @@ -38,8 +38,8 @@ syn keyword yamlConstant NULL Null null NONE None none NIL Nil nil 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 yamlKey "^\s*\zs[^ \t\"]\+\ze\s*:" +syn match yamlKey "^\s*-\s*\zs[^ \t\"]\+\ze\s*:" syn match yamlAnchor "&\S\+" syn match yamlAlias "*\S\+" diff --git a/autoload/elixir/indent.vim b/autoload/elixir/indent.vim index b6df3b5d..fd2f4a3f 100644 --- a/autoload/elixir/indent.vim +++ b/autoload/elixir/indent.vim @@ -1,219 +1,347 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'elixir') == -1 -let s:NO_COLON_BEFORE = ':\@' -let s:END_WITH_ARROW = s:ARROW.'$' -let s:SKIP_SYNTAX = '\%(Comment\|String\)$' -let s:BLOCK_SKIP = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '".s:SKIP_SYNTAX."'" -let s:DEF = '^\s*def' -let s:FN = '\' -let s:MULTILINE_FN = s:FN.'\%(.*end\)\@!' -let s:BLOCK_START = '\%(\\|'.s:FN.'\)\>' -let s:MULTILINE_BLOCK = '\%(\'.s:NO_COLON_AFTER.'\|'.s:MULTILINE_FN.'\)' -let s:BLOCK_MIDDLE = '\<\%(else\|match\|elsif\|catch\|after\|rescue\)\>' -let s:BLOCK_END = 'end' -let s:STARTS_WITH_PIPELINE = '^\s*|>.*$' -let s:QUERY_FROM = '^\s*\.*\.*,' -let s:ENDING_WITH_ASSIGNMENT = '=\s*$' -let s:INDENT_KEYWORDS = s:NO_COLON_BEFORE.'\%('.s:MULTILINE_BLOCK.'\|'.s:BLOCK_MIDDLE.'\)' -let s:DEINDENT_KEYWORDS = '^\s*\<\%('.s:BLOCK_END.'\|'.s:BLOCK_MIDDLE.'\)\>' -let s:PAIR_START = '\<\%('.s:NO_COLON_BEFORE.s:BLOCK_START.'\)\>'.s:NO_COLON_AFTER -let s:PAIR_MIDDLE = '^\s*\%('.s:BLOCK_MIDDLE.'\)\>'.s:NO_COLON_AFTER.'\zs' -let s:PAIR_END = '\<\%('.s:NO_COLON_BEFORE.s:BLOCK_END.'\)\>\zs' -let s:LINE_COMMENT = '^\s*#' -let s:MATCH_OPERATOR = '[^!><=]=[^~=>]' - -function! s:pending_parenthesis(line) - if a:line.last_non_blank.text !~ s:ARROW - return elixir#util#count_indentable_symbol_diff(a:line.last_non_blank, '(', '\%(end\s*\)\@ 0 - \ && (a:line.current.text =~ s:ARROW - \ || a:line.current.text =~ s:BLOCK_END) - let ind = b:old_ind.arrow - let b:old_ind.arrow = 0 - return ind - else - return a:ind - end +" Returns 0 or 1 based on whether or not the text matches the given expression +function! elixir#indent#contains(text, expr) + return a:text =~ a:expr endfunction -function! elixir#indent#deindent_ending_symbols(ind, line) - if a:line.current.text =~ '^\s*\('.s:ENDING_SYMBOLS.'\)' - return a:ind - &sw - else - return a:ind - end +" Returns 0 or 1 based on whether or not the given line number and column +" number pair is a string or comment +function! elixir#indent#is_string_or_comment(line, col) + return synIDattr(synID(a:line, a:col, 1), "name") =~ '\%(String\|Comment\)' endfunction -function! elixir#indent#deindent_keywords(ind, line) - if a:line.current.text =~ s:DEINDENT_KEYWORDS - let bslnum = searchpair( - \ s:PAIR_START, - \ s:PAIR_MIDDLE, - \ s:PAIR_END, - \ 'nbW', - \ s:BLOCK_SKIP - \ ) +" Skip expression for searchpair. Returns 0 or 1 based on whether the value +" under the cursor is a string or comment +function! elixir#indent#searchpair_back_skip() + " NOTE: @jbodah 2017-02-27: for some reason this function gets called with + " and index that doesn't exist in the line sometimes. Detect and account for + " that situation + let curr_col = col('.') + if getline('.')[curr_col-1] == '' + let curr_col = curr_col-1 + endif + return elixir#indent#is_string_or_comment(line('.'), curr_col) +endfunction - return indent(bslnum) +" DRY up searchpair calls +function! elixir#indent#searchpair_back(start, mid, end) + let line = line('.') + return searchpair(a:start, a:mid, a:end, 'bnW', "line('.') == " . line . " || elixir#indent#searchpair_back_skip()") +endfunction + +" DRY up searchpairpos calls +function! elixir#indent#searchpairpos_back(start, mid, end) + let line = line('.') + return searchpairpos(a:start, a:mid, a:end, 'bnW', "line('.') == " . line . " || elixir#indent#searchpair_back_skip()") +endfunction + +" DRY up regex for keywords that 1) makes sure we only look at complete words +" and 2) ignores atoms +function! elixir#indent#keyword(expr) + return ':\@:\@!' +endfunction + +function! elixir#indent#starts_with_comment(text) + return match(a:text, '^\s*#') != -1 +endfunction + +" Start at the end of text and search backwards looking for a match. Also peek +" ahead if we get a match to make sure we get a complete match. This means +" that the result should be the position of the start of the right-most match +function! elixir#indent#find_last_pos(lnum, text, match) + let last = len(a:text) - 1 + let c = last + + while c >= 0 + let substr = strpart(a:text, c, last) + let peek = strpart(a:text, c - 1, last) + let ss_match = match(substr, a:match) + if ss_match != -1 + let peek_match = match(peek, a:match) + if peek_match == ss_match + 1 + let syng = synIDattr(synID(a:lnum, c + ss_match, 1), 'name') + if syng !~ '\%(String\|Comment\)' + return c + ss_match + end + end + end + let c -= 1 + endwhile + + return -1 +endfunction + +function! elixir#indent#handle_top_of_file(_lnum, _text, prev_nb_lnum, _prev_nb_text) + if a:prev_nb_lnum == 0 + return 0 else - return a:ind + return -1 end endfunction -function! elixir#indent#deindent_opened_symbols(ind, line) - let s:opened_symbol = - \ s:pending_parenthesis(a:line) - \ + s:pending_square_brackets(a:line) - \ + s:pending_brackets(a:line) +" TODO: @jbodah 2017-03-31: remove +function! elixir#indent#handle_following_trailing_do(lnum, text, prev_nb_lnum, prev_nb_text) + if elixir#indent#ends_with(a:prev_nb_text, elixir#indent#keyword('do'), a:prev_nb_lnum) + if elixir#indent#starts_with(a:text, elixir#indent#keyword('end'), a:lnum) + return indent(a:prev_nb_lnum) + else + return indent(a:prev_nb_lnum) + &sw + end + else + return -1 + endif +endfunction - if s:opened_symbol < 0 - let ind = get(b:old_ind, 'symbol', a:ind + (s:opened_symbol * &sw)) - let ind = float2nr(ceil(floor(ind)/&sw)*&sw) - return ind <= 0 ? 0 : ind +function! elixir#indent#handle_following_trailing_binary_operator(lnum, text, prev_nb_lnum, prev_nb_text) + let binary_operator = '\%(=\|<>\|>>>\|<=\|||\|+\|\~\~\~\|-\|&&\|<<<\|/\|\^\^\^\|\*\)' + + if elixir#indent#ends_with(a:prev_nb_text, binary_operator, a:prev_nb_lnum) + return indent(a:prev_nb_lnum) + &sw else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_after_pipeline(ind, line) - if exists("b:old_ind.pipeline") - \ && elixir#util#is_blank(a:line.last.text) - \ && a:line.current.text !~ s:STARTS_WITH_PIPELINE - " Reset indentation in pipelines if there is a blank line between - " pipes - let ind = b:old_ind.pipeline - unlet b:old_ind.pipeline - return ind - elseif a:line.last_non_blank.text =~ s:STARTS_WITH_PIPELINE - if empty(substitute(a:line.current.text, ' ', '', 'g')) - \ || a:line.current.text =~ s:STARTS_WITH_PIPELINE - return indent(a:line.last_non_blank.num) - elseif a:line.last_non_blank.text !~ s:INDENT_KEYWORDS - let ind = b:old_ind.pipeline - unlet b:old_ind.pipeline - return ind +function! elixir#indent#handle_starts_with_pipe(lnum, text, prev_nb_lnum, prev_nb_text) + if elixir#indent#starts_with(a:text, '|>', a:lnum) + let match_operator = '\%(!\|=\|<\|>\)\@\|\~\)\@!' + let pos = elixir#indent#find_last_pos(a:prev_nb_lnum, a:prev_nb_text, match_operator) + if pos == -1 + return indent(a:prev_nb_lnum) + else + let next_word_pos = match(strpart(a:prev_nb_text, pos+1, len(a:prev_nb_text)-1), '\S') + if next_word_pos == -1 + return indent(a:prev_nb_lnum) + &sw + else + return pos + 1 + next_word_pos + end end - end + else + return -1 + endif +endfunction - return a:ind +function! elixir#indent#handle_starts_with_comment(_lnum, text, prev_nb_lnum, _prev_nb_text) + if elixir#indent#starts_with_comment(a:text) + return indent(a:prev_nb_lnum) + else + return -1 + endif endfunction -function! elixir#indent#indent_assignment(ind, line) - if a:line.last_non_blank.text =~ s:ENDING_WITH_ASSIGNMENT - let b:old_ind.pipeline = indent(a:line.last_non_blank.num) " FIXME: side effect - return a:ind + &sw +function! elixir#indent#handle_starts_with_end(lnum, text, _prev_nb_lnum, _prev_nb_text) + if elixir#indent#starts_with(a:text, elixir#indent#keyword('end'), a:lnum) + let pair_lnum = elixir#indent#searchpair_back(elixir#indent#keyword('do\|fn'), '', elixir#indent#keyword('end').'\zs') + return indent(pair_lnum) else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_brackets(ind, line) - if s:pending_brackets(a:line) > 0 - return a:ind + &sw +function! elixir#indent#handle_starts_with_mid_or_end_block_keyword(lnum, text, _prev_nb_lnum, _prev_nb_text) + if elixir#indent#starts_with(a:text, elixir#indent#keyword('catch\|rescue\|after\|else'), a:lnum) + let pair_lnum = elixir#indent#searchpair_back(elixir#indent#keyword('with\|receive\|try\|if\|fn'), elixir#indent#keyword('catch\|rescue\|after\|else').'\zs', elixir#indent#keyword('end')) + return indent(pair_lnum) else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_case_arrow(ind, line) - if a:line.last_non_blank.text =~ s:END_WITH_ARROW && a:line.last_non_blank.text !~ '\' - let b:old_ind.arrow = a:ind - return a:ind + &sw +function! elixir#indent#handle_starts_with_close_bracket(lnum, text, _prev_nb_lnum, _prev_nb_text) + if elixir#indent#starts_with(a:text, '\%(\]\|}\|)\)', a:lnum) + let pair_lnum = elixir#indent#searchpair_back('\%(\[\|{\|(\)', '', '\%(\]\|}\|)\)') + return indent(pair_lnum) else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_ending_symbols(ind, line) - if a:line.last_non_blank.text =~ '^\s*\('.s:ENDING_SYMBOLS.'\)\s*$' - return a:ind + &sw +function! elixir#indent#handle_starts_with_binary_operator(lnum, text, prev_nb_lnum, prev_nb_text) + let binary_operator = '\%(=\|<>\|>>>\|<=\|||\|+\|\~\~\~\|-\|&&\|<<<\|/\|\^\^\^\|\*\)' + + if elixir#indent#starts_with(a:text, binary_operator, a:lnum) + let match_operator = '\%(!\|=\|<\|>\)\@\|\~\)\@!' + let pos = elixir#indent#find_last_pos(a:prev_nb_lnum, a:prev_nb_text, match_operator) + if pos == -1 + return indent(a:prev_nb_lnum) + else + let next_word_pos = match(strpart(a:prev_nb_text, pos+1, len(a:prev_nb_text)-1), '\S') + if next_word_pos == -1 + return indent(a:prev_nb_lnum) + &sw + else + return pos + 1 + next_word_pos + end + end else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_keywords(ind, line) - if a:line.last_non_blank.text =~ s:INDENT_KEYWORDS && a:line.last_non_blank.text !~ s:LINE_COMMENT - return a:ind + &sw +" To handle nested structures properly we need to find the innermost +" nested structure. For example, we might be in a function in a map in a +" function, etc... so we need to first figure out what the innermost structure +" is then forward execution to the proper handler +function! elixir#indent#handle_inside_nested_construct(lnum, text, prev_nb_lnum, prev_nb_text) + let start_pattern = '\C\%(\\|\\|\\|\\|\\|\\|{\|\[\|(\)' + let end_pattern = '\C\%(\\|\]\|}\|)\)' + let pair_info = elixir#indent#searchpairpos_back(start_pattern, '', end_pattern) + let pair_lnum = pair_info[0] + let pair_col = pair_info[1] + if pair_lnum != 0 || pair_col != 0 + let pair_text = getline(pair_lnum) + let pair_char = pair_text[pair_col - 1] + if pair_char == 'f' + call elixir#indent#debug("testing elixir#indent#do_handle_inside_fn") + return elixir#indent#do_handle_inside_fn(pair_lnum, pair_col, a:lnum, a:text, a:prev_nb_lnum, a:prev_nb_text) + elseif pair_char == '[' + call elixir#indent#debug("testing elixir#indent#do_handle_inside_square_brace") + return elixir#indent#do_handle_inside_square_brace(pair_lnum, pair_col, a:lnum, a:text, a:prev_nb_lnum, a:prev_nb_text) + elseif pair_char == '{' + call elixir#indent#debug("testing elixir#indent#do_handle_inside_curly_brace") + return elixir#indent#do_handle_inside_curly_brace(pair_lnum, pair_col, a:lnum, a:text, a:prev_nb_lnum, a:prev_nb_text) + elseif pair_char == '(' + call elixir#indent#debug("testing elixir#indent#do_handle_inside_parens") + return elixir#indent#do_handle_inside_parens(pair_lnum, pair_col, a:lnum, a:text, a:prev_nb_lnum, a:prev_nb_text) + else + call elixir#indent#debug("testing elixir#indent#do_handle_inside_keyword_block") + return elixir#indent#do_handle_inside_keyword_block(pair_lnum, pair_col, a:lnum, a:text, a:prev_nb_lnum, a:prev_nb_text) + end else - return a:ind + return -1 end endfunction -function! elixir#indent#indent_parenthesis(ind, line) - if s:pending_parenthesis(a:line) > 0 - \ && a:line.last_non_blank.text !~ s:DEF - \ && a:line.last_non_blank.text !~ s:END_WITH_ARROW - let b:old_ind.symbol = a:ind - return matchend(a:line.last_non_blank.text, '(') +function! elixir#indent#do_handle_inside_keyword_block(pair_lnum, _pair_col, _lnum, text, prev_nb_lnum, prev_nb_text) + let keyword_pattern = '\C\%(\\|\\|\\|\\|\\|\\|\\|\\)' + if a:pair_lnum + " last line is a "receive" or something + if elixir#indent#starts_with(a:prev_nb_text, keyword_pattern, a:prev_nb_lnum) + call elixir#indent#debug("prev nb line is keyword") + return indent(a:prev_nb_lnum) + &sw + elseif elixir#indent#contains(a:text, '->') + call elixir#indent#debug("contains ->") + " TODO: @jbodah 2017-03-31: test contains ignores str + comments + return indent(a:pair_lnum) + &sw + elseif elixir#indent#contains(a:prev_nb_text, '->') + call elixir#indent#debug("prev nb line contains ->") + return indent(a:prev_nb_lnum) + &sw + else + call elixir#indent#debug("doesnt start with comment or contain ->") + return indent(a:prev_nb_lnum) + end else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_pipeline_assignment(ind, line) - if a:line.current.text =~ s:STARTS_WITH_PIPELINE - \ && a:line.last_non_blank.text =~ s:MATCH_OPERATOR - let b:old_ind.pipeline = indent(a:line.last_non_blank.num) - " if line starts with pipeline - " and last_non_blank line is an attribution - " indents pipeline in same level as attribution - let assign_pos = match(a:line.last_non_blank.text, '=\s*\zs[^ ]') - return (elixir#util#is_indentable_at(a:line.last_non_blank.num, assign_pos) ? assign_pos : a:ind) +function! elixir#indent#do_handle_inside_fn(pair_lnum, _pair_col, lnum, text, prev_nb_lnum, prev_nb_text) + if a:pair_lnum && a:pair_lnum != a:lnum + if elixir#indent#contains(a:text, '->') + return indent(a:pair_lnum) + &sw + else + if elixir#indent#ends_with(a:prev_nb_text, '->', a:prev_nb_lnum) + return indent(a:prev_nb_lnum) + &sw + else + return indent(a:prev_nb_lnum) + end + end else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_pipeline_continuation(ind, line) - if a:line.last_non_blank.text =~ s:STARTS_WITH_PIPELINE - \ && a:line.current.text =~ s:STARTS_WITH_PIPELINE - return indent(a:line.last_non_blank.num) +function! elixir#indent#do_handle_inside_square_brace(pair_lnum, pair_col, _lnum, _text, _prev_nb_lnum, _prev_nb_text) + " If in list... + if a:pair_lnum != 0 || a:pair_col != 0 + let pair_text = getline(a:pair_lnum) + let substr = strpart(pair_text, a:pair_col, len(pair_text)-1) + let indent_pos = match(substr, '\S') + if indent_pos != -1 + return indent_pos + a:pair_col + else + return indent(a:pair_lnum) + &sw + endif else - return a:ind + return -1 end endfunction -function! elixir#indent#indent_square_brackets(ind, line) - if s:pending_square_brackets(a:line) > 0 - if a:line.last_non_blank.text =~ '[\s*$' - return a:ind + &sw +function! elixir#indent#do_handle_inside_curly_brace(pair_lnum, _pair_col, _lnum, _text, _prev_nb_lnum, _prev_nb_text) + return indent(a:pair_lnum) + &sw +endfunction + +function! elixir#indent#do_handle_inside_parens(pair_lnum, pair_col, _lnum, _text, prev_nb_lnum, prev_nb_text) + if a:pair_lnum + if elixir#indent#ends_with(a:prev_nb_text, '(', a:prev_nb_lnum) + return indent(a:prev_nb_lnum) + &sw + elseif a:pair_lnum == a:prev_nb_lnum + " Align indent (e.g. "def add(a,") + let pos = elixir#indent#find_last_pos(a:prev_nb_lnum, a:prev_nb_text, '[^(]\+,') + if pos == -1 + return 0 + else + return pos + end else - " if start symbol is followed by a character, indent based on the - " whitespace after the symbol, otherwise use the default shiftwidth - " Avoid negative indentation index - return matchend(a:line.last_non_blank.text, '[\s*') + return indent(a:prev_nb_lnum) end else - return a:ind - end + return -1 + endif endfunction -function! elixir#indent#indent_ecto_queries(ind, line) - if a:line.last_non_blank.text =~ s:QUERY_FROM - return a:ind + &sw +function! elixir#indent#handle_inside_generic_block(lnum, _text, prev_nb_lnum, prev_nb_text) + let pair_lnum = searchpair(elixir#indent#keyword('do\|fn'), '', elixir#indent#keyword('end'), 'bW', "line('.') == ".a:lnum." || elixir#indent#is_string_or_comment(line('.'), col('.'))") + if pair_lnum + " TODO: @jbodah 2017-03-29: this should probably be the case in *all* + " blocks + if elixir#indent#ends_with(a:prev_nb_text, ',', a:prev_nb_lnum) + return indent(pair_lnum) + 2 * &sw + else + return indent(pair_lnum) + &sw + endif else - return a:ind - end + return -1 + endif endfunction endif diff --git a/autoload/elixir/util.vim b/autoload/elixir/util.vim index fbbd62aa..46db20e0 100644 --- a/autoload/elixir/util.vim +++ b/autoload/elixir/util.vim @@ -1,52 +1,28 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'elixir') == -1 -let s:SKIP_SYNTAX = '\%(Comment\|String\)$' +function! elixir#util#get_filename(word) abort + let word = a:word -function! elixir#util#is_indentable_at(line, col) - if a:col == -1 " skip synID lookup for not found match - return 1 - end - " TODO: Remove these 2 lines - " I don't know why, but for the test on spec/indent/lists_spec.rb:24. - " Vim is making some mess on parsing the syntax of 'end', it is being - " recognized as 'elixirString' when should be recognized as 'elixirBlock'. - call synID(a:line, a:col, 1) - " This forces vim to sync the syntax. Using fromstart is very slow on files - " over 1k lines - syntax sync minlines=20 maxlines=150 + " get first thing that starts uppercase, until the first space or end of line + let word = substitute(word,'^\s*\(\u[^ ]\+\).*$','\1','g') - return synIDattr(synID(a:line, a:col, 1), "name") - \ !~ s:SKIP_SYNTAX -endfunction - -function! elixir#util#count_indentable_symbol_diff(line, open, close) - return - \ s:match_count(a:line, a:open) - \ - s:match_count(a:line, a:close) -endfunction + " remove any trailing characters that don't look like a nested module + let word = substitute(word,'\.\U.*$','','g') -function! s:match_count(line, pattern) - let size = strlen(a:line.text) - let index = 0 - let counter = 0 + " replace module dots with slash + let word = substitute(word,'\.','/','g') - while index < size - let index = match(a:line.text, a:pattern, index) - if index >= 0 - let index += 1 - if elixir#util#is_indentable_at(a:line.num, index) - let counter +=1 - end - else - break - end - endwhile + " remove any special chars + let word = substitute(word,'[^A-z0-9-_/]','','g') - return counter -endfunction + " convert to snake_case + let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') + let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') + let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g') + let word = substitute(word,'-','_','g') + let word = tolower(word) -function elixir#util#is_blank(string) - return a:string =~ '^\s*$' + return word endfunction endif diff --git a/autoload/xml/html5.vim b/autoload/xml/html5.vim index 73b24a4c..982fe29a 100644 --- a/autoload/xml/html5.vim +++ b/autoload/xml/html5.vim @@ -371,6 +371,7 @@ 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' +let crossorigin = ['anonymous', 'use-credentials'] let g:xmldata_html5 = { @@ -582,7 +583,7 @@ let g:xmldata_html5 = { \ ], \ 'img': [ \ [], - \ extend(copy(global_attributes), {'src': [], 'alt': [], 'height': [], 'width': [], 'usemap': [], 'ismap': ['ismap', ''], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url']}) + \ extend(copy(global_attributes), {'src': [], 'alt': [], 'height': [], 'width': [], 'usemap': [], 'ismap': ['ismap', ''], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url'], 'crossorigin': ['anonymous', 'use-credentials']}) \ ], \ 'input': [ \ [], @@ -614,7 +615,7 @@ let g:xmldata_html5 = { \ ], \ 'link': [ \ [], - \ extend(copy(global_attributes), {'href': [], 'rel': linkreltypes, 'hreflang': lang_tag, 'media': [], 'type': [], 'sizes': ['any'], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url']}) + \ extend(copy(global_attributes), {'href': [], 'rel': linkreltypes, 'hreflang': lang_tag, 'media': [], 'type': [], 'sizes': ['any'], 'referrerpolicy': ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'unsafe-url'], 'crossorigin': crossorigin, 'preload': ['preload', ''], 'prefetch': ['prefetch', '']}) \ ], \ 'main': [ \ flow_elements + ['style'], @@ -722,7 +723,7 @@ let g:xmldata_html5 = { \ ], \ 'script': [ \ [], - \ extend(copy(global_attributes), {'src': [], 'defer': ['defer', ''], 'async': ['async', ''], 'type': [], 'charset': charset, 'nonce': []}) + \ extend(copy(global_attributes), {'src': [], 'defer': ['defer', ''], 'async': ['async', ''], 'type': [], 'charset': charset, 'nonce': [], 'crossorigin': crossorigin}) \ ], \ 'section': [ \ flow_elements + ['style'], @@ -834,7 +835,7 @@ let g:xmldata_html5 = { \ ], \ 'video': [ \ flow_elements + ['source', 'track'], - \ extend(copy(global_attributes), {'autoplay': ['autoplay', ''], 'preload': ['none', 'metadata', 'auto', ''], 'controls': ['controls', ''], 'loop': ['loop', ''], 'playsinline': ['playsinline', ''], 'poster': [], 'height': [], 'width': [], 'src': []}) + \ extend(copy(global_attributes), {'autoplay': ['autoplay', ''], 'preload': ['none', 'metadata', 'auto', ''], 'controls': ['controls', ''], 'loop': ['loop', ''], 'playsinline': ['playsinline', ''], 'poster': [], 'height': [], 'width': [], 'src': [], 'crossorigin': crossorigin}) \ ], \ 'wbr': [ \ [], diff --git a/compiler/eslint.vim b/compiler/eslint.vim index 95e39535..123d9d1e 100644 --- a/compiler/eslint.vim +++ b/compiler/eslint.vim @@ -1,5 +1,10 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1 +" Vim compiler plugin +" Language: JavaScript +" Maintainer: vim-javascript community +" URL: https://github.com/pangloss/vim-javascript + if exists("current_compiler") finish endif diff --git a/compiler/rake.vim b/compiler/rake.vim index 3b130f1d..3ed1472b 100644 --- a/compiler/rake.vim +++ b/compiler/rake.vim @@ -24,10 +24,10 @@ CompilerSet errorformat= \%D(in\ %f), \%\\s%#from\ %f:%l:%m, \%\\s%#from\ %f:%l:, - \%\\s%##\ %f:%l:%m, - \%\\s%##\ %f:%l, - \%\\s%#[%f:%l:\ %#%m, - \%\\s%#%f:%l:\ %#%m, + \%\\s%##\ %f:%l:%m%\\&%.%#%\\D:%.%#, + \%\\s%##\ %f:%l%\\&%.%#%\\D:%.%#, + \%\\s%#[%f:%l:\ %#%m%\\&%.%#%\\D:%.%#, + \%\\s%#%f:%l:\ %#%m%\\&%.%#%\\D:%.%#, \%\\s%#%f:%l:, \%m\ [%f:%l]:, \%+Erake\ aborted!, diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index f4bd7e95..7f1f385f 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -165,8 +165,6 @@ au BufRead,BufNewFile *.ex,*.exs call s:setf('elixir') au BufRead,BufNewFile *.eex call s:setf('eelixir') au BufRead,BufNewFile * call s:DetectElixir() -au FileType elixir,eelixir setl sw=2 sts=2 et iskeyword+=!,? - function! s:setf(filetype) abort let &filetype = a:filetype endfunction @@ -283,7 +281,9 @@ augroup filetypedetect " Language: OpenGL Shading Language " Maintainer: Sergey Tikhomirov -autocmd! BufNewFile,BufRead *.glsl,*.geom,*.vert,*.frag,*.gsh,*.vsh,*.fsh,*.vs,*.fs,*.gs,*.tcs,*.tes,*.tesc,*.tese,*.comp set filetype=glsl +" Extensions supported by Khronos reference compiler +" https://github.com/KhronosGroup/glslang +autocmd! BufNewFile,BufRead *.vert,*.tesc,*.tese,*.geom,*.frag,*.comp set filetype=glsl " vim:set sts=2 sw=2 : augroup END @@ -376,10 +376,16 @@ augroup END augroup filetypedetect " javascript:pangloss/vim-javascript:_JAVASCRIPT -au BufNewFile,BufRead *.js setf javascript -au BufNewFile,BufRead *.jsm setf javascript -au BufNewFile,BufRead Jakefile setf javascript -au BufNewFile,BufRead *.es6 setf javascript +au BufNewFile,BufRead *.{js,jsm,es,es6},Jakefile setf javascript + +fun! s:SourceFlowSyntax() + if !exists('javascript_plugin_flow') && !exists('b:flow_active') && + \ search('\v\C%^\_s*%(//\s*|/\*[ \t\n*]*)\@flow>','nw') + runtime extras/flow.vim + let b:flow_active = 1 + endif +endfun +au FileType javascript au BufRead,BufWritePost call s:SourceFlowSyntax() fun! s:SelectJavascript() if getline(1) =~# '^#!.*/bin/\%(env\s\+\)\?node\>' @@ -616,11 +622,6 @@ augroup END augroup filetypedetect " plantuml:aklt/plantuml-syntax -" Vim ftdetect file -" Language: PlantUML -" Maintainer: Aaron C. Meadows < language name at shadowguarddev dot com> -" Version: 0.1 - if did_filetype() finish endif @@ -975,6 +976,12 @@ augroup END augroup filetypedetect " twig:lumiliet/vim-twig + +if !exists('g:vim_twig_filetype_detected') && has("autocmd") + au BufNewFile,BufRead *.twig set filetype=html.twig + au BufNewFile,BufRead *.html.twig set filetype=html.twig + au BufNewFile,BufRead *.xml.twig set filetype=xml.twig +endif augroup END augroup filetypedetect @@ -1002,7 +1009,7 @@ augroup END augroup filetypedetect " vue:posva/vim-vue -au BufNewFile,BufRead *.vue setf vue.html.javascript.css +au BufNewFile,BufRead *.vue setf vue augroup END augroup filetypedetect diff --git a/ftplugin/eelixir.vim b/ftplugin/eelixir.vim index eb6f6559..a4721f99 100644 --- a/ftplugin/eelixir.vim +++ b/ftplugin/eelixir.vim @@ -16,7 +16,7 @@ if !exists("g:eelixir_default_subtype") endif if !exists("b:eelixir_subtype") - let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$") + let s:lines = join(getline(1, 5) + [getline('$')], "\n") let b:eelixir_subtype = matchstr(s:lines,'eelixir_subtype=\zs\w\+') if b:eelixir_subtype == '' let b:eelixir_subtype = matchstr(&filetype,'^eex\.\zs\w\+') @@ -100,7 +100,7 @@ endif setlocal comments=:<%# setlocal commentstring=<%#\ %s\ %> -let b:undo_ftplugin = "setl cms< " +let b:undo_ftplugin = "setl cms< " . \ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin let &cpo = s:save_cpo diff --git a/ftplugin/elixir.vim b/ftplugin/elixir.vim index 807d0665..651cfba6 100644 --- a/ftplugin/elixir.vim +++ b/ftplugin/elixir.vim @@ -17,45 +17,24 @@ if exists("loaded_matchit") && !exists("b:match_words") \ ',{:},\[:\],(:)' endif +setlocal shiftwidth=2 softtabstop=2 expandtab iskeyword+=!,? setlocal comments=:# setlocal commentstring=#\ %s -function! GetElixirFilename(word) - let word = a:word - - " get first thing that starts uppercase, until the first space or end of line - let word = substitute(word,'^\s*\(\u[^ ]\+\).*$','\1','g') - - " remove any trailing characters that don't look like a nested module - let word = substitute(word,'\.\U.*$','','g') - - " replace module dots with slash - let word = substitute(word,'\.','/','g') - - " remove any special chars - let word = substitute(word,'[^A-z0-9-_/]','','g') - - " convert to snake_case - let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') - let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') - let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g') - let word = substitute(word,'-','_','g') - let word = tolower(word) - - return word -endfunction - let &l:path = \ join([ - \ getcwd().'/lib', - \ getcwd().'/src', - \ getcwd().'/deps/**/lib', - \ getcwd().'/deps/**/src', + \ 'lib', + \ 'src', + \ 'deps/**/lib', + \ 'deps/**/src', \ &g:path \ ], ',') -setlocal includeexpr=GetElixirFilename(v:fname) +setlocal includeexpr=elixir#util#get_filename(v:fname) setlocal suffixesadd=.ex,.exs,.eex,.erl,.yrl,.hrl silent! setlocal formatoptions-=t formatoptions+=croqlj +let b:undo_ftplugin = 'setlocal sw< sts< et< isk< com< cms< path< inex< sua< '. + \ '| unlet! b:match_ignorecase b:match_words' + endif diff --git a/ftplugin/plantuml.vim b/ftplugin/plantuml.vim index fe5496fc..4d55d809 100644 --- a/ftplugin/plantuml.vim +++ b/ftplugin/plantuml.vim @@ -1,22 +1,17 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'plantuml') == -1 -" Vim plugin file -" Language: PlantUML -" Maintainer: Aaron C. Meadows < language name at shadowguarddev dot com> -" Version: 0.1 - -if exists("b:loaded_plantuml_plugin") +if exists('b:loaded_plantuml_plugin') finish endif let b:loaded_plantuml_plugin = 1 let s:cpo_save = &cpo set cpo&vim -if !exists("g:plantuml_executable_script") - let g:plantuml_executable_script="plantuml" +if !exists('g:plantuml_executable_script') + let g:plantuml_executable_script='plantuml' endif -if exists("loaded_matchit") +if exists('loaded_matchit') let b:match_ignorecase = 0 let b:match_words = \ '\(\\|\\|\\|\\|\\|\\|\\|\\):\:\' . @@ -27,7 +22,7 @@ if exists("loaded_matchit") \ ',\<\while\>:\' endif -let &l:makeprg=g:plantuml_executable_script . " " . fnameescape(expand("%")) +let &l:makeprg=g:plantuml_executable_script . ' ' . fnameescape(expand('%')) setlocal comments=s1:/',mb:',ex:'/,:' commentstring=/'%s'/ formatoptions-=t formatoptions+=croql diff --git a/ftplugin/ps1.vim b/ftplugin/ps1.vim index a88fe019..9a980834 100644 --- a/ftplugin/ps1.vim +++ b/ftplugin/ps1.vim @@ -19,6 +19,8 @@ setlocal formatoptions=tcqro " Enable autocompletion of hyphenated PowerShell commands, " e.g. Get-Content or Get-ADUser setlocal iskeyword+=- +" MS applications (including PowerShell) require a Byte Order Mark (BOM) for UTF-8. +setlocal bomb " Change the browse dialog on Win32 to show mainly PowerShell-related files if has("gui_win32") diff --git a/ftplugin/ps1xml.vim b/ftplugin/ps1xml.vim index 11815d2d..e2616a00 100644 --- a/ftplugin/ps1xml.vim +++ b/ftplugin/ps1xml.vim @@ -16,6 +16,8 @@ let b:did_ftplugin = 1 setlocal tw=0 setlocal commentstring=#%s setlocal formatoptions=tcqro +" MS applications (including PowerShell) require a Byte Order Mark (BOM) for UTF-8. +setlocal bomb " Change the browse dialog on Win32 to show mainly PowerShell-related files if has("gui_win32") diff --git a/ftplugin/ruby.vim b/ftplugin/ruby.vim index 806b21cb..24576de0 100644 --- a/ftplugin/ruby.vim +++ b/ftplugin/ruby.vim @@ -71,7 +71,7 @@ endif function! s:query_path(root) abort let code = "print $:.join %q{,}" - if &shell =~# 'sh' + if &shell =~# 'sh' && empty(&shellxquote) let prefix = 'env PATH='.shellescape($PATH).' ' else let prefix = '' @@ -164,23 +164,23 @@ if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps") nmap '] }, + \ { 'name': 'javascript', 'pairs': [''] }, + \ ] + +for language in s:languages + " Set 'indentexpr' if the user has an indent file installed for the language + if strlen(globpath(&rtp, 'indent/'. language.name .'.vim')) + let language.indentexpr = s:get_indentexpr(language.name) + endif endfor +let s:html_indent = s:get_indentexpr('html') + let b:did_indent = 1 setlocal indentexpr=GetVueIndent() -if exists("*GetVueIndent") +if exists('*GetVueIndent') finish endif function! GetVueIndent() - if searchpair('