From af870100716f20ee4daef9cc527a9ecf41b54114 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 17 May 2017 11:07:28 +0200 Subject: [PATCH] Update --- after/ftplugin/terraform.vim | 33 +++ after/syntax/yaml.vim | 4 +- autoload/elixir/indent.vim | 536 ++++++++++++++++++++++------------- 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 | 43 +-- ftplugin/vue.vim | 7 + indent/ansible.vim | 5 + indent/elixir.vim | 123 +++----- indent/haskell.vim | 88 +++--- indent/javascript.vim | 264 +++++++++++------ 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 | 312 ++++++++++++++------ syntax/pug.vim | 5 +- syntax/ruby.vim | 12 +- syntax/swift.vim | 9 +- syntax/terraform.vim | 62 ++++ syntax/tmux.vim | 16 +- syntax/vue.vim | 119 +++----- 38 files changed, 1250 insertions(+), 845 deletions(-) diff --git a/after/ftplugin/terraform.vim b/after/ftplugin/terraform.vim index 17115b1..add0944 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 78983cc..d429da6 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 b6df3b5..fd2f4a3 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 +" Returns 0 or 1 based on whether or not the text starts with the given +" expression and is not a string or comment +function! elixir#indent#starts_with(text, expr, lnum) + let pos = match(a:text, '^\s*'.a:expr) + if pos == -1 + return 0 else - return a:ind - end -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 -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 - \ ) - - return indent(bslnum) - else - return a:ind - 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) - - 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 - else - return a:ind - end -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 - end - end - - return a:ind -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 - else - return a:ind - end -endfunction - -function! elixir#indent#indent_brackets(ind, line) - if s:pending_brackets(a:line) > 0 - return a:ind + &sw - else - return a:ind - end -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 - else - return a:ind - end -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 - else - return a:ind - end -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 - else - return a:ind - 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, '(') - else - return a:ind - end -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) - else - return a:ind - end -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) - else - return a:ind - 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 + " NOTE: @jbodah 2017-02-24: pos is the index of the match which is + " zero-indexed. Add one to make it the column number + if elixir#indent#is_string_or_comment(a:lnum, pos + 1) + return 0 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 1 end - else - return a:ind end endfunction -function! elixir#indent#indent_ecto_queries(ind, line) - if a:line.last_non_blank.text =~ s:QUERY_FROM - return a:ind + &sw +" Returns 0 or 1 based on whether or not the text ends with the given +" expression and is not a string or comment +function! elixir#indent#ends_with(text, expr, lnum) + let pos = match(a:text, a:expr.'\s*$') + if pos == -1 + return 0 else - return a:ind + if elixir#indent#is_string_or_comment(a:lnum, pos) + return 0 + else + return 1 + end end endfunction +" 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 + +" 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 + +" 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 + +" 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 -1 + end +endfunction + +" 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 + +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 -1 + endif +endfunction + +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 + else + return -1 + endif +endfunction + +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#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 -1 + endif +endfunction + +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 -1 + endif +endfunction + +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 -1 + endif +endfunction + +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 -1 + endif +endfunction + +" 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 -1 + end +endfunction + +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 -1 + endif +endfunction + +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 -1 + endif +endfunction + +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 -1 + end +endfunction + +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 + return indent(a:prev_nb_lnum) + end + else + return -1 + endif +endfunction + +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 -1 + endif +endfunction + endif diff --git a/autoload/elixir/util.vim b/autoload/elixir/util.vim index fbbd62a..46db20e 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 + " remove any trailing characters that don't look like a nested module + let word = substitute(word,'\.\U.*$','','g') -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 + " replace module dots with slash + let word = substitute(word,'\.','/','g') -function! s:match_count(line, pattern) - let size = strlen(a:line.text) - let index = 0 - let counter = 0 + " remove any special chars + let word = substitute(word,'[^A-z0-9-_/]','','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 + " 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 counter -endfunction - -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 73b24a4..982fe29 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 95e3953..123d9d1 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 3b130f1..3ed1472 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 f4bd7e9..7f1f385 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 eb6f655..a4721f9 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 807d066..651cfba 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 fe5496f..4d55d80 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 a88fe01..9a98083 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 11815d2..e2616a0 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 806b21c..24576de 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('