mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-23 07:00:04 +08:00
Improve tsx support (#3993)
This commit is contained in:
parent
03a2ab8afe
commit
6e25213d3e
@ -25,8 +25,8 @@
|
||||
|
||||
function! SpaceVim#layers#lang#typescript#plugins() abort
|
||||
let plugins = []
|
||||
call add(plugins, ['leafgarland/typescript-vim'])
|
||||
call add(plugins, ['peitalin/vim-jsx-typescript'])
|
||||
call add(plugins, ['leafgarland/typescript-vim', {'merged' : 0}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/vim-jsx-typescript', {'merged' : 0}])
|
||||
call add(plugins, ['heavenshell/vim-jsdoc', { 'on_cmd': 'JsDoc' }])
|
||||
if !SpaceVim#layers#lsp#check_filetype('typescript')
|
||||
if has('nvim')
|
||||
|
16
bundle/vim-jsx-typescript/after/ftplugin/typescriptreact.vim
Normal file
16
bundle/vim-jsx-typescript/after/ftplugin/typescriptreact.vim
Normal file
@ -0,0 +1,16 @@
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Vim ftplugin file
|
||||
"
|
||||
" Language: TSX (TypeScript)
|
||||
"
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" modified from html.vim
|
||||
if exists("loaded_matchit")
|
||||
let b:match_ignorecase = 0
|
||||
let b:match_words = '(:),\[:\],{:},<:>,' .
|
||||
\ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>'
|
||||
endif
|
||||
|
||||
setlocal suffixesadd+=.tsx
|
||||
setlocal commentstring={/*\ %s\ */}
|
183
bundle/vim-jsx-typescript/after/indent/typescriptreact.vim
Normal file
183
bundle/vim-jsx-typescript/after/indent/typescriptreact.vim
Normal file
@ -0,0 +1,183 @@
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Vim indent file
|
||||
"
|
||||
" Language: typescriptreact (TypeScript)
|
||||
" from:
|
||||
" https://github.com/peitalin/vim-jsx-typescript/issues/4#issuecomment-564519091
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
runtime! indent/typescript.vim
|
||||
|
||||
let b:did_indent = 1
|
||||
|
||||
if !exists('*GetTypescriptIndent') | finish | endif
|
||||
|
||||
setlocal indentexpr=GetTsxIndent()
|
||||
setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e,*<Return>,<>>,<<>,/
|
||||
|
||||
if exists('*shiftwidth')
|
||||
function! s:sw()
|
||||
return shiftwidth()
|
||||
endfunction
|
||||
else
|
||||
function! s:sw()
|
||||
return &sw
|
||||
endfunction
|
||||
endif
|
||||
|
||||
let s:real_endtag = '\s*<\/\+[A-Za-z]*>'
|
||||
let s:return_block = '\s*return\s\+('
|
||||
function! s:SynSOL(lnum)
|
||||
return map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
|
||||
endfunction
|
||||
|
||||
function! s:SynEOL(lnum)
|
||||
let lnum = prevnonblank(a:lnum)
|
||||
let col = strlen(getline(lnum))
|
||||
return map(synstack(lnum, col), 'synIDattr(v:val, "name")')
|
||||
endfunction
|
||||
|
||||
function! s:SynAttrJSX(synattr)
|
||||
return a:synattr =~ "^tsx"
|
||||
endfunction
|
||||
|
||||
function! s:SynXMLish(syns)
|
||||
return s:SynAttrJSX(get(a:syns, -1))
|
||||
endfunction
|
||||
|
||||
function! s:SynJSXDepth(syns)
|
||||
return len(filter(copy(a:syns), 'v:val ==# "tsxRegion"'))
|
||||
endfunction
|
||||
|
||||
function! s:SynJSXCloseTag(syns)
|
||||
return len(filter(copy(a:syns), 'v:val ==# "tsxCloseTag"'))
|
||||
endfunction
|
||||
|
||||
function! s:SynJsxEscapeJs(syns)
|
||||
return len(filter(copy(a:syns), 'v:val ==# "tsxJsBlock"'))
|
||||
endfunction
|
||||
|
||||
function! s:SynJSXContinues(cursyn, prevsyn)
|
||||
let curdepth = s:SynJSXDepth(a:cursyn)
|
||||
let prevdepth = s:SynJSXDepth(a:prevsyn)
|
||||
|
||||
return prevdepth == curdepth ||
|
||||
\ (prevdepth == curdepth + 1 && get(a:cursyn, -1) ==# 'tsxRegion')
|
||||
endfunction
|
||||
|
||||
function! GetTsxIndent()
|
||||
let cursyn = s:SynSOL(v:lnum)
|
||||
let prevsyn = s:SynEOL(v:lnum - 1)
|
||||
let nextsyn = s:SynEOL(v:lnum + 1)
|
||||
let currline = getline(v:lnum)
|
||||
|
||||
if ((s:SynXMLish(prevsyn) && s:SynJSXContinues(cursyn, prevsyn)) || currline =~# '\v^\s*\<')
|
||||
let preline = getline(v:lnum - 1)
|
||||
|
||||
if currline =~# '\v^\s*\/?\>' " /> >
|
||||
return preline =~# '\v^\s*\<' ? indent(v:lnum - 1) : indent(v:lnum - 1) - s:sw()
|
||||
endif
|
||||
|
||||
if preline =~# '\v\{\s*$' && preline !~# '\v^\s*\<'
|
||||
return currline =~# '\v^\s*\}' ? indent(v:lnum - 1) : indent(v:lnum - 1) + s:sw()
|
||||
endif
|
||||
|
||||
" return ( | return ( | return (
|
||||
" <div></div> | <div | <div
|
||||
" {} | style={ | style={
|
||||
" <div></div> | } | }
|
||||
" ) | foo="bar"| ></div>
|
||||
if preline =~# '\v\}\s*$'
|
||||
if currline =~# '\v^\s*\<\/'
|
||||
return indent(v:lnum - 1) - s:sw()
|
||||
endif
|
||||
let ind = indent(v:lnum - 1)
|
||||
if preline =~# '\v^\s*\<'
|
||||
let ind = ind + s:sw()
|
||||
endif
|
||||
if currline =~# '\v^\s*\/?\>'
|
||||
let ind = ind - s:sw()
|
||||
endif
|
||||
return ind
|
||||
endif
|
||||
|
||||
" return ( | return (
|
||||
" <div> | <div>
|
||||
" </div> | </div>
|
||||
" ##); | );
|
||||
if preline =~# '\v(\s?|\k?)\($' || preline =~# '\v^\s*\<\>'
|
||||
return indent(v:lnum - 1) + s:sw()
|
||||
endif
|
||||
|
||||
let ind = s:XmlIndentGet(v:lnum)
|
||||
|
||||
" <div | <div
|
||||
" hoge={ | hoge={
|
||||
" <div></div> | ##<div></div>
|
||||
if s:SynJsxEscapeJs(prevsyn) && preline =~# '\v\{\s*$'
|
||||
let ind = ind + s:sw()
|
||||
endif
|
||||
|
||||
" />
|
||||
if preline =~# '\v^\s*\/?\>$' || currline =~# '\v^\s*\<\/\>'
|
||||
"let ind = currline =~# '\v^\s*\<\/' ? ind : ind + s:sw()
|
||||
let ind = ind + s:sw()
|
||||
" }> or }}\> or }}>
|
||||
elseif preline =~# '\v^\s*\}?\}\s*\/?\>$'
|
||||
let ind = ind + s:sw()
|
||||
" ></a
|
||||
elseif preline =~# '\v^\s*\>\<\/\a'
|
||||
let ind = ind + s:sw()
|
||||
elseif preline =~# '\v^\s*}}.+\<\/\k+\>$'
|
||||
let ind = ind + s:sw()
|
||||
endif
|
||||
|
||||
" <div | <div
|
||||
" hoge={ | hoge={
|
||||
" <div></div> | <div></div>
|
||||
" } | }##
|
||||
if currline =~# '}$' && !(currline =~# '\v\{')
|
||||
let ind = ind - s:sw()
|
||||
endif
|
||||
|
||||
if currline =~# '^\s*)' && s:SynJSXCloseTag(prevsyn)
|
||||
let ind = ind - s:sw()
|
||||
endif
|
||||
else
|
||||
let ind = GetTypescriptIndent()
|
||||
endif
|
||||
return ind
|
||||
endfunction
|
||||
|
||||
let b:xml_indent_open = '.\{-}<\a'
|
||||
let b:xml_indent_close = '.\{-}</'
|
||||
|
||||
function! s:XmlIndentWithPattern(line, pat)
|
||||
let s = substitute('x'.a:line, a:pat, "\1", 'g')
|
||||
return strlen(substitute(s, "[^\1].*$", '', ''))
|
||||
endfunction
|
||||
|
||||
" [-- return the sum of indents of a:lnum --]
|
||||
function! s:XmlIndentSum(lnum, style, add)
|
||||
let line = getline(a:lnum)
|
||||
if a:style == match(line, '^\s*</')
|
||||
return (&sw *
|
||||
\ (s:XmlIndentWithPattern(line, b:xml_indent_open)
|
||||
\ - s:XmlIndentWithPattern(line, b:xml_indent_close)
|
||||
\ - s:XmlIndentWithPattern(line, '.\{-}/>'))) + a:add
|
||||
else
|
||||
return a:add
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:XmlIndentGet(lnum)
|
||||
" Find a non-empty line above the current line.
|
||||
let lnum = prevnonblank(a:lnum - 1)
|
||||
|
||||
" Hit the start of the file, use zero indent.
|
||||
if lnum == 0 | return 0 | endif
|
||||
|
||||
let ind = s:XmlIndentSum(lnum, -1, indent(lnum))
|
||||
let ind = s:XmlIndentSum(a:lnum, 0, ind)
|
||||
return ind
|
||||
endfunction
|
256
bundle/vim-jsx-typescript/after/syntax/typescriptreact.vim
Normal file
256
bundle/vim-jsx-typescript/after/syntax/typescriptreact.vim
Normal file
@ -0,0 +1,256 @@
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Vim syntax file
|
||||
"
|
||||
" Language: TSX (TypeScript)
|
||||
"
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" These are the plugin-to-syntax-element correspondences:
|
||||
" - leafgarland/typescript-vim: typescriptFuncBlock
|
||||
|
||||
|
||||
let s:tsx_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
syntax case match
|
||||
|
||||
if exists('b:current_syntax')
|
||||
let s:current_syntax = b:current_syntax
|
||||
unlet b:current_syntax
|
||||
endif
|
||||
|
||||
syn include @HTMLSyntax syntax/html.vim
|
||||
set syntax=typescript
|
||||
if exists('s:current_syntax')
|
||||
let b:current_syntax = s:current_syntax
|
||||
endif
|
||||
|
||||
"""""" Vim Syntax Help """"""
|
||||
" `keepend` and `extend` docs:
|
||||
" https://github.com/othree/til/blob/master/vim/syntax-keepend-extend.md
|
||||
|
||||
" \@<= positive lookbehind
|
||||
" \@<! negative lookbehind
|
||||
" \@= positive lookahead
|
||||
" \@! negative lookahead
|
||||
|
||||
|
||||
|
||||
syntax case match
|
||||
|
||||
" <tag></tag>
|
||||
" s~~~~~~~~~~~e
|
||||
syntax region tsxRegion
|
||||
\ start=+\(\([a-zA-Z]\)\@<!<>\|\(\s\|[(]\s*\)\@<=\z(<[/a-zA-Z],\@!\([a-zA-Z0-9:\-],\@!\)*\)\)+
|
||||
\ skip=+<!--\_.\{-}-->+
|
||||
\ end=+</\_.\{-}>+
|
||||
\ end=+[a-zA-Z0-9.]*[/]*>\s*\n*\s*\n*\s*[});,]\@=+
|
||||
\ contains=tsxTag,tsxCloseTag,tsxComment,Comment,@Spell,tsxColon,tsxIfOperator,tsxElseOperator,jsBlock
|
||||
\ extend
|
||||
\ keepend
|
||||
|
||||
|
||||
|
||||
" Negative lookbacks for:
|
||||
" <> preceeded by [a-zA-Z]
|
||||
" <<Tag...
|
||||
" [a-zA-Z]<Tag
|
||||
|
||||
" end 1): handle </NormalClosingTag>
|
||||
" end 2): handle <SelfClosingTags/>\s*\n*\s*\n*\s*)
|
||||
" \s => spaces/tabs
|
||||
" \n => end-of-line => \n only match end of line in the buffer.
|
||||
" \s*\n*\s*\n*\s* => handles arbitrary spacing between closing tsxTag </tag>
|
||||
" and the ending brace for the scope: `}` or `)`
|
||||
"
|
||||
" \z( pattern \) Braces can be used to make a pattern into an atom.
|
||||
|
||||
" <tag>{content}</tag>
|
||||
" s~~~~~~~e
|
||||
syn region jsBlock
|
||||
\ start=+{+
|
||||
\ end=+}+
|
||||
\ contained
|
||||
\ contains=TOP
|
||||
|
||||
" \@<= positive lookbehind
|
||||
" \@<! negative lookbehind
|
||||
" \@= positive lookahead
|
||||
" \@! negative lookahead
|
||||
" RULE: capture expression, then apply rule AFTER
|
||||
" e.g foo\(bar\)\@!
|
||||
" match all `foo` which is not followed by `bar`
|
||||
" https://jbodah.github.io/blog/2016/11/01/positivenegative-lookaheadlookbehind-vim/
|
||||
|
||||
" <tag key={this.props.key}>
|
||||
" s~~~~~~~~~~~~~~e
|
||||
syntax region tsxJsBlock
|
||||
\ matchgroup=tsxAttributeBraces start=+\([=]\|\s\)\@<={+
|
||||
\ matchgroup=tsxAttributeBraces end=+}\(\s*}\|)\)\@!+
|
||||
\ contained
|
||||
\ keepend
|
||||
\ extend
|
||||
\ contains=TOP
|
||||
|
||||
" <tag id="sample">
|
||||
" s~~~~~~~~~~~~~~~e
|
||||
syntax region tsxTag
|
||||
\ start=+<[^ /!?<"'=:]\@=+
|
||||
\ end=+[/]\{0,1}>+
|
||||
\ contained
|
||||
\ contains=tsxTagName,tsxAttrib,tsxEqual,tsxString,tsxJsBlock,tsxAttributeComment,tsxGenerics
|
||||
|
||||
syntax region tsxGenerics
|
||||
\ matchgroup=tsxTypeBraces start=+\([<][_\-\.:a-zA-Z0-9]*\|[<][_\-\.:a-zA-Z0-9]*\)\@<=\s*[<]+
|
||||
\ matchgroup=tsxTypeBraces end=+>+
|
||||
\ contains=tsxTypes,tsxGenerics
|
||||
\ contained
|
||||
\ extend
|
||||
|
||||
syntax match tsxTypes /[_\.a-zA-Z0-9]/
|
||||
\ contained
|
||||
|
||||
" \@<! negative lookbehind
|
||||
|
||||
" <T1, T2>
|
||||
" s~~~~~~~e
|
||||
" For Generics outside of tsxRegion
|
||||
" Must come after tsxRegion in this file
|
||||
syntax region tsGenerics
|
||||
\ start=+<\([\[A-Z]\|typeof\)\([a-zA-Z0-9,{}\[\]'".=>():]\|\s\)*>\(\s*\n*\s*[()]\|\s*[=]\)+
|
||||
\ end=+\([=]\)\@<!>+
|
||||
\ contains=tsxTypes,tsxGenerics
|
||||
\ extend
|
||||
|
||||
" </tag>
|
||||
" ~~~~~~
|
||||
syntax region tsxCloseTag
|
||||
\ start=+</[^ /!?<"'=:]\@=+
|
||||
\ end=+>+
|
||||
|
||||
|
||||
" matches tsx Comments: {/* ..... /*}
|
||||
syn region Comment contained start=+{/\*+ end=+\*/}+ contains=Comment
|
||||
\ extend
|
||||
|
||||
syn region tsxAttributeComment contained start=+//+ end=+\n+ contains=Comment
|
||||
\ extend
|
||||
|
||||
syntax match tsxCloseString
|
||||
\ +\w\++
|
||||
\ contained
|
||||
|
||||
syntax match tsxColon
|
||||
\ +[;]+
|
||||
\ contained
|
||||
|
||||
" <!-- -->
|
||||
" ~~~~~~~~
|
||||
syntax match tsxComment /<!--\_.\{-}-->/ display
|
||||
syntax match tsxEntity "&[^; \t]*;" contains=tsxEntityPunct
|
||||
syntax match tsxEntityPunct contained "[&.;]"
|
||||
|
||||
" <MyComponent ...>
|
||||
" ~~~~~~~~~~~
|
||||
" NOT
|
||||
" <someCamel ...>
|
||||
" ~~~~~
|
||||
syntax match tsxComponentName
|
||||
\ +\<[_$]\?[A-Z][-_$A-Za-z0-9]*\>+
|
||||
\ contained
|
||||
\ display
|
||||
|
||||
syntax match tsxCloseComponentName
|
||||
\ +[</]\?[A-Z][-_$A-Za-z0-9]*\>+
|
||||
\ contained
|
||||
\ display
|
||||
|
||||
" <tag key={this.props.key}>
|
||||
" ~~~
|
||||
syntax match tsxTagName
|
||||
\ +[<]\@<=[^ /!?<>"']\++
|
||||
\ contained
|
||||
\ contains=tsxComponentName
|
||||
\ display
|
||||
|
||||
" </tag>
|
||||
" ~~~
|
||||
syntax match tsxCloseTagName
|
||||
\ +[</]\@<=[^ /!?<>"']\++
|
||||
\ containedin=tsxCloseTag
|
||||
\ contains=tsxCloseComponentName
|
||||
\ display
|
||||
|
||||
" <tag key={this.props.key}>
|
||||
" ~~~
|
||||
syntax match tsxAttrib
|
||||
\ +[-'"<]\@<!\<[a-zA-Z:_][-.0-9a-zA-Z0-9:_]*[/]\{0,1}\>\(['"]\@!\|$\)+
|
||||
\ contained
|
||||
\ keepend
|
||||
\ contains=tsxAttribPunct,tsxAttribHook
|
||||
\ display
|
||||
|
||||
syntax match tsxAttribPunct +[:.]+ contained display
|
||||
|
||||
" <tag id="sample">
|
||||
" ~
|
||||
syntax match tsxEqual +=+ contained display
|
||||
|
||||
" <tag id="sample">
|
||||
" s~~~~~~e
|
||||
syntax region tsxString contained start=+"+ end=+"+ contains=tsxEntity,@Spell display
|
||||
|
||||
" <tag id=`sample${var}`>
|
||||
syntax region tsxString contained start=+`+ end=+`+ contains=tsxEntity,@Spell display
|
||||
|
||||
" <tag id='sample'>
|
||||
" s~~~~~~e
|
||||
syntax region tsxString contained start=+'+ end=+'+ contains=tsxEntity,@Spell display
|
||||
|
||||
syntax match tsxIfOperator +?+
|
||||
syntax match tsxNotOperator +!+
|
||||
syntax match tsxElseOperator +:+
|
||||
|
||||
" highlight def link tsxTagName htmlTagName
|
||||
highlight def link tsxTagName xmlTagName
|
||||
highlight def link tsxComponentName xmlTagName
|
||||
highlight def link tsxCloseComponentName xmlTagName
|
||||
highlight def link tsxTag htmlTag
|
||||
highlight def link tsxCloseTag xmlEndTag
|
||||
highlight def link tsxCloseTagName xmlTagName
|
||||
highlight def link tsxRegionEnd xmlEndTag
|
||||
highlight def link tsxEqual htmlTag
|
||||
highlight def link tsxString String
|
||||
highlight def link tsxNameSpace Function
|
||||
highlight def link tsxComment Error
|
||||
highlight def link tsxAttrib htmlArg
|
||||
highlight def link tsxCloseString htmlTagName
|
||||
highlight def link tsxAttributeBraces htmlTag
|
||||
highlight def link tsxAttributeComment Comment
|
||||
highlight def link tsxColon typescriptEndColons
|
||||
|
||||
highlight def link tsxGenerics typescriptEndColons
|
||||
highlight def link tsGenerics tsxTypeBraces
|
||||
|
||||
highlight def link tsxIfOperator typescriptEndColons
|
||||
highlight def link tsxNotOperator typescriptEndColons
|
||||
highlight def link tsxElseOperator typescriptEndColons
|
||||
highlight def link tsxTypeBraces htmlTag
|
||||
highlight def link tsxTypes typescriptEndColons
|
||||
|
||||
" Custom React Highlights
|
||||
syn keyword ReactState state nextState prevState setState
|
||||
" Then EITHER (define your own colour scheme):
|
||||
" OR (make the colour scheme match an existing one):
|
||||
" hi link ReactKeywords typescriptRComponent
|
||||
syn keyword ReactProps props defaultProps ownProps nextProps prevProps
|
||||
syn keyword Events e event target value
|
||||
syn keyword ReduxKeywords dispatch payload
|
||||
syn keyword ReduxHooksKeywords useState useEffect useMemo useCallback
|
||||
syn keyword WebBrowser window localStorage
|
||||
syn keyword ReactLifeCycleMethods componentWillMount shouldComponentUpdate componentWillUpdate componentDidUpdate componentWillReceiveProps componentWillUnmount componentDidMount
|
||||
|
||||
let b:current_syntax = 'typescriptreact'
|
||||
|
||||
let &cpo = s:tsx_cpo
|
||||
unlet s:tsx_cpo
|
6
bundle/vim-jsx-typescript/ftdetect/typescript.vim
Normal file
6
bundle/vim-jsx-typescript/ftdetect/typescript.vim
Normal file
@ -0,0 +1,6 @@
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Vim ftdetect file
|
||||
" Language: TSX (Typescript)
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
autocmd BufNewFile,BufRead *.tsx setf typescriptreact
|
Loading…
Reference in New Issue
Block a user