diff options
Diffstat (limited to 'autoload')
| -rw-r--r-- | autoload/go/config.vim | 28 | ||||
| -rw-r--r-- | autoload/jsx_pretty/indent.vim | 733 | 
2 files changed, 592 insertions, 169 deletions
| diff --git a/autoload/go/config.vim b/autoload/go/config.vim index ee9a0bb9..f4ec3ccf 100644 --- a/autoload/go/config.vim +++ b/autoload/go/config.vim @@ -463,6 +463,14 @@ function! go#config#HighlightVariableDeclarations() abort    return get(g:, 'go_highlight_variable_declarations', 0)  endfunction +function! go#config#HighlightDiagnosticErrors() abort +  return get(g:, 'go_highlight_diagnostic_errors', 1) +endfunction + +function! go#config#HighlightDiagnosticWarnings() abort +  return get(g:, 'go_highlight_diagnostic_warnings', 1) +endfunction +  function! go#config#HighlightDebug() abort    return get(g:, 'go_highlight_debug', 1)  endfunction @@ -487,6 +495,26 @@ function! go#config#Updatetime() abort    return go_updatetime == 0 ? &updatetime : go_updatetime  endfunction +function! go#config#ReferrersMode() abort +  return get(g:, 'go_referrers_mode', 'gopls') +endfunction + +function! go#config#GoplsCompleteUnimported() abort +  return get(g:, 'go_gopls_complete_unimported', 0) +endfunction + +function! go#config#GoplsDeepCompletion() abort +  return get(g:, 'go_gopls_deep_completion', 1) +endfunction + +function! go#config#GoplsFuzzyMatching() abort +  return get(g:, 'go_gopls_fuzzy_matching', 1) +endfunction + +function! go#config#GoplsUsePlaceholders() abort +  return get(g:, 'go_gopls_use_placeholders', 0) +endfunction +  " Set the default value. A value of "1" is a shortcut for this, for  " compatibility reasons.  if exists("g:go_gorename_prefill") && g:go_gorename_prefill == 1 diff --git a/autoload/jsx_pretty/indent.vim b/autoload/jsx_pretty/indent.vim index 15e177e0..03bdf29b 100644 --- a/autoload/jsx_pretty/indent.vim +++ b/autoload/jsx_pretty/indent.vim @@ -10,209 +10,604 @@ else    endfunction  endif -" Get the syntax group of start of line -function! s:syn_sol(lnum) -  let line = getline(a:lnum) -  let sol = matchstr(line, '^\s*') -  return map(synstack(a:lnum, len(sol) + 1), 'synIDattr(v:val, "name")') +" Regexp for the start tag +let s:start_tag = '<\_s*\%(>\|\${\|\%(\<[-:._$A-Za-z0-9]\+\>\)\)' +" Regexp for the end tag +let s:end_tag = '\%(<\_s*/\_s*\%(\<[-:._$A-Za-z0-9]\+\>\)\_s*>\|/\_s*>\)' + +" Get the syntax stack at the given position +function s:syntax_stack_at(lnum, col) +  return map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")')  endfunction -" Get the syntax group of end of line -function! s:syn_eol(lnum) -  let lnum = prevnonblank(a:lnum) -  let col = strlen(getline(lnum)) -  return map(synstack(lnum, col), 'synIDattr(v:val, "name")') +" Get the syntax at the given position +function s:syntax_at(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name')  endfunction -function! s:prev_indent(lnum) -  let lnum = prevnonblank(a:lnum - 1) -  return indent(lnum) +" Get the start col of the non-space charactor +function s:start_col(lnum) +  return len(matchstr(getline(a:lnum), '^\s*')) + 1  endfunction -function! s:prev_line(lnum) -  let lnum = prevnonblank(a:lnum - 1) -  return substitute(getline(lnum), '^\s*\|\s*$', '', 'g') +" Get the end col of the non-space charactor +function s:end_col(lnum) +  return len(substitute(getline(a:lnum), '\s*$', '', 'g'))  endfunction -function! s:syn_attr_jsx(synattr) -  return a:synattr =~? "^jsx" +" Get the start syntax of a given line number +function s:start_syntax(lnum) +  return s:syntax_at(a:lnum, s:start_col(a:lnum))  endfunction -function! s:syn_xmlish(syns) -  return s:syn_attr_jsx(get(a:syns, -1)) +" Get the end syntax of a given line number +function s:end_syntax(lnum) +  let end_col = len(substitute(getline(a:lnum), '\s*$', '', 'g')) +  return s:syntax_at(a:lnum, end_col)  endfunction -function! s:syn_jsx_element(syns) -  return get(a:syns, -1) =~? 'jsxElement' +" The skip function for searchpair +function s:skip_if_not(current_lnum, ...) +  " Skip the match in current line +  if line('.') == a:current_lnum +    return 1 +  endif + +  let syntax = s:syntax_at(line('.'), col('.')) +  return syntax !~? join(a:000, '\|')  endfunction -function! s:syn_js_comment(syns) -  return get(a:syns, -1) =~? 'Comment$' +" Whether the specified stytax group is an jsx-related syntax +function s:is_jsx(syntax_name) +  return a:syntax_name =~ '^jsx' && a:syntax_name !=? 'jsxEscapeJs'  endfunction -function! s:syn_jsx_escapejs(syns) -  return get(a:syns, -1) =~? '\(\(js\(Template\)\?\|javaScript\(Embed\)\?\|typescript\)Braces\|javascriptTemplateSB\|typescriptInterpolationDelimiter\)' && -        \ (get(a:syns, -2) =~? 'jsxEscapeJs' || -        \ get(a:syns, -3) =~? 'jsxEscapeJs') +" Whether the specified line is start with jsx-related syntax +function s:start_with_jsx(lnum) +  let start_syntax = s:start_syntax(a:lnum) +  return s:is_jsx(start_syntax)  endfunction -function! s:syn_jsx_attrib(syns) -  return len(filter(copy(a:syns), 'v:val =~? "jsxAttrib"')) +" Whether the specified line is end with jsx-related syntax +function s:end_with_jsx(lnum) +  let end_syntax = s:end_syntax(a:lnum) +  return s:is_jsx(end_syntax)  endfunction -let s:start_tag = '<\s*\([-:_\.\$0-9A-Za-z]\+\|>\)' -" match `/end_tag>` and `//>` -let s:end_tag = '/\%(\s*[-:_\.\$0-9A-Za-z]*\s*\|/\)>' -let s:opfirst = '^' . get(g:,'javascript_opfirst', -      \ '\C\%([<>=,.?^%|/&]\|\([-:+]\)\1\@!\|\*\+\|!=\|in\%(stanceof\)\=\>\)') +" Whether the specified line is comment related syntax +function s:is_comment(syntax) +  return a:syntax =~? 'comment' +endfunction -function! jsx_pretty#indent#get(js_indent) -  let lnum = v:lnum -  let line = substitute(getline(lnum), '^\s*\|\s*$', '', 'g') -  let current_syn = s:syn_sol(lnum) -  let current_syn_eol = s:syn_eol(lnum) -  let prev_line_num = prevnonblank(lnum - 1) -  let prev_syn_sol = s:syn_sol(prev_line_num) -  let prev_syn_eol = s:syn_eol(prev_line_num) -  let prev_line = s:prev_line(lnum) -  let prev_ind = s:prev_indent(lnum) - -  if s:syn_xmlish(current_syn) - -    if !s:syn_xmlish(prev_syn_sol) -          \ && !s:syn_jsx_escapejs(prev_syn_sol) -          \ && !s:syn_jsx_escapejs(prev_syn_eol) -          \ && !s:syn_js_comment(prev_syn_sol) -      if line =~ '^/\s*>' || line =~ '^<\s*' . s:end_tag -        return prev_ind -      else -        return prev_ind + s:sw() +" Whether the specified line is embedded comment in jsxTag +function s:is_embedded_comment(lnum) +  let start_col = s:start_col(a:lnum) +  let syntax_stack = s:syntax_stack_at(a:lnum, start_col) +  let last = get(syntax_stack, -1) +  let last_2nd = get(syntax_stack, -2) + +  " Patch code for pangloss/vim-javascript +  " <div +  "   /* hello */ <-- syntax stack is [..., jsxTag, jsComment, jsComment] +  " > +  if last_2nd =~ 'comment' +    let last_2nd = get(syntax_stack, -3) +  endif + +  return last =~? 'comment' && last_2nd =~? 'jsxTag' && +        \ trim(getline(a:lnum)) =~ '\%(^/[*/]\)\|\%(\*/$\)' +endfunction + +" Whether the specified stytax group is the opening tag +function s:is_opening_tag(syntax) +  return a:syntax =~? 'jsxOpenPunct' +endfunction + +" Whether the specified stytax group is the closing tag +function s:is_closing_tag(syntax) +  return a:syntax =~? 'jsxClose' +endfunction + +" Whether the specified stytax group is the jsxAttrib +function s:is_jsx_attr(syntax) +  return a:syntax =~? 'jsxAttrib' +endfunction + +" Whether the specified syntax group is the jsxElement +function s:is_jsx_element(syntax) +  return a:syntax =~? 'jsxElement' +endfunction + +" Whether the specified syntax group is the jsxTag +function s:is_jsx_tag(syntax) +  return a:syntax =~? 'jsxTag' +endfunction + +" Whether the specified syntax group is the jsxBraces +function s:is_jsx_brace(syntax) +  return a:syntax =~? 'jsxBraces' +endfunction + +" Whether the specified syntax group is the jsxComment +function s:is_jsx_comment(syntax) +  return a:syntax =~? 'jsxComment' +endfunction + +" Whether the specified syntax group is the jsxComment +function s:is_jsx_backticks(syntax) +  return a:syntax =~? 'jsxBackticks' +endfunction + +" Get the prvious line number +function s:prev_lnum(lnum) +  return prevnonblank(a:lnum - 1) +endfunction + +" Given a lnum and get the information of its previous line +function s:prev_info(lnum) +  let prev_lnum = s:prev_lnum(a:lnum) +  let prev_start_syntax = s:start_syntax(prev_lnum) +  let prev_end_syntax = s:end_syntax(prev_lnum) + +  return [prev_lnum, prev_start_syntax, prev_end_syntax] +endfunction + +" Get the length difference between syntax stack a and b +function s:syntax_stack_length_compare(lnum_a, col_a, lnum_b, col_b) +  let stack_a = s:syntax_stack_at(a:lnum_a, a:col_a) +  let stack_b = s:syntax_stack_at(a:lnum_b, a:col_b) + +  return len(stack_a) - len(stack_b) +endfunction + +" Determine whether child is a element of parent +function s:is_element_of(parent_lnum, child_lnum) +  let parent_stack = s:syntax_stack_at(a:parent_lnum, s:start_col(a:parent_lnum)) +  let child_stack = s:syntax_stack_at(a:child_lnum, s:start_col(a:child_lnum)) + +  let element_index = len(child_stack) - index(reverse(child_stack), 'jsxElement') +  let rest = parent_stack[element_index:] + +  return index(rest, 'jsxElement') == -1 +endfunction + +" Compute the indention of the opening tag +function s:jsx_indent_opening_tag(lnum) +  let [prev_lnum, prev_start_syntax, prev_end_syntax] = s:prev_info(a:lnum) + +  " If current line is start with > +  if trim(getline(a:lnum)) =~ '^>' +    let pair_line = searchpair('<', '', '>', 'bW', 's:skip_if_not(a:lnum, "jsxOpenPunct", "jsxClose")') +    return indent(pair_line) +  endif + +  " If both the start and the end of the previous line are not jsx-related syntax +  " return ( +  "   <div></div> <-- +  " ) +  if !s:end_with_jsx(prev_lnum) && !s:start_with_jsx(prev_lnum) +    " return -1, so that it will use the default js indent function +    return -1 +  endif + +  " If the end of the previous line is not jsx-related syntax +  " [ +  "   <div></div>, +  "   <div></div> <-- +  " ] +  " should not affect +  " <div +  "   render={() => ( +  "     <div> <-- +  "     </div> +  "   )} +  " > +  " </div> +  " <div> +  "   {items.map(() => ( +  "     <Item /> <-- +  "   ))} +  " </div> +  if !s:end_with_jsx(prev_lnum) &&  +        \ !s:is_jsx_attr(prev_start_syntax) && +        \ !s:is_jsx_brace(prev_start_syntax) +    return indent(prev_lnum) +  endif + +  " If the start of the previous line is not jsx-related syntax +  " return <div> +  "   <div></div> <-- +  " </div> +  if !s:start_with_jsx(prev_lnum) +      return indent(prev_lnum) + s:sw() +    endif +  endif + +  " <div> +  "   <span> +  "   </span> +  "   <div> <-- +  "   </div> +  " </div> +  if s:is_closing_tag(prev_start_syntax) +    return indent(prev_lnum) +  endif + +  " If the previous line is end with a closing tag +  " <div> +  "   <br /> +  "   <div></div> <-- +  " </div> +  " should not affect case like +  " <div><br /> +  "   <span> <-- +  " </div> +  if s:is_closing_tag(prev_end_syntax) && +        \ s:syntax_stack_length_compare( +        \   prev_lnum, s:start_col(prev_lnum), prev_lnum, s:end_col(prev_lnum)) == 2 +    return indent(prev_lnum) +  endif + +  " If the start of the previous line is the jsxElement +  " <div> +  "   hello +  "   <div></div> <-- +  " </div> +  if s:is_jsx_element(prev_start_syntax) || +        \ s:is_jsx_comment(prev_start_syntax) +    return indent(prev_lnum) +  endif + +  " If the start of the prvious line is the jsxBraces { +  " <div> +  "   {foo} +  "   <div></div> <-- +  " </div> +  " should not affect case like +  " <div> +  "   { +  "     <div></div> <-- +  "   } +  " </div> +  if s:is_jsx_brace(prev_start_syntax) && +        \ trim(getline(prev_lnum)) =~ '^[$]\?{' && +        \ s:syntax_stack_length_compare( +        \ prev_lnum, s:start_col(prev_lnum), a:lnum, s:start_col(a:lnum)) == -2 +    return indent(prev_lnum) +  endif + +  " If the start of the prvious line is the jsxBraces } +  " <div> +  "   { +  "     foo +  "   } +  "   <div></div> <-- +  " </div> +  if s:is_jsx_brace(prev_start_syntax) && +        \ trim(getline(prev_lnum)) =~ '}' && +        \ s:syntax_stack_length_compare( +        \ prev_lnum, s:start_col(prev_lnum), a:lnum, s:start_col(a:lnum)) == -3 +    return indent(prev_lnum) +  endif + +  " Otherwise, indent s:sw() spaces +  return indent(prev_lnum) + s:sw() +endfunction + +" Compute the indention of the closing tag +function s:jsx_indent_closing_tag(lnum) +  let pair_line = searchpair(s:start_tag, '', s:end_tag, 'bW', 's:skip_if_not(a:lnum, "jsxOpenPunct", "jsxClose")') +  return pair_line ? indent(pair_line) : indent(a:lnum) +endfunction + +" Compute the indention of the jsxAttrib +function s:jsx_indent_attr(lnum) +  let [prev_lnum, prev_start_syntax, prev_end_syntax] = s:prev_info(a:lnum) + +  " If the start of the previous line is not jsx-related syntax +  " return <div +  "   attr="hello" <-- +  " > +  " should not affect +  " <div +  "   // comment here +  "   attr="hello" +  " > +  " </div> +  if !s:start_with_jsx(prev_lnum) && +        \ !s:is_comment(prev_start_syntax) +    return indent(prev_lnum) + s:sw() +  endif + +  " If the start of the previous line is the opening tag +  " <div +  "   title="title" <-- +  " > +  if s:is_opening_tag(prev_start_syntax) +    return indent(prev_lnum) + s:sw() +  endif + +  " Otherwise, align the attribute with its previous line +  return indent(prev_lnum) +endfunction + +" Compute the indentation of the jsxElement +function s:jsx_indent_element(lnum) +  let [prev_lnum, prev_start_syntax, prev_end_syntax] = s:prev_info(a:lnum) + +  " Fix test case like +  " <div|> <-- press enter +  " should indent as +  " <div +  " > <-- +  if trim(getline(a:lnum)) =~ '^>' && !s:is_opening_tag(prev_end_syntax) +    return indent(prev_lnum) +  endif + +  " If the start of the previous line is start with > +  " <div +  "   attr="foo" +  " > +  "   text <-- +  " </div> +  if s:is_opening_tag(prev_start_syntax) && +        \ trim(getline(prev_lnum)) =~ '^>$' +    return indent(prev_lnum) + s:sw() +  endif + +  " <div> +  "   text <-- +  " </div> +  " should not affect case like +  " <div> +  "   <br /> +  "   hello <-- +  " </div> +  if s:is_opening_tag(prev_start_syntax) && +        \ s:is_element_of(prev_lnum, a:lnum) +    return indent(prev_lnum) + s:sw() +  endif + +  " return <div> +  "   text <-- +  " </div> +  if !s:start_with_jsx(prev_lnum) +    return indent(prev_lnum) + s:sw() +  endif + +  " Otherwise, align with the previous line +  " <div> +  "   {foo} +  "   text <-- +  " </div> +  return indent(prev_lnum) +endfunction + +" Compute the indentation of jsxBraces +function s:jsx_indent_brace(lnum) +  let [prev_lnum, prev_start_syntax, prev_end_syntax] = s:prev_info(a:lnum) +   +  " If the start of the previous line is start with > +  " <div +  "   attr="foo" +  " > +  "   {foo} <-- +  " </div> +  if s:is_opening_tag(prev_start_syntax) && +        \ trim(getline(prev_lnum)) =~ '^>$' +    return indent(prev_lnum) + s:sw() +  endif + +  " <div> +  "   {foo} <-- +  " </div> +  " should not affect case like +  " <div> +  "   <br /> +  "   {foo} <-- +  "   text +  "   {foo} <-- +  " </div> +  if s:is_opening_tag(prev_start_syntax) && +        \ s:syntax_stack_length_compare( +        \ prev_lnum, s:start_col(prev_lnum), a:lnum, s:start_col(a:lnum)) == 1 +    return indent(prev_lnum) + s:sw() +  endif + +  " If current line is the close brace } +  if trim(getline(a:lnum)) =~ '^}' +    let pair_line = searchpair('{', '', '}', 'bW', 's:skip_if_not(a:lnum, "jsxBraces")') +    return indent(pair_line) +  endif + +  " return <div> +  "   {foo} <-- +  " </div> +  " should not affect +  " <div +  "   // js comment +  "   {...props} <-- +  " > +  " </div> +  if !s:start_with_jsx(prev_lnum) && +        \ !s:is_comment(prev_start_syntax) +    return indent(prev_lnum) + s:sw() +  endif +   +  return indent(prev_lnum) +endfunction + +" Compute the indentation of the comment +function s:jsx_indent_comment(lnum) +  let [prev_lnum, prev_start_syntax, prev_end_syntax] = s:prev_info(a:lnum) + +  " If current line is jsxComment +  if s:is_jsx_comment(s:start_syntax(a:lnum)) +    let line = trim(getline(a:lnum)) +    if line =~ '^<!--' +      " Patch code for yajs.vim +      " ${logs.map(log => html` +      "   <${Log} class="log" ...${log} /> +      " `)} <-- The backtick here is Highlighted as javascriptTemplate +      " <!-- <-- Correct the indentation here +      if !s:start_with_jsx(prev_lnum) && s:end_with_jsx(prev_lnum) +        return indent(prev_lnum)        endif -    elseif !s:syn_xmlish(prev_syn_sol) && !s:syn_js_comment(prev_syn_sol) && s:syn_jsx_attrib(current_syn) -      " For #79 -      return prev_ind + s:sw() -    " { -    "   <div></div> -    " ##} <-- -    elseif s:syn_jsx_element(current_syn) && line =~ '}$' -      let pair_line = searchpair('{', '', '}', 'b') + +      " Return the element indent for the opening comment +      return s:jsx_indent_element(a:lnum) +    elseif line =~ '^-->' +      " Return the paired indent for the closing comment +      let pair_line = searchpair('<!--', '', '-->', 'bW')        return indent(pair_line) -    elseif line =~ '^-->$' -      if prev_line =~ '^<!--' -        return prev_ind -      else -        return prev_ind - s:sw() -      endif -    elseif prev_line =~ '-->$' -      return prev_ind -    " close tag </tag> or /> including </> -    elseif prev_line =~ s:end_tag . '$' -      if line =~ '^<\s*' . s:end_tag -        return prev_ind - s:sw() -      elseif s:syn_jsx_attrib(prev_syn_sol) -        return prev_ind - s:sw() -      else -        return prev_ind -      endif -    elseif line =~ '^\(>\|/\s*>\)' -      if prev_line =~ '^<' -        return prev_ind -      else -        return prev_ind - s:sw() -      endif -    elseif prev_line =~ '^\(<\|>\)' && -          \ (s:syn_xmlish(prev_syn_eol) || s:syn_js_comment(prev_syn_eol)) -      if line =~ '^<\s*' . s:end_tag -        return prev_ind -      else -        return prev_ind + s:sw() -      endif -    elseif line =~ '^<\s*' . s:end_tag -      if !s:syn_xmlish(prev_syn_sol)  -        if s:syn_jsx_escapejs(prev_syn_eol) -              \ || s:syn_jsx_escapejs(prev_syn_sol) -          return prev_ind - s:sw() -        else -          return prev_ind -        endif -      elseif prev_line =~ '^\<return' -        return prev_ind -      else -        return prev_ind - s:sw() -      endif -    elseif !s:syn_xmlish(prev_syn_eol) -      if prev_line =~ '\(&&\|||\|=>\|[([{]\|`\)$' -        " <div> -        "   { -        "   } -        " </div> -        if line =~ '^[)\]}]' -          return prev_ind -        else -          return prev_ind + s:sw() -        endif -      else -        return prev_ind -      endif      else -      return prev_ind -    endif -  elseif s:syn_jsx_escapejs(current_syn) -    if line =~ '^}' -      let char = getline('.')[col('.') - 1] -      " When pressing enter after the }, keep the indent -      if char != '}' && search('}', 'b', lnum) -        return indent(lnum) -      else -        let pair_line = searchpair('{', '', '}', 'bW') -        return indent(pair_line) -      endif -    elseif line =~ '^{' || line =~ '^\${' -      if s:syn_jsx_escapejs(prev_syn_eol) -            \ || s:syn_jsx_attrib(prev_syn_sol) -        return prev_ind -      elseif s:syn_xmlish(prev_syn_eol) && (prev_line =~ s:end_tag || prev_line =~ '-->$') -        return prev_ind +      if trim(getline(prev_lnum)) =~ '^<!--' +        " <!-- +        "   comment <-- +        " --> +        return indent(prev_lnum) + s:sw()        else -        return prev_ind + s:sw() +        " <!-- +        "   comment +        "   comment <-- +        " --> +        return indent(prev_lnum)        endif      endif -  elseif line =~ '^`' && s:syn_jsx_escapejs(current_syn_eol) -    " For `} of template syntax -    let pair_line = searchpair('{', '', '}', 'bW') -    return indent(pair_line) -  elseif line =~ '^/[/*]' " js comment in jsx tag -    if get(prev_syn_sol, -1) =~ 'Punct' -      return prev_ind + s:sw() -    elseif synIDattr(synID(lnum - 1, 1, 1), 'name') =~ 'jsxTag' -      return prev_ind -    else -      return a:js_indent() +  endif + +  " For comment inside the jsxTag +  if s:is_opening_tag(prev_start_syntax) +    return indent(prev_lnum) + s:sw() +  endif + +  if trim(getline(a:lnum)) =~ '\*/$' +    let pair_line = searchpair('/\*', '', '\*/', 'bW', 's:skip_if_not(a:lnum)') +    return indent(pair_line) + 1 +  endif +   +  return indent(prev_lnum) +endfunction + +function s:jsx_indent_backticks(lnum) +  let tags = get(g:, 'vim_jsx_pretty_template_tags', ['html', 'jsx']) +  let start_tag = '\%(' . join(tags, '\|') . '\)`' +  let end_tag = '\%(' . join(tags, '\|') . '\)\@<!`' +  let pair_line = searchpair(start_tag, '', end_tag, 'bW', 's:skip_if_not(a:lnum)') + +  return indent(pair_line) +endfunction + +" Compute the indentation for the jsx-related element +function s:jsx_indent(lnum) +  let start_syntax = s:start_syntax(a:lnum) + +  if s:is_opening_tag(start_syntax) +    return s:jsx_indent_opening_tag(a:lnum) +  elseif s:is_closing_tag(start_syntax) +    return s:jsx_indent_closing_tag(a:lnum) +  elseif s:is_jsx_attr(start_syntax) +    return s:jsx_indent_attr(a:lnum) +  elseif s:is_jsx_element(start_syntax) +    return s:jsx_indent_element(a:lnum) +  elseif s:is_jsx_brace(start_syntax) +    return s:jsx_indent_brace(a:lnum) +  elseif s:is_jsx_comment(start_syntax) +    return s:jsx_indent_comment(a:lnum) +  elseif s:is_jsx_backticks(start_syntax) +    return s:jsx_indent_backticks(a:lnum) +  endif + +  return -1 +endfunction + +" Return the jsx context of the specified line  +function s:jsx_context(lnum) +  if !s:end_with_jsx(prev_lnum) +    return 'non-jsx' +  endif + +  let prev_lnum = s:prev_lnum(a:lnum) +  let start_syntax = s:start_syntax(prev_lnum) +  let end_col = s:end_col(prev_lnum) +  let end_syntax_stack = s:syntax_stack_at(prev_lnum, end_col) +  let reversed = reverse(end_syntax_stack) + +  for item in reversed +    if item =~? 'jsxEscapeJs' +      return 'unknown' +    elseif s:is_jsx_element(item) && s:is_jsx(start_syntax) && start_syntax !~? 'jsxEscapeJs' +      " <div> +      "   <br /> <-- press o +      " </div> +      " -------------------- +      " <div> +      " { +      "     a > 0 ? 1 <div>|</div> <-- press enter +      " } +      " </div> +      return 'jsxElement' +    elseif s:is_jsx_tag(item) +      return 'jsxTag' +    elseif s:is_jsx_brace(item) && trim(getline(prev_lnum)) =~ '{$' +      return 'jsxBraces'      endif +  endfor + +  return 'unknown' +endfunction + +function! jsx_pretty#indent#get(js_indent) +  " The start column index of the current line (one-based) +  let start_col = s:start_col(v:lnum) +  " The end column index of the current line (one-based) +  let end_col = s:end_col(v:lnum) + +  if s:start_with_jsx(v:lnum) +    let ind = s:jsx_indent(v:lnum) +    return ind == -1 ? a:js_indent() : ind +  elseif s:is_embedded_comment(v:lnum) +    return s:jsx_indent_comment(v:lnum)    else -    let ind = a:js_indent() - -    " Issue #68 -    " return (<div> -    " |<div>) -    if (line =~ '^/\s*>' || line =~ '^<\s*' . s:end_tag) -          \ && !s:syn_xmlish(prev_syn_sol) -      return prev_ind +    let line = trim(getline(v:lnum)) +    let prev_lnum = s:prev_lnum(v:lnum) + +    " Fix the case where pressing enter at the cursor +    " return <div>|</div> +    if line =~ '^' . s:end_tag && +          \ s:end_with_jsx(s:prev_lnum(v:lnum)) +      return s:jsx_indent_closing_tag(v:lnum)      endif -    " If current syntax is not a jsx syntax group -    if s:syn_xmlish(prev_syn_eol) && line !~ '^[)\]}]' -      let sol = matchstr(line, s:opfirst) -      if sol is '' -        " Fix javascript continue indent -        return ind - s:sw() -      else -        return ind +    " Fix cases for the new line +    if empty(line) +      let context = s:jsx_context(v:lnum) + +      if context == 'jsxElement' +        " <div> <-- press o +        " </div> +        return s:jsx_indent_element(v:lnum) +      elseif context == 'jsxTag' +        " <div <-- press o +        " > +        " </div> +        " ----------------------- +        " <div +        "   attr="attr" <-- press o +        " > +        " </div> +        return s:jsx_indent_attr(v:lnum) +      elseif context == 'jsxBraces' +        " <div> +        "   { <-- press o +        "   } +        " </div> +        return indent(prev_lnum) + s:sw()        endif      endif -    return ind -  endif +    return a:js_indent() +  endif  endfunction  endif | 
