Repository: peitalin/vim-jsx-typescript
Branch: master
Commit: 22df470d9265
Files: 7
Total size: 16.1 KB
Directory structure:
gitextract_e875e2p0/
├── .gitignore
├── LICENSE
├── README.md
├── after/
│ ├── ftplugin/
│ │ └── typescriptreact.vim
│ ├── indent/
│ │ └── typescriptreact.vim
│ └── syntax/
│ └── typescriptreact.vim
└── ftdetect/
└── typescript.vim
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
================================================
FILE: LICENSE
================================================
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>
================================================
FILE: README.md
================================================
# vim-jsx-typescript
Syntax highlighting and indentation for JSX in Typescript (`typescriptreact` filetypes).
`vim-jsx-typescript` works with the built-in typescript syntax highlighter and indentation engine for recent versions of Vim/Neovim.
**Changelog: filetypes were updated from typescript.tsx to typescriptreact**
**Please set filetypes as typescriptreact, not typescript.tsx as in prior versions in your .vimrc if you have any issues**
```
" set filetypes as typescriptreact
autocmd BufNewFile,BufRead *.tsx,*.jsx set filetype=typescriptreact
```


## Installation
You need to install [Vundle] or [vim-plug]: `https://github.com/junegunn/vim-plug` --- just add the following lines to your `~/.vimrc`:
### Vundle:
```
Plugin 'leafgarland/typescript-vim'
Plugin 'peitalin/vim-jsx-typescript'
```
### Vim-plug:
```
Plug 'leafgarland/typescript-vim'
Plug 'peitalin/vim-jsx-typescript'
```
To install from within vim, use the commands below.
```
:so ~/.vimrc
:PluginInstall
" OR for vim-plug:
:so ~/.vimrc
:PlugInstall
```
Note you can include .jsx files as typescriptreact files for syntax highlighting.
```
" set filetypes as typescriptreact
autocmd BufNewFile,BufRead *.tsx,*.jsx set filetype=typescriptreact
```
Set jsx-tag colors in vimrc, for example:
```
" dark red
hi tsxTagName guifg=#E06C75
hi tsxComponentName guifg=#E06C75
hi tsxCloseComponentName guifg=#E06C75
" orange
hi tsxCloseString guifg=#F99575
hi tsxCloseTag guifg=#F99575
hi tsxCloseTagName guifg=#F99575
hi tsxAttributeBraces guifg=#F99575
hi tsxEqual guifg=#F99575
" yellow
hi tsxAttrib guifg=#F8BD7F cterm=italic
```

There is support for JSX Generics (Typescript 2.9). You can set the colors by adding this to your .vimrc settings
```
" light-grey
hi tsxTypeBraces guifg=#999999
" dark-grey
hi tsxTypes guifg=#666666
```


Other keywords you can change coloring:
```
hi ReactState guifg=#C176A7
hi ReactProps guifg=#D19A66
hi ApolloGraphQL guifg=#CB886B
hi Events ctermfg=204 guifg=#56B6C2
hi ReduxKeywords ctermfg=204 guifg=#C678DD
hi ReduxHooksKeywords ctermfg=204 guifg=#C176A7
hi WebBrowser ctermfg=204 guifg=#56B6C2
hi ReactLifeCycleMethods ctermfg=204 guifg=#D19A66
```
================================================
FILE: after/ftplugin/typescriptreact.vim
================================================
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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
================================================
FILE: after/indent/typescriptreact.vim
================================================
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 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
================================================
FILE: after/syntax/typescriptreact.vim
================================================
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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
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
================================================
FILE: ftdetect/typescript.vim
================================================
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Vim ftdetect file
" Language: TSX (Typescript)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
autocmd FileType typescriptreact setlocal commentstring={/*\ %s\ */}
autocmd BufNewFile,BufRead *.tsx set filetype=typescriptreact
gitextract_e875e2p0/
├── .gitignore
├── LICENSE
├── README.md
├── after/
│ ├── ftplugin/
│ │ └── typescriptreact.vim
│ ├── indent/
│ │ └── typescriptreact.vim
│ └── syntax/
│ └── typescriptreact.vim
└── ftdetect/
└── typescript.vim
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
{
"path": ".gitignore",
"chars": 10,
"preview": ".DS_Store\n"
},
{
"path": "LICENSE",
"chars": 1210,
"preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
},
{
"path": "README.md",
"chars": 2306,
"preview": "# vim-jsx-typescript\n\nSyntax highlighting and indentation for JSX in Typescript (`typescriptreact` filetypes).\n\n`vim-jsx"
},
{
"path": "after/ftplugin/typescriptreact.vim",
"chars": 425,
"preview": "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" Vim ftplugin file\n\"\n\" Language: TSX (TypeS"
},
{
"path": "after/indent/typescriptreact.vim",
"chars": 5121,
"preview": "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" \" Vim indent file\n\"\n\" Language: typescriptre"
},
{
"path": "after/syntax/typescriptreact.vim",
"chars": 7121,
"preview": "\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" Vim syntax file\n\"\n\" Language: TSX (TypeSc"
},
{
"path": "ftdetect/typescript.vim",
"chars": 333,
"preview": "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" Vim ftdetect file\n\" Language: TSX (Typescr"
}
]
About this extraction
This page contains the full source code of the peitalin/vim-jsx-typescript GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (16.1 KB), approximately 5.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.