diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2017-05-17 11:07:28 +0200 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2017-05-17 11:07:28 +0200 | 
| commit | af870100716f20ee4daef9cc527a9ecf41b54114 (patch) | |
| tree | 0859464c3145682cbfc29ad08de4527dd661abf7 /autoload | |
| parent | ef369d45a505403587ea0bae30ce6768ba51398c (diff) | |
| download | vim-polyglot-af870100716f20ee4daef9cc527a9ecf41b54114.tar.gz vim-polyglot-af870100716f20ee4daef9cc527a9ecf41b54114.zip | |
Update
Diffstat (limited to 'autoload')
| -rw-r--r-- | autoload/elixir/indent.vim | 442 | ||||
| -rw-r--r-- | autoload/elixir/util.vim | 58 | ||||
| -rw-r--r-- | autoload/xml/html5.vim | 9 | 
3 files changed, 307 insertions, 202 deletions
| 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:NO_COLON_AFTER = ':\@!' -let s:ENDING_SYMBOLS = '\]\|}\|)' -let s:ARROW = '->' -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 = '\<fn\>' -let s:MULTILINE_FN = s:FN.'\%(.*end\)\@!' -let s:BLOCK_START = '\%(\<do\>\|'.s:FN.'\)\>' -let s:MULTILINE_BLOCK = '\%(\<do\>'.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*\<from\>.*\<in\>.*,' -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*\)\@<!)') -  end +function! elixir#indent#debug(str) +  if exists("g:elixir_indent_debug") && g:elixir_indent_debug +    echom a:str +  endif  endfunction -function! s:pending_square_brackets(line) -  if a:line.last_non_blank.text !~ s:ARROW -    return elixir#util#count_indentable_symbol_diff(a:line.last_non_blank, '[', ']') +" 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 +    " 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 +      return 1 +    end    end  endfunction -function! s:pending_brackets(line) -  if a:line.last_non_blank.text !~ s:ARROW -    return elixir#util#count_indentable_symbol_diff(a:line.last_non_blank, '{', '}') +" 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 +    if elixir#indent#is_string_or_comment(a:lnum, pos) +      return 0 +    else +      return 1 +    end    end  endfunction -function! elixir#indent#deindent_case_arrow(ind, line) -  if get(b:old_ind, 'arrow', 0) > 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 ':\@<!\<\C\%('.a:expr.'\)\>:\@!' +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 !~ '\<fn\>' -    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\%(\<if\>\|\<case\>\|\<cond\>\|\<try\>\|\<receive\>\|\<fn\>\|{\|\[\|(\)' +  let end_pattern = '\C\%(\<end\>\|\]\|}\|)\)' +  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\%(\<case\>\|\<cond\>\|\<try\>\|\<receive\>\|\<after\>\|\<catch\>\|\<rescue\>\|\<else\>\)' +  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': [      \ [], | 
