diff --git a/dotfiles/.vim/plugged/vim-jsx/.gitrepo b/dotfiles/.vim/plugged/vim-jsx/.gitrepo new file mode 100644 index 00000000..f9afc7c4 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/mxw/vim-jsx.git + branch = master + commit = 8879e0d9c5ba0e04ecbede1c89f63b7a0efa24af + parent = 066343f60ac25d3ebbe21608fd2d28df72643105 + method = merge + cmdver = 0.4.3 diff --git a/dotfiles/.vim/plugged/vim-jsx/README.md b/dotfiles/.vim/plugged/vim-jsx/README.md new file mode 100644 index 00000000..26315634 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/README.md @@ -0,0 +1,158 @@ +vim-jsx +======= + +**IMPORTANT**: This package is deprecated! It apparently broke following +changes to the [pangloss/vim-javascript][2] JavaScript syntax package circa +early 2019. As someone who has (perhaps surprisingly) never written a single +line of JSX or React code except to test this package, I don't closely track +breaking changes like these, hence the (lamentable) inactivity in this repo. + +Fortunately, the community seems to have settled on +[MaxMEllon/vim-jsx-pretty][6] as the syntax package of choice for up-to-date +JSX support. If you're not writing exclusively pre-2019 JavaScript with +pre-2019 tooling, consider switching over to that package. + +Thanks for following along here, and I hope this package was useful to folks in +the years since React first debuted. + +If things change and this package becomes actively maintained again, I'll be +sure to update this note. + +Introduction +------------ + +Syntax highlighting and indenting for JSX. JSX is a JavaScript syntax +transformer which translates inline XML document fragments into JavaScript +objects. It was developed by Facebook alongside [React][1]. + +vim-jsx is _not_ a JavaScript syntax package, so in order to use it, you will +also need to choose a base JS highlighter. [pangloss/vim-javascript][2] is the +recommended package---it is vim-jsx's "official" dependency, and the only +package against which it is regularly tested. However, vim-jsx makes a best +effort to support other JavaScript syntax packages, including: +- pangloss/vim-javascript +- jelera/vim-javascript-syntax +- othree/yajs + +Notably, the system vim JavaScript syntax is _not_ supported, due to its +over-simplicity. However, the system XML syntax package is an implicit +dependency. + +Vim support for inline XML in JS is remarkably similar to the same for PHP, +which you can find [here][3]. + +Troubleshooting +--------------- + +If you're experiencing incorrect highlighting or indenting in your JSX code, +please file a GitHub issue which includes the following: + +- A brief affirmation that you've read the README and have installed one of the + supported dependencies (and the name of the one you're using). + +- A minimal ~/.vimrc which repros the issue you're having, as well as both a + paste and a screenshot of the issue (a paste alone is insufficient, since it + doesn't illustrate the specific highlighting or indenting problem). To + obtain a minimal ~/.vimrc, simply bisect your ~/.vimrc by adding `finish` at + various points in the file. (You can likewise bisect your included plugins + by selectively including only half of them, then a quarter, etc.). + +Most of the issues filed result from failures to install vim-javascript or +conflicts with existing JS syntax or indent files---so failing to indicate that +you've ruled those issues out may result in your issue being closed with +minimal comment. + +(Please feel free to disregard all this for feature requests.) + +Usage +----- + +By default, JSX syntax highlighting and indenting will be enabled for +files with the `.js` and `.jsx` extension. If you would like JSX only in `.jsx` files, add + +```viml +let g:jsx_ext_required = 1 +``` + +to your .vimrc or somewhere in your include path. If you wish to restrict JSX +to files with the pre-v0.12 `@jsx React.DOM` pragma, add + +```viml +let g:jsx_pragma_required = 1 +``` + +to your .vimrc or somewhere in your include path. + +Frequently Asked Questions +-------------------------- + +- _How come syntax highlighting doesn't work at all?_ + +This is the only question I'll answer with another question---Which do you +think is more likely: (a) this package fails completely and utterly in serving +its most fundamental purpose, or (b) user error? + +- _Why are my end tags colored differently than my start tags?_ + +vim-jsx is basically the glue that holds JavaScript and XML syntax packages +together in blissful harmony. This means that any XML syntax defaults carry +over to the XML portions of vim, and it's common for many colorschemes to +highlight start and end tags differently due to the system XML syntax defaults. + +- _Syntax highlighting seems to work, but breaks highlighting and indenting + further down in the file. What's wrong?_ + +This often results from trying to enable XML folding in one's `~/.vimrc` (i.e., +via `let g:xml_syntax_folding = 1`). vim-jsx does not support syntax folding, +and is not tested with either JavaScript or XML folding enabled. + +Installation +------------ + +### Pathogen + +The recommended installation method is via [Pathogen][4]. Then simply execute + + git clone https://github.com/mxw/vim-jsx.git ~/.vim/bundle/vim-jsx + +(You can install [vim-javascript][2] in an analogous manner.) + +### Vundle + +You can also add vim-jsx using [Vundle][5]---just add the following lines to +your `~/.vimrc`: + + Plugin 'pangloss/vim-javascript' + Plugin 'mxw/vim-jsx' + +To install from within vim, use the commands below. + + :so ~/.vimrc + :PluginInstall + +Alternatively, use the command below to install the plugins from the command +line. + + vim +PluginInstall +qall + +### Manual Installation + +If you have no `~/.vim/after` directory, you can download the tarball or zip +and copy the contents to `~/.vim`. + +If you have existing `~/.vim/after` files, copy the syntax and indent files +directly into their respective destinations. If you have existing after syntax +or indent files for Javascript, you'll probably want to do something like + + mkdir -p ~/.vim/after/syntax/javascript + cp path/to/vim-jsx/after/syntax/jsx.vim ~/.vim/after/syntax/javascript/jsx.vim + mkdir -p ~/.vim/after/indent/javascript + cp path/to/vim-jsx/after/indent/jsx.vim ~/.vim/after/indent/javascript/jsx.vim + + +[1]: http://facebook.github.io/react/ "React" +[2]: https://github.com/pangloss/vim-javascript "pangloss: vim-javascript" +[3]: https://github.com/mxw/vim-xhp "mxw: vim-xhp" +[4]: https://github.com/tpope/vim-pathogen "tpope: vim-pathogen" +[5]: https://github.com/VundleVim/Vundle.vim "VundleVim: Vundle.vim" +[6]: https://github.com/MaxMEllon/vim-jsx-pretty "MaxMEllon: vim-jsx-pretty" diff --git a/dotfiles/.vim/plugged/vim-jsx/after/ftplugin/jsx.vim b/dotfiles/.vim/plugged/vim-jsx/after/ftplugin/jsx.vim new file mode 100644 index 00000000..f9329fc4 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/after/ftplugin/jsx.vim @@ -0,0 +1,19 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim ftplugin file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" modified from html.vim +if exists("loaded_matchit") + let b:match_ignorecase = 0 + let s:jsx_match_words = '(:),\[:\],{:},<:>,' . + \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(/\@\|$\):<\@<=/\1>' + let b:match_words = exists('b:match_words') + \ ? b:match_words . ',' . s:jsx_match_words + \ : s:jsx_match_words +endif + +setlocal suffixesadd+=.jsx diff --git a/dotfiles/.vim/plugged/vim-jsx/after/indent/jsx.vim b/dotfiles/.vim/plugged/vim-jsx/after/indent/jsx.vim new file mode 100644 index 00000000..9c1a1ac6 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/after/indent/jsx.vim @@ -0,0 +1,114 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim indent file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" Save the current JavaScript indentexpr. +let b:jsx_js_indentexpr = &indentexpr + +" Prologue; load in XML indentation. +if exists('b:did_indent') + let s:did_indent=b:did_indent + unlet b:did_indent +endif +exe 'runtime! indent/xml.vim' +if exists('s:did_indent') + let b:did_indent=s:did_indent +endif + +setlocal indentexpr=GetJsxIndent() + +" JS indentkeys +setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e +" XML indentkeys +setlocal indentkeys+=*,<>>,<<>,/ + +" Multiline end tag regex (line beginning with '>' or '/>') +let s:endtag = '^\s*\/\?>\s*;\=' + +" Get all syntax types at the beginning of a given line. +fu! SynSOL(lnum) + return map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') +endfu + +" Get all syntax types at the end of a given line. +fu! SynEOL(lnum) + let lnum = prevnonblank(a:lnum) + let col = strlen(getline(lnum)) + return map(synstack(lnum, col), 'synIDattr(v:val, "name")') +endfu + +" Check if a syntax attribute is XMLish. +fu! SynAttrXMLish(synattr) + return a:synattr =~ "^xml" || a:synattr =~ "^jsx" +endfu + +" Check if a synstack is XMLish (i.e., has an XMLish last attribute). +fu! SynXMLish(syns) + return SynAttrXMLish(get(a:syns, -1)) +endfu + +" Check if a synstack denotes the end of a JSX block. +fu! SynJSXBlockEnd(syns) + return get(a:syns, -1) =~ '\%(js\|javascript\)Braces' && + \ SynAttrXMLish(get(a:syns, -2)) +endfu + +" Determine how many jsxRegions deep a synstack is. +fu! SynJSXDepth(syns) + return len(filter(copy(a:syns), 'v:val ==# "jsxRegion"')) +endfu + +" Check whether `cursyn' continues the same jsxRegion as `prevsyn'. +fu! SynJSXContinues(cursyn, prevsyn) + let curdepth = SynJSXDepth(a:cursyn) + let prevdepth = SynJSXDepth(a:prevsyn) + + " In most places, we expect the nesting depths to be the same between any + " two consecutive positions within a jsxRegion (e.g., between a parent and + " child node, between two JSX attributes, etc.). The exception is between + " sibling nodes, where after a completed element (with depth N), we return + " to the parent's nesting (depth N - 1). This case is easily detected, + " since it is the only time when the top syntax element in the synstack is + " jsxRegion---specifically, the jsxRegion corresponding to the parent. + return prevdepth == curdepth || + \ (prevdepth == curdepth + 1 && get(a:cursyn, -1) ==# 'jsxRegion') +endfu + +" Cleverly mix JS and XML indentation. +fu! GetJsxIndent() + let cursyn = SynSOL(v:lnum) + let prevsyn = SynEOL(v:lnum - 1) + + " Use XML indenting iff: + " - the syntax at the end of the previous line was either JSX or was the + " closing brace of a jsBlock whose parent syntax was JSX; and + " - the current line continues the same jsxRegion as the previous line. + if (SynXMLish(prevsyn) || SynJSXBlockEnd(prevsyn)) && + \ SynJSXContinues(cursyn, prevsyn) + let ind = XmlIndentGet(v:lnum, 0) + + " Align '/>' and '>' with '<' for multiline tags. + if getline(v:lnum) =~? s:endtag + let ind = ind - &sw + endif + + " Then correct the indentation of any JSX following '/>' or '>'. + if getline(v:lnum - 1) =~? s:endtag + let ind = ind + &sw + endif + else + if len(b:jsx_js_indentexpr) + " Invoke the base JS package's custom indenter. (For vim-javascript, + " e.g., this will be GetJavascriptIndent().) + let ind = eval(b:jsx_js_indentexpr) + else + let ind = cindent(v:lnum) + endif + endif + + return ind +endfu diff --git a/dotfiles/.vim/plugged/vim-jsx/after/syntax/jsx.vim b/dotfiles/.vim/plugged/vim-jsx/after/syntax/jsx.vim new file mode 100644 index 00000000..94232665 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/after/syntax/jsx.vim @@ -0,0 +1,65 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim syntax file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang +" Depends: pangloss/vim-javascript +" +" CREDITS: Inspired by Facebook. +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" Prologue; load in XML syntax. +if exists('b:current_syntax') + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif +syn include @XMLSyntax syntax/xml.vim +if exists('s:current_syntax') + let b:current_syntax=s:current_syntax +endif + +" Officially, vim-jsx depends on the pangloss/vim-javascript syntax package +" (and is tested against it exclusively). However, in practice, we make some +" effort towards compatibility with other packages. +" +" These are the plugin-to-syntax-element correspondences: +" +" - pangloss/vim-javascript: jsBlock, jsExpression +" - jelera/vim-javascript-syntax: javascriptBlock +" - othree/yajs.vim: javascriptNoReserved + + +" JSX attributes should color as JS. Note the trivial end pattern; we let +" jsBlock take care of ending the region. +syn region xmlString contained start=+{+ end=++ contains=jsBlock,javascriptBlock + +" JSX comments inside XML tag should color as comment. Note the trivial end pattern; we let +" jsComment take care of ending the region. +syn region xmlString contained start=+//+ end=++ contains=jsComment + +" JSX child blocks behave just like JSX attributes, except that (a) they are +" syntactically distinct, and (b) they need the syn-extend argument, or else +" nested XML end-tag patterns may end the outer jsxRegion. +syn region jsxChild contained start=+{+ end=++ contains=jsBlock,javascriptBlock + \ extend + +" Highlight JSX regions as XML; recursively match. +" +" Note that we prohibit JSX tags from having a < or word character immediately +" preceding it, to avoid conflicts with, respectively, the left shift operator +" and generic Flow type annotations (http://flowtype.org/). +syn region jsxRegion + \ contains=@Spell,@XMLSyntax,jsxRegion,jsxChild,jsBlock,javascriptBlock + \ start=+\%(<\|\w\)\@[:,]\@!\)\([^>]*>(\)\@!+ + \ skip=++ + \ end=++ + \ end=+/>+ + \ keepend + \ extend + +" Add jsxRegion to the lowest-level JS syntax cluster. +syn cluster jsExpression add=jsxRegion + +" Allow jsxRegion to contain reserved words. +syn cluster javascriptNoReserved add=jsxRegion diff --git a/dotfiles/.vim/plugged/vim-jsx/ftdetect/javascript.vim b/dotfiles/.vim/plugged/vim-jsx/ftdetect/javascript.vim new file mode 100644 index 00000000..c55e0233 --- /dev/null +++ b/dotfiles/.vim/plugged/vim-jsx/ftdetect/javascript.vim @@ -0,0 +1,37 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim ftdetect file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" Whether the .jsx extension is required. +if !exists('g:jsx_ext_required') + let g:jsx_ext_required = 0 +endif + +" Whether the @jsx pragma is required. +if !exists('g:jsx_pragma_required') + let g:jsx_pragma_required = 0 +endif + +let s:jsx_pragma_pattern = '\%^\_s*\/\*\*\%(\_.\%(\*\/\)\@!\)*@jsx\_.\{-}\*\/' + +" Whether to set the JSX filetype on *.js files. +fu! EnableJSX() + if g:jsx_pragma_required && !exists('b:jsx_ext_found') + " Look for the @jsx pragma. It must be included in a docblock comment + " before anything else in the file (except whitespace). + let b:jsx_pragma_found = search(s:jsx_pragma_pattern, 'npw') + endif + + if g:jsx_pragma_required && !b:jsx_pragma_found | return 0 | endif + if g:jsx_ext_required && !exists('b:jsx_ext_found') | return 0 | endif + return 1 +endfu + +autocmd BufNewFile,BufRead *.jsx let b:jsx_ext_found = 1 +autocmd BufNewFile,BufRead *.jsx set filetype=javascript.jsx +autocmd BufNewFile,BufRead *.js + \ if EnableJSX() | set filetype=javascript.jsx | endif