From 6325830fe40e2250049c96f5003913fa99d3ace1 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sat, 15 Sep 2018 16:14:40 -0400 Subject: [PATCH 01/12] Don't skip indent delta for the line that closes a litHtml region --- after/indent/javascript.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 4f0124f..337508a 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -336,6 +336,7 @@ fu! s:StateClass.getIndentOfLastClose() dict let l:closeWords = s:getCloseWordsLeftToRight(self.prevLine) if (len(l:closeWords) == 0) + call VHTL_debug('no close words found') return -1 endif @@ -404,8 +405,8 @@ fu! ComputeLitHtmlIndent() " let l:indent_delta = -1 for starting with closing tag, template, or expression let l:indent_basis = l:state.getIndentOfLastClose() if (l:indent_basis == -1) - call VHTL_debug("default to html indent because base indent not found") - return HtmlIndent() + call VHTL_debug("using html indent as base indent") + let l:indent_basis = HtmlIndent() endif let l:indent_delta = l:state.getIndentDelta() call VHTL_debug('indent delta ' . l:indent_delta) From 1bd7b0701ba9b0bfc9c927d728bf8ee1348a3122 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 21 Oct 2018 11:16:25 -0400 Subject: [PATCH 02/12] Improve debug logging --- after/indent/javascript.vim | 40 +++++++++++++++++-------------------- test/minimalvimrc | 1 + 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 337508a..830a734 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -183,13 +183,11 @@ endfunction if exists('g:VHTL_debugging') set debug=msg " show errors in indentexpr - fu! SynAt(l,c) - return s:SynAt(a:l,a:c) - endfu endif -fu! VHTL_debug(str) +" Make debug log. You can view these logs using ':messages' +fu! s:debug(str) if exists('g:VHTL_debugging') - echom a:str + echom 'vhtl ' . v:lnum . ': ' . a:str endif endfu @@ -246,6 +244,7 @@ fu! s:StateClass.isHtml() dict return get(self.currSynstack, -1) =~# '^html' endfu fu! s:StateClass.isLitHtmlRegionCloser() dict + " TODO this doesn't accoutn for semicolons or trailing spaces? return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*`' endfu fu! s:StateClass.wasJs() dict @@ -320,11 +319,11 @@ fu! s:StateClass.getIndentDelta() dict let [l:closeWord, l:col] = l:closeWords[0] let l:syntax = s:SynAt(self.currLine, l:col) if (l:syntax == 'htmlEndTag') - call VHTL_debug('indent_delta: html end tag') + call s:debug('indent_delta: html end tag') return - &shiftwidth endif if (l:syntax == 'litHtmlRegion' && 'html`' != strpart(getline(self.currLine), l:col-5, len('html`'))) - call VHTL_debug('indent_delta: end of litHtmlRegion') + call s:debug('indent_delta: end of litHtmlRegion') return - &shiftwidth endif return 0 @@ -336,7 +335,7 @@ fu! s:StateClass.getIndentOfLastClose() dict let l:closeWords = s:getCloseWordsLeftToRight(self.prevLine) if (len(l:closeWords) == 0) - call VHTL_debug('no close words found') + call s:debug('no close words found') return -1 endif @@ -347,16 +346,16 @@ fu! s:StateClass.getIndentOfLastClose() dict redraw if ("}" == l:closeWord && l:syntax == 'jsTemplateBraces') call searchpair('{', '', '}', 'b', 's:SkipFuncJsTemplateBraces()') - call VHTL_debug('js brace base indent') + call s:debug('js brace base indent') elseif ("`" == l:closeWord && l:syntax == 'litHtmlRegion') call searchpair('html`', '', '\(html\)\@', '', '') call searchpair(l:openWord, '', l:closeWord, 'b') - call VHTL_debug('html tag region base indent ') + call s:debug('html tag region base indent ') else - call VHTL_debug("UNRECOGNIZED CLOSER SYNTAX: '" . l:syntax . "'") + call s:debug("UNRECOGNIZED CLOSER SYNTAX: '" . l:syntax . "'") endif return indent(line('.')) " cursor was moved by searchpair() endfor @@ -374,11 +373,8 @@ fu! ComputeLitHtmlIndent() " get most recent non-empty line let l:prev_lnum = prevnonblank(v:lnum - 1) - let l:currLineSynstack = VHTL_SynSOL(v:lnum) - let l:prevLineSynstack = VHTL_SynEOL(l:prev_lnum) - if (!l:state.isInsideLitHtml() && !l:state.wasInsideLitHtml()) - call VHTL_debug('outside of litHtmlRegion: ' . b:litHtmlOriginalIndentExpression) + call s:debug('outside of litHtmlRegion: ' . b:litHtmlOriginalIndentExpression) if (exists('b:hi_indent') && has_key(b:hi_indent, 'blocklnr')) call remove(b:hi_indent, 'blocklnr') @@ -391,12 +387,12 @@ fu! ComputeLitHtmlIndent() endif if (l:state.openedLitHtmlTemplate()) - call VHTL_debug('opened tagged template literal') + call s:debug('opened tagged template literal') return indent(l:prev_lnum) + &shiftwidth endif if (l:state.openedJsExpression()) - call VHTL_debug('opened js expression') + call s:debug('opened js expression') return indent(l:prev_lnum) + &shiftwidth endif @@ -405,12 +401,12 @@ fu! ComputeLitHtmlIndent() " let l:indent_delta = -1 for starting with closing tag, template, or expression let l:indent_basis = l:state.getIndentOfLastClose() if (l:indent_basis == -1) - call VHTL_debug("using html indent as base indent") + call s:debug("using html indent as base indent") let l:indent_basis = HtmlIndent() endif let l:indent_delta = l:state.getIndentDelta() - call VHTL_debug('indent delta ' . l:indent_delta) - call VHTL_debug('indent basis ' . l:indent_basis) + call s:debug('indent delta ' . l:indent_delta) + call s:debug('indent basis ' . l:indent_basis) return l:indent_basis + l:indent_delta endif @@ -418,6 +414,6 @@ fu! ComputeLitHtmlIndent() return eval(b:litHtmlOriginalIndentExpression) endif - call VHTL_debug('default to html indent') + call s:debug('default to html indent') return HtmlIndent() endfu diff --git a/test/minimalvimrc b/test/minimalvimrc index 6d506e0..f9ac15d 100644 --- a/test/minimalvimrc +++ b/test/minimalvimrc @@ -5,4 +5,5 @@ call plug#begin('~/.vim/plugged') Plug 'pangloss/vim-javascript' call plug#end() syntax enable +let g:VHTL_debugging = 1 let g:html_indent_style1 = "inc" From 69705681fcd225027d690715e8518d4460bdc661 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 21 Oct 2018 12:04:36 -0400 Subject: [PATCH 03/12] Fix incorrect param --- after/indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 830a734..7470b8e 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -39,7 +39,7 @@ let s:endtag = '^\s*\/\?>\s*;\=' " Get syntax stack at StartOfLine fu! VHTL_SynSOL(lnum) - let l:col = match(getline(line('.')), '\S') + let l:col = match(getline(a:lnum), '\S') if (l:col == -1) return [] endif From 152d6497c0687614e7367e00ecd56603667ff272 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 21 Oct 2018 19:42:52 -0400 Subject: [PATCH 04/12] Parameterize state constructor --- after/indent/javascript.vim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 7470b8e..50b8c0b 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -192,10 +192,10 @@ fu! s:debug(str) endfu let s:StateClass={} -fu! s:StateClass.new() +fu! s:StateClass.new(lnum) let l:instance = copy(self) - let l:instance.currLine = v:lnum - let l:instance.prevLine = prevnonblank(v:lnum - 1) + let l:instance.currLine = a:lnum + let l:instance.prevLine = prevnonblank(a:lnum - 1) let l:instance.currSynstack = VHTL_SynSOL(l:instance.currLine) let l:instance.prevSynstack = VHTL_SynEOL(l:instance.prevLine) return l:instance @@ -368,7 +368,7 @@ endfu fu! ComputeLitHtmlIndent() let s:synid_cache = [[],[]] - let l:state = s:StateClass.new() + let l:state = s:StateClass.new(v:lnum) " get most recent non-empty line let l:prev_lnum = prevnonblank(v:lnum - 1) From ad85ef8708b67c515770c6adf6e0917854b81020 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Wed, 21 Nov 2018 19:23:17 -0500 Subject: [PATCH 05/12] Delete old test files in order to start fresh --- test/lit-html.vader | 287 ------------------------------------- test/random-examples.vader | 91 ------------ 2 files changed, 378 deletions(-) delete mode 100644 test/lit-html.vader delete mode 100644 test/random-examples.vader diff --git a/test/lit-html.vader b/test/lit-html.vader deleted file mode 100644 index 16e1086..0000000 --- a/test/lit-html.vader +++ /dev/null @@ -1,287 +0,0 @@ -Before: - set tabstop=2 - set shiftwidth=2 - set expandtab - -Given javascript (html in html); -html` -
-
-
-`; - -Do: - =G - -Expect javascript; -html` -
-
-
-`; - -Given javascript (close template and tag); - html` -
- ${when(condition, html` - `)} -
`; - js(); - -Do: - =G - -Expect javascript; -html` -
- ${when(condition, html` - `)} -
`; -js(); - -Given javascript (text line inside xml); -html` -
- simple text -
- `; - -Do: - =G - -Expect javascript; -html` -
- simple text -
-`; - -Given javascript (sparse text lines inside xml): - html` -
- - text one - - text two - -
- ` - -Do: - =G - -Expect javascript: - html` -
- - text one - - text two - -
- ` - -Given javascript (nested css); - html` - -
- -
- ` - -Do: - =G - -Expect javascript; -html` - -
- -
-` - -Given javascript (lit-html readme example 1); -const render = () => html` -${when(state === 'loading', -html`
Loading...
`, -html`

${message}

`)} -`; - -Do: - =G - -Expect javascript; -const render = () => html` - ${when(state === 'loading', - html`
Loading...
`, - html`

${message}

`)} -`; - -Given javascript (lit-html readme example 2); -const render = () => html` -
    -${repeat(items, (i) => i.id, (i, index) => html` -
  • ${index}: ${i.name}
  • `)} -
-`; - -Do: - =G - -Expect javascript; -const render = () => html` -
    - ${repeat(items, (i) => i.id, (i, index) => html` -
  • ${index}: ${i.name}
  • `)} -
-`; - -Given javascript (lit-html readme example 3); -const render = () => html` -

-${until( -fetch('content.txt').then((r) => r.text()), -html`Loading...`)} -

-`; - -Do: - =G - -Expect javascript; -const render = () => html` -

- ${until( - fetch('content.txt').then((r) => r.text()), - html`Loading...`)} -

-`; - - -Given javascript (nuances with closing brackets and templates): - html` - ${repeat(items, (i) => i.id, (i, index) => html` -
  • ${index}: ${i.name}
  • `)} -
    DEDENT THIS LINE ONCE
    -
    -
    as usual
    - ${this.ternary ? html` -
    indented
    - ` : html` -
    also indented
    - `} -
    DO NOT DEDENT THIS LINE
    -
    - ` - -Do: - =G - -Expect javascript: - html` - ${repeat(items, (i) => i.id, (i, index) => html` -
  • ${index}: ${i.name}
  • `)} -
    DEDENT THIS LINE ONCE
    -
    -
    as usual
    - ${this.ternary ? html` -
    indented
    - ` : html` -
    also indented
    - `} -
    DO NOT DEDENT THIS LINE
    -
    - ` - -Given javascript (adjacent js expressions): - html` - ${console.log(null)} - ${console.log('this line should have equal indentation')} - ` -Do: - =G - -Expect javascript: - html` - ${console.log(null)} - ${console.log('this line should have equal indentation')} - ` - -Given javascript(multiple dedents after closing js expression): - html` -
    - ${ test - ? html`

    one

    ` - : html` -

    - two -

    `} -
    - dedent THRICE here - `; - -Do: - =G - -Expect javascript: - html` -
    - ${ test - ? html`

    one

    ` - : html` -

    - two -

    `} -
    - dedent THRICE here - `; - -" " This test fails because vim-javascript doesn't correctly indent ternaries inside ${ } -" Given javascript (subsequent templates): -" html` -" ${user.isloggedIn -" ? html`Welcome ${user.name}` -" : html`Please log in` -" } -" `; -" html` -"
      -" ${items.map((i) => html`
    • ${i}
    • `)} -"
    -" `; -" -" Do: -" =G -" -" Expect javascript: -" html` -" ${user.isloggedIn -" ? html`Welcome ${user.name}` -" : html`Please log in` -" } -" `; -" html` -"
      -" ${items.map((i) => html`
    • ${i}
    • `)} -"
    -" `; diff --git a/test/random-examples.vader b/test/random-examples.vader deleted file mode 100644 index 8f2f357..0000000 --- a/test/random-examples.vader +++ /dev/null @@ -1,91 +0,0 @@ -Before: - set tabstop=2 - set shiftwidth=2 - set expandtab - -Given javascript (multiple syntaxes on one line); -return html` - Web Components are - ${mood}!`; - -Do: - =G - -Expect javascript; -return html` - Web Components are - ${mood}!`; - -Given javascript (tricky indnetation); -return html` -
    Files
    - ${!this.fileList ? - html` - this.onFetchBtn()}> - fetch notes - - ` : html` - this.onFetchBtn()}> - refresh - - ${repeat(this.fileList || [], null, (file) => html` - this.onFileClick(file.path)} data="${file}">${file.name} - `)} - `} - - this.onNewFileClick()}> -`; - -Do: - =G - -Expect javascript; -return html` -
    Files
    - ${!this.fileList ? - html` - this.onFetchBtn()}> - fetch notes - - ` : html` - this.onFetchBtn()}> - refresh - - ${repeat(this.fileList || [], null, (file) => html` - this.onFileClick(file.path)} data="${file}">${file.name} - `)} - `} - - this.onNewFileClick()}> -`; - - - -Given javascript (commented template): - // normal comment - // html` - //
    - // `; - -Do: - =G - -Expect javascript: - // normal comment - // html` - //
    - // `; From e510d2da44c95aeac33c8d583cbe90823b59a7db Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Fri, 23 Nov 2018 08:57:21 -0500 Subject: [PATCH 06/12] Write some basic tests and fix issues so they pass Additionally improve test runner so it accepts the CI environment variable Addresses #10 --- after/indent/javascript.vim | 65 ++++++++++++----------- test/indent/html-string-literal-end.vader | 56 +++++++++++++++++++ test/runtests | 7 ++- 3 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 test/indent/html-string-literal-end.vader diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 50b8c0b..83b232a 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -86,21 +86,6 @@ fu! IsSynstackInsideJsx(synstack) return v:false endfu -fu! VHTL_closesJsExpression(str) - return (VHTL_getBracketDepthChange(a:str) < 0) -endfu -fu! VHTL_getBracketDepthChange(str) - let l:depth=0 - for l:char in split(a:str, '\zs') - if (l:char ==# '{') - let l:depth += 1 - elseif (l:char ==# '}') - let l:depth -=1 - endif - endfor - return l:depth -endfu - fu! VHTL_startsWithTemplateEnd(linenum) return (getline(a:linenum)) =~# '^\s*`' endfu @@ -205,12 +190,6 @@ fu! s:StateClass.startsWithTemplateClose() dict return (getline(self.currSynstack)) =~# '^\s*`' endfu -fu! s:StateClass.closedJsExpression() dict - return VHTL_closesJsExpression(getline(self.prevLine)) -endfu -fu! s:StateClass.closesJsExpression() dict - return VHTL_closesJsExpression(getline(self.currLine)) -endfu fu! s:StateClass.openedJsExpression() dict return (VHTL_getBracketDepthChange(getline(self.prevLine)) > 0) endfu @@ -247,17 +226,33 @@ fu! s:StateClass.isLitHtmlRegionCloser() dict " TODO this doesn't accoutn for semicolons or trailing spaces? return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*`' endfu +fu! s:StateClass.opensTemplate() dict + return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*html`' +endfu fu! s:StateClass.wasJs() dict - return get(self.prevSynstack, -1) =~# '^js' + call s:debug(string(get(self.prevSynstack, -1))) + return get(self.prevSynstack, -1) =~# '^js' || get(self.prevSynstack, -1) =~# '^javaScript' endfu -fu! s:StateClass.isJsTemplateBrace() dict - return get(self.currSynstack, -1) ==# 'jsTemplateBraces' +fu! s:StateClass.isJs() dict + return get(self.currSynstack, -1) =~# '^js' || get(self.currSynstack, -1) =~# '^javaScript' endfu -fu! s:StateClass.wasJsTemplateBrace() dict +fu! s:StateClass.wasExpressionBracket() dict return get(self.prevSynstack, -1) ==# 'jsTemplateBraces' endfu -fu! s:StateClass.isJs() dict - return get(self.currSynstack, -1) =~# '^js' +fu! s:StateClass.isExpressionBracket() dict + return get(l:self.currSynstack, -1) ==# 'jsTemplateBraces' +endfu +fu! s:StateClass.closedExpression() dict + return l:self.wasExpressionBracket() && self.prevLine[-1:-1] ==# '}' +endfu +fu! s:StateClass.closesExpression() dict + return l:self.isExpressionBracket() && self.currLine[-1:-1] ==# '}' +endfu +fu! s:StateClass.openedExpression() dict + return l:self.wasExpressionBracket() && self.prevLine[-1:-1] ==# '{' +endfu +fu! s:StateClass.opensExpression() dict + return l:self.isExpressionBracket() && self.currLine[-1:-1] ==# '{' endfu fu! s:StateClass.wasCss() dict return get(self.prevSynstack, -1) =~# '^css' @@ -387,16 +382,21 @@ fu! ComputeLitHtmlIndent() endif if (l:state.openedLitHtmlTemplate()) - call s:debug('opened tagged template literal') - return indent(l:prev_lnum) + &shiftwidth + call s:debug('opened html template literal') + if (l:state.closesLitHtmlTemplate()) + call s:debug('closes html template literal') + return indent(l:prev_lnum) + else + return indent(l:prev_lnum) + &shiftwidth + endif endif - if (l:state.openedJsExpression()) + if (l:state.openedExpression()) call s:debug('opened js expression') return indent(l:prev_lnum) + &shiftwidth endif - if (l:state.wasJsTemplateBrace() || l:state.isLitHtmlRegionCloser()) + if (l:state.closesExpression() || l:state.isLitHtmlRegionCloser()) " let l:indent_basis = previous matching js or template start " let l:indent_delta = -1 for starting with closing tag, template, or expression let l:indent_basis = l:state.getIndentOfLastClose() @@ -410,7 +410,8 @@ fu! ComputeLitHtmlIndent() return l:indent_basis + l:indent_delta endif - if ((l:state.wasJs() && !l:state.wasJsTemplateBrace()) && (l:state.isJs() && !l:state.isJsTemplateBrace())) + if (l:state.wasJs() && !l:state.closedExpression() && ((l:state.isJs() || l:state.opensTemplate()))) + call s:debug("using javascript indent") return eval(b:litHtmlOriginalIndentExpression) endif diff --git a/test/indent/html-string-literal-end.vader b/test/indent/html-string-literal-end.vader new file mode 100644 index 0000000..c7f5f72 --- /dev/null +++ b/test/indent/html-string-literal-end.vader @@ -0,0 +1,56 @@ +Before: + set tabstop=2 + set shiftwidth=2 + set expandtab + +" IT SHOULD MATCH REGION END INDENT WITH REGION START + +Given javascript (LITERAL WITH SINGLE NEWLINE); +{ +html` +`; +} + +Do: + =G + +Expect javascript; +{ + html` + `; +} + +Given javascript (LITERAL WITH SINGLE HTML TAG); +{ +html` +
    +`; +} + +Do: + =G + +Expect javascript; +{ + html` +
    + `; +} + + +Given javascript (LITERAL WITH SINGLE SELF CLOSING TAG); +{ +html` + +`; +} + +Do: + =G + +Expect javascript; +{ + html` + + `; +} diff --git a/test/runtests b/test/runtests index 839a879..d59c41b 100755 --- a/test/runtests +++ b/test/runtests @@ -2,4 +2,9 @@ cd "$(dirname "$0")" -vim -u <(cat minimalvimrc) +Vader* +if [[ "$CI" = true ]]; then + export VADER_OUTPUT_FILE='testresults.txt' + vim -u <(cat minimalvimrc) +'Vader! indent/*.vader' +else + vim -u <(cat minimalvimrc) +'Vader indent/*.vader' +fi From 8bab5d3eceb9f35acdf60891d544c489387bf9a7 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 14:38:54 -0500 Subject: [PATCH 07/12] Be more reasonable about enabling debug mode --- after/indent/javascript.vim | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 83b232a..d8f5079 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -166,12 +166,9 @@ function! s:SynAt(l,c) " from $VIMRUNTIME/indent/javascript.vim return s:synid_cache[1][pos] endfunction -if exists('g:VHTL_debugging') - set debug=msg " show errors in indentexpr -endif " Make debug log. You can view these logs using ':messages' fu! s:debug(str) - if exists('g:VHTL_debugging') + if (exists('g:VHTL_debugging') && g:VHTL_debugging == 1) echom 'vhtl ' . v:lnum . ': ' . a:str endif endfu From c2618911032bd6eb7b4175a03dcb26781c8d968a Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 15:16:54 -0500 Subject: [PATCH 08/12] Add and fix more texts --- after/indent/javascript.vim | 22 +++++---- test/indent/html-string-literal-end.vader | 55 +++++++++++++++++++++++ test/minimalvimrc | 6 +++ 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index d8f5079..5c94932 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -224,14 +224,17 @@ fu! s:StateClass.isLitHtmlRegionCloser() dict return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*`' endfu fu! s:StateClass.opensTemplate() dict - return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*html`' + return get(l:self.currSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.currLine) =~# '^\s*html`' +endfu +fu! s:StateClass.closedTemplate() dict + return get(l:self.prevSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.prevLine) !~# 'html`$' endfu fu! s:StateClass.wasJs() dict - call s:debug(string(get(self.prevSynstack, -1))) - return get(self.prevSynstack, -1) =~# '^js' || get(self.prevSynstack, -1) =~# '^javaScript' + call s:debug(string(get(l:self.prevSynstack, -1))) + return get(l:self.prevSynstack, -1) =~# '^js' endfu fu! s:StateClass.isJs() dict - return get(self.currSynstack, -1) =~# '^js' || get(self.currSynstack, -1) =~# '^javaScript' + return get(l:self.currSynstack, -1) =~# '^js' endfu fu! s:StateClass.wasExpressionBracket() dict return get(self.prevSynstack, -1) ==# 'jsTemplateBraces' @@ -380,10 +383,13 @@ fu! ComputeLitHtmlIndent() if (l:state.openedLitHtmlTemplate()) call s:debug('opened html template literal') - if (l:state.closesLitHtmlTemplate()) - call s:debug('closes html template literal') + if (getline(l:state.currLine) =~# '^\s*`') + " The first character closes template on previous line. This is a tiny + " but very common edge case when typing out a new template from scratch. + call s:debug('closes html template literal in first character') return indent(l:prev_lnum) else + call s:debug('first line of template is always indented') return indent(l:prev_lnum) + &shiftwidth endif endif @@ -407,8 +413,8 @@ fu! ComputeLitHtmlIndent() return l:indent_basis + l:indent_delta endif - if (l:state.wasJs() && !l:state.closedExpression() && ((l:state.isJs() || l:state.opensTemplate()))) - call s:debug("using javascript indent") + if (((l:state.wasJs() && !l:state.closedExpression()) || l:state.closedTemplate()) && ((l:state.isJs() || l:state.opensTemplate()))) + call s:debug('using javascript indent') return eval(b:litHtmlOriginalIndentExpression) endif diff --git a/test/indent/html-string-literal-end.vader b/test/indent/html-string-literal-end.vader index c7f5f72..e6086a5 100644 --- a/test/indent/html-string-literal-end.vader +++ b/test/indent/html-string-literal-end.vader @@ -54,3 +54,58 @@ Expect javascript; `; } + +Given javascript (LITERAL AT END OF LINE, NO SEMICOLON); +{ +html` +
    +
    ` +more() +} + +Do: + =G + +Expect javascript; +{ + html` +
    +
    ` + more() +} + +Given javascript (LITERAL AT END OF LINE, WITH SEMICOLON); +{ +html` +
    +
    `; +more() +} + +Do: + =G + +Expect javascript; +{ + html` +
    +
    `; + more() +} + +Given javascript (LITERAL AT END OF ONLY LINE); +{ +html` +
    ` +more() +} + +Do: + =G + +Expect javascript; +{ + html` +
    ` + more() +} diff --git a/test/minimalvimrc b/test/minimalvimrc index f9ac15d..e6638db 100644 --- a/test/minimalvimrc +++ b/test/minimalvimrc @@ -7,3 +7,9 @@ call plug#end() syntax enable let g:VHTL_debugging = 1 let g:html_indent_style1 = "inc" + +nmap :echo map(synstack(line("."), col(".")), "synIDattr(v:val, 'name')") + +set tabstop=2 +set shiftwidth=2 +set expandtab From 852c1957b3e1112bef2975c604924dc70b2b3909 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 15:17:49 -0500 Subject: [PATCH 09/12] Fix a bunch of lint reported by vint --- after/indent/javascript.vim | 80 ++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 5c94932..2a91913 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -158,12 +158,12 @@ fu! VHTL_countMatches(string, pattern) endfu function! s:SynAt(l,c) " from $VIMRUNTIME/indent/javascript.vim - let byte = line2byte(a:l) + a:c - 1 - let pos = index(s:synid_cache[0], byte) - if pos == -1 - let s:synid_cache[:] += [[byte], [synIDattr(synID(a:l, a:c, 0), 'name')]] + let l:byte = line2byte(a:l) + a:c - 1 + let l:pos = index(s:synid_cache[0], l:byte) + if l:pos == -1 + let s:synid_cache[:] += [[l:byte], [synIDattr(synID(a:l, a:c, 0), 'name')]] endif - return s:synid_cache[1][pos] + return s:synid_cache[1][l:pos] endfunction " Make debug log. You can view these logs using ':messages' @@ -175,7 +175,7 @@ endfu let s:StateClass={} fu! s:StateClass.new(lnum) - let l:instance = copy(self) + let l:instance = copy(l:self) let l:instance.currLine = a:lnum let l:instance.prevLine = prevnonblank(a:lnum - 1) let l:instance.currSynstack = VHTL_SynSOL(l:instance.currLine) @@ -184,44 +184,44 @@ fu! s:StateClass.new(lnum) endfu fu! s:StateClass.startsWithTemplateClose() dict - return (getline(self.currSynstack)) =~# '^\s*`' + return (getline(l:self.currSynstack)) =~# '^\s*`' endfu fu! s:StateClass.openedJsExpression() dict - return (VHTL_getBracketDepthChange(getline(self.prevLine)) > 0) + return (VHTL_getBracketDepthChange(getline(l:self.prevLine)) > 0) endfu fu! s:StateClass.opensLitHtmlTemplate() dict - return VHTL_opensTemplate(getline(self.currLine)) + return VHTL_opensTemplate(getline(l:self.currLine)) endfu fu! s:StateClass.openedLitHtmlTemplate() dict - return VHTL_opensTemplate(getline(self.prevLine)) + return VHTL_opensTemplate(getline(l:self.prevLine)) endfu fu! s:StateClass.closesLitHtmlTemplate() dict - return VHTL_closesTemplate(getline(self.currLine)) + return VHTL_closesTemplate(getline(l:self.currLine)) endfu fu! s:StateClass.closedLitHtmlTemplate() dict - return VHTL_closesTemplate(getline(self.prevLine)) + return VHTL_closesTemplate(getline(l:self.prevLine)) endfu fu! s:StateClass.isInsideLitHtml() dict - return VHTL_isSynstackInsideLitHtml(self.currSynstack) + return VHTL_isSynstackInsideLitHtml(l:self.currSynstack) endfu fu! s:StateClass.wasInsideLitHtml() dict - return VHTL_isSynstackInsideLitHtml(self.prevSynstack) + return VHTL_isSynstackInsideLitHtml(l:self.prevSynstack) endfu fu! s:StateClass.isInsideJsx() dict - return IsSynstackInsideJsx(self.currSynstack) + return IsSynstackInsideJsx(l:self.currSynstack) endfu fu! s:StateClass.wasHtml() dict - return get(self.prevSynstack, -1) =~# '^html' + return get(l:self.prevSynstack, -1) =~# '^html' endfu fu! s:StateClass.isHtml() dict - return get(self.currSynstack, -1) =~# '^html' + return get(l:self.currSynstack, -1) =~# '^html' endfu fu! s:StateClass.isLitHtmlRegionCloser() dict " TODO this doesn't accoutn for semicolons or trailing spaces? - return get(self.currSynstack, -1) ==# 'litHtmlRegion' && getline(self.currLine) =~# '^\s*`' + return get(l:self.currSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.currLine) =~# '^\s*`' endfu fu! s:StateClass.opensTemplate() dict return get(l:self.currSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.currLine) =~# '^\s*html`' @@ -237,38 +237,38 @@ fu! s:StateClass.isJs() dict return get(l:self.currSynstack, -1) =~# '^js' endfu fu! s:StateClass.wasExpressionBracket() dict - return get(self.prevSynstack, -1) ==# 'jsTemplateBraces' + return get(l:self.prevSynstack, -1) ==# 'jsTemplateBraces' endfu fu! s:StateClass.isExpressionBracket() dict - return get(l:self.currSynstack, -1) ==# 'jsTemplateBraces' + return get(l:self.currSynstack, -2) ==# 'jsTemplateBraces' endfu fu! s:StateClass.closedExpression() dict - return l:self.wasExpressionBracket() && self.prevLine[-1:-1] ==# '}' + return l:self.wasExpressionBracket() && l:self.prevLine[-1:-1] ==# '}' endfu fu! s:StateClass.closesExpression() dict - return l:self.isExpressionBracket() && self.currLine[-1:-1] ==# '}' + return l:self.isExpressionBracket() && l:self.currLine[-1:-1] ==# '}' endfu fu! s:StateClass.openedExpression() dict - return l:self.wasExpressionBracket() && self.prevLine[-1:-1] ==# '{' + return l:self.wasExpressionBracket() && l:self.prevLine[-1:-1] ==# '{' endfu fu! s:StateClass.opensExpression() dict - return l:self.isExpressionBracket() && self.currLine[-1:-1] ==# '{' + return l:self.isExpressionBracket() && l:self.currLine[-1:-1] ==# '{' endfu fu! s:StateClass.wasCss() dict - return get(self.prevSynstack, -1) =~# '^css' + return get(l:self.prevSynstack, -1) =~# '^css' endfu fu! s:StateClass.isCss() dict - return get(self.currSynstack, -1) =~# '^css' + return get(l:self.currSynstack, -1) =~# '^css' endfu fu! s:StateClass.toStr() dict - return '{line ' . self.currLine . '}' + return '{line ' . l:self.currLine . '}' endfu fu! s:SkipFuncJsTemplateBraces() " let l:char = getline(line('.'))[col('.')-1] let l:syntax = s:SynAt(line('.'), col('.')) - if (l:syntax != 'jsTemplateBraces') + if (l:syntax !=# 'jsTemplateBraces') return 1 endif endfu @@ -276,7 +276,7 @@ endfu fu! s:SkipFuncLitHtmlRegion() " let l:char = getline(line('.'))[col('.')-1] let l:syntax = s:SynAt(line('.'), col('.')) - if (l:syntax != 'litHtmlRegion') + if (l:syntax !=# 'litHtmlRegion') return 1 endif endfu @@ -307,17 +307,17 @@ fu! s:getCloseWordsLeftToRight(lineNum) endfu fu! s:StateClass.getIndentDelta() dict - let l:closeWords = s:getCloseWordsLeftToRight(self.currLine) + let l:closeWords = s:getCloseWordsLeftToRight(l:self.currLine) if len(l:closeWords) == 0 return 0 endif let [l:closeWord, l:col] = l:closeWords[0] - let l:syntax = s:SynAt(self.currLine, l:col) - if (l:syntax == 'htmlEndTag') + let l:syntax = s:SynAt(l:self.currLine, l:col) + if (l:syntax ==# 'htmlEndTag') call s:debug('indent_delta: html end tag') return - &shiftwidth endif - if (l:syntax == 'litHtmlRegion' && 'html`' != strpart(getline(self.currLine), l:col-5, len('html`'))) + if (l:syntax ==# 'litHtmlRegion' && 'html`' !=# strpart(getline(l:self.currLine), l:col-5, len('html`'))) call s:debug('indent_delta: end of litHtmlRegion') return - &shiftwidth endif @@ -327,7 +327,7 @@ endfu " html tag, html template, or js expression on previous line fu! s:StateClass.getIndentOfLastClose() dict - let l:closeWords = s:getCloseWordsLeftToRight(self.prevLine) + let l:closeWords = s:getCloseWordsLeftToRight(l:self.prevLine) if (len(l:closeWords) == 0) call s:debug('no close words found') @@ -336,16 +336,16 @@ fu! s:StateClass.getIndentOfLastClose() dict for l:item in reverse(l:closeWords) let [l:closeWord, l:col] = l:item - let l:syntax = s:SynAt(self.prevLine, l:col) - call cursor(self.prevLine, l:col) " sets start point for searchpair() + let l:syntax = s:SynAt(l:self.prevLine, l:col) + call cursor(l:self.prevLine, l:col) " sets start point for searchpair() redraw - if ("}" == l:closeWord && l:syntax == 'jsTemplateBraces') + if ('}' ==# l:closeWord && l:syntax ==# 'jsTemplateBraces') call searchpair('{', '', '}', 'b', 's:SkipFuncJsTemplateBraces()') call s:debug('js brace base indent') - elseif ("`" == l:closeWord && l:syntax == 'litHtmlRegion') + elseif ('`' ==# l:closeWord && l:syntax ==# 'litHtmlRegion') call searchpair('html`', '', '\(html\)\@', '', '') call searchpair(l:openWord, '', l:closeWord, 'b') call s:debug('html tag region base indent ') @@ -404,7 +404,7 @@ fu! ComputeLitHtmlIndent() " let l:indent_delta = -1 for starting with closing tag, template, or expression let l:indent_basis = l:state.getIndentOfLastClose() if (l:indent_basis == -1) - call s:debug("using html indent as base indent") + call s:debug('using html indent as base indent') let l:indent_basis = HtmlIndent() endif let l:indent_delta = l:state.getIndentDelta() From a41a00cb1b426bfc913a32f915c95a29ef3760c7 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 16:14:13 -0500 Subject: [PATCH 10/12] Add more tests and fix more issues --- after/indent/javascript.vim | 12 +++-- test/indent/html-string-literal-end.vader | 41 ++++++++++++++++- test/indent/template-end.vader | 54 +++++++++++++++++++++++ 3 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 test/indent/template-end.vader diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 2a91913..0ebede4 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -220,7 +220,6 @@ fu! s:StateClass.isHtml() dict return get(l:self.currSynstack, -1) =~# '^html' endfu fu! s:StateClass.isLitHtmlRegionCloser() dict - " TODO this doesn't accoutn for semicolons or trailing spaces? return get(l:self.currSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.currLine) =~# '^\s*`' endfu fu! s:StateClass.opensTemplate() dict @@ -230,7 +229,6 @@ fu! s:StateClass.closedTemplate() dict return get(l:self.prevSynstack, -1) ==# 'litHtmlRegion' && getline(l:self.prevLine) !~# 'html`$' endfu fu! s:StateClass.wasJs() dict - call s:debug(string(get(l:self.prevSynstack, -1))) return get(l:self.prevSynstack, -1) =~# '^js' endfu fu! s:StateClass.isJs() dict @@ -243,16 +241,16 @@ fu! s:StateClass.isExpressionBracket() dict return get(l:self.currSynstack, -2) ==# 'jsTemplateBraces' endfu fu! s:StateClass.closedExpression() dict - return l:self.wasExpressionBracket() && l:self.prevLine[-1:-1] ==# '}' + return l:self.wasExpressionBracket() && getline(l:self.prevLine)[-1:-1] ==# '}' endfu fu! s:StateClass.closesExpression() dict - return l:self.isExpressionBracket() && l:self.currLine[-1:-1] ==# '}' + return l:self.isExpressionBracket() && getline(l:self.currLine)[-1:-1] ==# '}' endfu fu! s:StateClass.openedExpression() dict - return l:self.wasExpressionBracket() && l:self.prevLine[-1:-1] ==# '{' + return l:self.wasExpressionBracket() && getline(l:self.prevLine)[-1:-1] ==# '{' endfu fu! s:StateClass.opensExpression() dict - return l:self.isExpressionBracket() && l:self.currLine[-1:-1] ==# '{' + return l:self.isExpressionBracket() && getline(l:self.currLine)[-1:-1] ==# '{' endfu fu! s:StateClass.wasCss() dict return get(l:self.prevSynstack, -1) =~# '^css' @@ -399,7 +397,7 @@ fu! ComputeLitHtmlIndent() return indent(l:prev_lnum) + &shiftwidth endif - if (l:state.closesExpression() || l:state.isLitHtmlRegionCloser()) + if (l:state.closedExpression() || l:state.isLitHtmlRegionCloser()) " let l:indent_basis = previous matching js or template start " let l:indent_delta = -1 for starting with closing tag, template, or expression let l:indent_basis = l:state.getIndentOfLastClose() diff --git a/test/indent/html-string-literal-end.vader b/test/indent/html-string-literal-end.vader index e6086a5..c8cc941 100644 --- a/test/indent/html-string-literal-end.vader +++ b/test/indent/html-string-literal-end.vader @@ -3,8 +3,6 @@ Before: set shiftwidth=2 set expandtab -" IT SHOULD MATCH REGION END INDENT WITH REGION START - Given javascript (LITERAL WITH SINGLE NEWLINE); { html` @@ -109,3 +107,42 @@ Expect javascript;
    ` more() } + +Given javascript (CONTINUE WITH CORRECT INDENTATION); +{ +html` +${ +html` +
    ` } `; +more() +} + +Do: + =G + +Expect javascript; +{ + html` + ${ + html` +
    ` } `; + more() +} + +After: +# Given javascript (IGNORED: LITERAL AFTER SELF-CLOSING TAG) +# { +# html` +#
    +# `; +# } +# +# Do: +# =G +# +# Expect javascript; +# { +# html` +#
    +# `; +# } diff --git a/test/indent/template-end.vader b/test/indent/template-end.vader new file mode 100644 index 0000000..f629468 --- /dev/null +++ b/test/indent/template-end.vader @@ -0,0 +1,54 @@ +Before: + set tabstop=2 + set shiftwidth=2 + set expandtab + +Given javascript (FOLLOWING HTML TAGS); +{ +html` +${ +html`${ +2 + 2}`} +
    +
    +`; +} + +Do: + =G + +Expect javascript; +{ + html` + ${ + html`${ + 2 + 2}`} +
    +
    + `; +} + +Given javascript (CONTINUE WITH CORRECT HTML INDENT); +{ +html` +${ +html`${ +2 + 2}`} +
    +
    +`; +} + +Do: + =G + +Expect javascript; +{ + html` + ${ + html`${ + 2 + 2}`} +
    +
    + `; +} From 24d5e7d2479df0044ce1cb733c3fa4374dd2f343 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 16:39:20 -0500 Subject: [PATCH 11/12] Delete a bunch of old unused code --- after/indent/javascript.vim | 154 ++++++++---------------------------- 1 file changed, 33 insertions(+), 121 deletions(-) diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 0ebede4..4a82d5d 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -38,7 +38,7 @@ setlocal indentkeys+=` let s:endtag = '^\s*\/\?>\s*;\=' " Get syntax stack at StartOfLine -fu! VHTL_SynSOL(lnum) +fu! s:VHTL_SynSOL(lnum) let l:col = match(getline(a:lnum), '\S') if (l:col == -1) return [] @@ -47,7 +47,7 @@ fu! VHTL_SynSOL(lnum) endfu " Get syntax stack at EndOfLine -fu! VHTL_SynEOL(lnum) +fu! s:VHTL_SynEOL(lnum) if (a:lnum < 1) return [] endif @@ -55,108 +55,6 @@ fu! VHTL_SynEOL(lnum) return map(synstack(a:lnum, l:col), "synIDattr(v:val, 'name')") endfu -fu! IsSynstackCss(synstack) - return get(a:synstack, -1) =~# '^css' -endfu - -" Does synstack end with an xml syntax attribute -fu! IsSynstackHtml(synstack) - return get(a:synstack, -1) =~# '^html' -endfu - -fu! IsSynstackJs(synstack) - return get(a:synstack, -1) =~# '^js' -endfu - -fu! VHTL_isSynstackInsideLitHtml(synstack) - for l:syntaxAttribute in reverse(copy((a:synstack))) - if (l:syntaxAttribute ==# 'litHtmlRegion') - return v:true - endif - endfor - return v:false -endfu - -fu! IsSynstackInsideJsx(synstack) - for l:syntaxAttribute in reverse(copy((a:synstack))) - if (l:syntaxAttribute =~# '^jsx') - return v:true - endif - endfor - return v:false -endfu - -fu! VHTL_startsWithTemplateEnd(linenum) - return (getline(a:linenum)) =~# '^\s*`' -endfu - -fu! VHTL_opensTemplate(line) - let l:index = 0 - let l:depth = 0 - while v:true - let [l:term, l:index, l:trash] = matchstrpos(a:line, '\Mhtml`\|\\`\|`', l:index) - if (l:index == -1) - return (l:depth > 0) - endif - if (l:term ==# 'html`') - let l:index += len('html`') - let l:depth += 1 - elseif(l:term ==# '`') - let l:index += len('`') - if (l:depth > 0) - let l:depth -= 1 - endif - endif - endwhile -endfu - -fu! VHTL_closesTemplate(line) - let l:index = 0 - let l:depth = 0 - while v:true - let [l:term, l:index, l:trash] = matchstrpos(a:line, '\Mhtml`\|\\`\|`', l:index) - if (l:index == -1) - return v:false - endif - if (l:term ==# 'html`') - let l:index += len('html`') - let l:depth += 1 - elseif(l:term ==# '`') - let l:index += len('`') - let l:depth -= 1 - if (l:depth < 0) - return v:true - endif - endif - endwhile -endfu - -fu! VHTL_closesTag(line) - return (-1 != match(a:line, '^\s*<\/')) - " todo: what about
    ? -endfu - -fu! VHTL_getHtmlTemplateDepthChange(line) - let l:templateOpeners = VHTL_countMatches(a:line, 'html`') - let l:escapedTics = VHTL_countMatches(a:line, '\M\\`') - let l:templateClosers = VHTL_countMatches(a:line, '`') - l:templateOpeners - l:escapedTics - let l:depth = l:templateOpeners - l:templateClosers - return l:depth -endfu - -fu! VHTL_countMatches(string, pattern) - let l:count = 0 - let l:lastMatch = -1 - while v:true - let l:lastMatch = match(a:string, a:pattern, l:lastMatch+1) - if (-1 == l:lastMatch) - return l:count - else - let l:count += 1 - endif - endwhile -endfu - function! s:SynAt(l,c) " from $VIMRUNTIME/indent/javascript.vim let l:byte = line2byte(a:l) + a:c - 1 let l:pos = index(s:synid_cache[0], l:byte) @@ -178,8 +76,8 @@ fu! s:StateClass.new(lnum) let l:instance = copy(l:self) let l:instance.currLine = a:lnum let l:instance.prevLine = prevnonblank(a:lnum - 1) - let l:instance.currSynstack = VHTL_SynSOL(l:instance.currLine) - let l:instance.prevSynstack = VHTL_SynEOL(l:instance.prevLine) + let l:instance.currSynstack = s:VHTL_SynSOL(l:instance.currLine) + let l:instance.prevSynstack = s:VHTL_SynEOL(l:instance.prevLine) return l:instance endfu @@ -190,27 +88,41 @@ endfu fu! s:StateClass.openedJsExpression() dict return (VHTL_getBracketDepthChange(getline(l:self.prevLine)) > 0) endfu -fu! s:StateClass.opensLitHtmlTemplate() dict - return VHTL_opensTemplate(getline(l:self.currLine)) -endfu fu! s:StateClass.openedLitHtmlTemplate() dict - return VHTL_opensTemplate(getline(l:self.prevLine)) -endfu -fu! s:StateClass.closesLitHtmlTemplate() dict - return VHTL_closesTemplate(getline(l:self.currLine)) -endfu -fu! s:StateClass.closedLitHtmlTemplate() dict - return VHTL_closesTemplate(getline(l:self.prevLine)) + let l:index = 0 + let l:depth = 0 + while v:true + let [l:term, l:index, l:trash] = matchstrpos(getline(l:self.prevLine), '\Mhtml`\|\\`\|`', l:index) + if (l:index == -1) + return (l:depth > 0) + endif + if (l:term ==# 'html`') + let l:index += len('html`') + let l:depth += 1 + elseif(l:term ==# '`') + let l:index += len('`') + if (l:depth > 0) + let l:depth -= 1 + endif + endif + endwhile endfu fu! s:StateClass.isInsideLitHtml() dict - return VHTL_isSynstackInsideLitHtml(l:self.currSynstack) + for l:syntaxAttribute in reverse(copy(l:self.currSynstack)) + if (l:syntaxAttribute ==# 'litHtmlRegion') + return v:true + endif + endfor + return v:false endfu fu! s:StateClass.wasInsideLitHtml() dict - return VHTL_isSynstackInsideLitHtml(l:self.prevSynstack) -endfu -fu! s:StateClass.isInsideJsx() dict - return IsSynstackInsideJsx(l:self.currSynstack) + for l:syntaxAttribute in reverse(copy(l:self.prevSynstack)) + if (l:syntaxAttribute ==# 'litHtmlRegion') + return v:true + endif + endfor + return v:false endfu fu! s:StateClass.wasHtml() dict From 7cb3dccf2bceb46845783f5815128a1b52d66643 Mon Sep 17 00:00:00 2001 From: Jon Smithers Date: Sun, 16 Dec 2018 17:11:14 -0500 Subject: [PATCH 12/12] Organize tests and title them more clearly --- .../example-code-tests.vader | 369 ++++++++++++++++++ test/indent/html-string-literal-end.vader | 3 +- test/indent/html-string-literal-start.vader | 12 + test/indent/template-end.vader | 28 +- 4 files changed, 385 insertions(+), 27 deletions(-) create mode 100644 test/example-code-tests/example-code-tests.vader create mode 100644 test/indent/html-string-literal-start.vader diff --git a/test/example-code-tests/example-code-tests.vader b/test/example-code-tests/example-code-tests.vader new file mode 100644 index 0000000..3d61ad7 --- /dev/null +++ b/test/example-code-tests/example-code-tests.vader @@ -0,0 +1,369 @@ +" This test file is not used for regular testing because the tests here are +" generally very large in scope and thus not helpful in telling you what's +" actually failing. + +Before: + set tabstop=2 + set shiftwidth=2 + set expandtab + +Given javascript (html in html); +html` +
    +
    +
    +`; + +Do: + =G + +Expect javascript; +html` +
    +
    +
    +`; + +Given javascript (close template and tag); + html` +
    + ${when(condition, html` + `)} +
    `; + js(); + +Do: + =G + +Expect javascript; +html` +
    + ${when(condition, html` + `)} +
    `; +js(); + +Given javascript (text line inside xml); +html` +
    + simple text +
    + `; + +Do: + =G + +Expect javascript; +html` +
    + simple text +
    +`; + +Given javascript (sparse text lines inside xml): + html` +
    + + text one + + text two + +
    + ` + +Do: + =G + +Expect javascript: + html` +
    + + text one + + text two + +
    + ` + +Given javascript (nested css); + html` + +
    + +
    + ` + +Do: + =G + +Expect javascript; +html` + +
    + +
    +` + +Given javascript (lit-html readme example 1); +const render = () => html` +${when(state === 'loading', +html`
    Loading...
    `, +html`

    ${message}

    `)} +`; + +Do: + =G + +Expect javascript; +const render = () => html` + ${when(state === 'loading', + html`
    Loading...
    `, + html`

    ${message}

    `)} +`; + +Given javascript (lit-html readme example 2); +const render = () => html` +
      +${repeat(items, (i) => i.id, (i, index) => html` +
    • ${index}: ${i.name}
    • `)} +
    +`; + +Do: + =G + +Expect javascript; +const render = () => html` +
      + ${repeat(items, (i) => i.id, (i, index) => html` +
    • ${index}: ${i.name}
    • `)} +
    +`; + +Given javascript (lit-html readme example 3); +const render = () => html` +

    +${until( +fetch('content.txt').then((r) => r.text()), +html`Loading...`)} +

    +`; + +Do: + =G + +Expect javascript; +const render = () => html` +

    + ${until( + fetch('content.txt').then((r) => r.text()), + html`Loading...`)} +

    +`; + + +Given javascript (nuances with closing brackets and templates): + html` + ${repeat(items, (i) => i.id, (i, index) => html` +
  • ${index}: ${i.name}
  • `)} +
    DEDENT THIS LINE ONCE
    +
    +
    as usual
    + ${this.ternary ? html` +
    indented
    + ` : html` +
    also indented
    + `} +
    DO NOT DEDENT THIS LINE
    +
    + ` + +Do: + =G + +Expect javascript: + html` + ${repeat(items, (i) => i.id, (i, index) => html` +
  • ${index}: ${i.name}
  • `)} +
    DEDENT THIS LINE ONCE
    +
    +
    as usual
    + ${this.ternary ? html` +
    indented
    + ` : html` +
    also indented
    + `} +
    DO NOT DEDENT THIS LINE
    +
    + ` + +Given javascript (adjacent js expressions): + html` + ${console.log(null)} + ${console.log('this line should have equal indentation')} + ` +Do: + =G + +Expect javascript: + html` + ${console.log(null)} + ${console.log('this line should have equal indentation')} + ` + +Given javascript(multiple dedents after closing js expression): + html` +
    + ${ test + ? html`

    one

    ` + : html` +

    + two +

    `} +
    + dedent THRICE here + `; + +Do: + =G + +Expect javascript: + html` +
    + ${ test + ? html`

    one

    ` + : html` +

    + two +

    `} +
    + dedent THRICE here + `; + +" " This test fails because vim-javascript doesn't correctly indent ternaries inside ${ } +" Given javascript (subsequent templates): +" html` +" ${user.isloggedIn +" ? html`Welcome ${user.name}` +" : html`Please log in` +" } +" `; +" html` +"
      +" ${items.map((i) => html`
    • ${i}
    • `)} +"
    +" `; +" +" Do: +" =G +" +" Expect javascript: +" html` +" ${user.isloggedIn +" ? html`Welcome ${user.name}` +" : html`Please log in` +" } +" `; +" html` +"
      +" ${items.map((i) => html`
    • ${i}
    • `)} +"
    +" `; + + +Before: + set tabstop=2 + set shiftwidth=2 + set expandtab + +Given javascript (multiple syntaxes on one line); +return html` + Web Components are + ${mood}!`; + +Do: + =G + +Expect javascript; +return html` + Web Components are + ${mood}!`; + +Given javascript (tricky indnetation); +return html` +
    Files
    + ${!this.fileList ? + html` + this.onFetchBtn()}> + fetch notes + + ` : html` + this.onFetchBtn()}> + refresh + + ${repeat(this.fileList || [], null, (file) => html` + this.onFileClick(file.path)} data="${file}">${file.name} + `)} + `} + + this.onNewFileClick()}> +`; + +Do: + =G + +Expect javascript; +return html` +
    Files
    + ${!this.fileList ? + html` + this.onFetchBtn()}> + fetch notes + + ` : html` + this.onFetchBtn()}> + refresh + + ${repeat(this.fileList || [], null, (file) => html` + this.onFileClick(file.path)} data="${file}">${file.name} + `)} + `} + + this.onNewFileClick()}> +`; + + diff --git a/test/indent/html-string-literal-end.vader b/test/indent/html-string-literal-end.vader index c8cc941..677818b 100644 --- a/test/indent/html-string-literal-end.vader +++ b/test/indent/html-string-literal-end.vader @@ -3,6 +3,7 @@ Before: set shiftwidth=2 set expandtab +" (IT SHOULD CORRECTLY INDENT...) Given javascript (LITERAL WITH SINGLE NEWLINE); { html` @@ -108,7 +109,7 @@ Expect javascript; more() } -Given javascript (CONTINUE WITH CORRECT INDENTATION); +Given javascript (NEXT LINE AFTER LITERAL); { html` ${ diff --git a/test/indent/html-string-literal-start.vader b/test/indent/html-string-literal-start.vader new file mode 100644 index 0000000..555ee52 --- /dev/null +++ b/test/indent/html-string-literal-start.vader @@ -0,0 +1,12 @@ + +" (IT SHOULD CORRECTLY INDENT...) +Given javascript (COMMENTED TEMPLATES): + // html` + //
    `; + +Do: + =G + +Expect javascript: + // html` + //
    `; diff --git a/test/indent/template-end.vader b/test/indent/template-end.vader index f629468..24b88d7 100644 --- a/test/indent/template-end.vader +++ b/test/indent/template-end.vader @@ -3,32 +3,8 @@ Before: set shiftwidth=2 set expandtab -Given javascript (FOLLOWING HTML TAGS); -{ -html` -${ -html`${ -2 + 2}`} -
    -
    -`; -} - -Do: - =G - -Expect javascript; -{ - html` - ${ - html`${ - 2 + 2}`} -
    -
    - `; -} - -Given javascript (CONTINUE WITH CORRECT HTML INDENT); +" (IT SHOULD CORRECTLY INDENT...) +Given javascript (NEXT LINE OF HTML); { html` ${