Merge commit 'abb5c708307e3d1c77c6708b79affed1a807d6ea' as 'vim/bundle/flow'

Buddy Sandidge 8 years ago
commit a6242f4c60

@ -0,0 +1 @@
doc/tags

@ -0,0 +1,30 @@
BSD License
For vim-flow software
Copyright (c) 2013, Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,23 @@
Additional Grant of Patent Rights
"Software" means the vim-flow software distributed by Facebook, Inc.
Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive,
irrevocable (subject to the termination provision below) license under any
rights in any patent claims owned by Facebook, to make, have made, use, sell,
offer to sell, import, and otherwise transfer the Software. For avoidance of
doubt, no license is granted under Facebook's rights in any patent claims that
are infringed by (i) modifications to the Software made by you or a third party,
or (ii) the Software in combination with any software or other technology
provided by you or a third party.
The license granted hereunder will terminate, automatically and without notice,
for anyone that makes any claim (including by filing any lawsuit, assertion or
other action) alleging (a) direct, indirect, or contributory infringement or
inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or
affiliates, whether or not such claim is related to the Software, (ii) by any
party if such claim arises in whole or in part from any software, product or
service of Facebook or any of its subsidiaries or affiliates, whether or not
such claim is related to the Software, or (iii) by any party relating to the
Software; or (b) that any right in any patent claim of Facebook is invalid or
unenforceable.

@ -0,0 +1,128 @@
# vim-flow
A vim plugin for [Flow][flow].
- Adds completions to `omnifunc`
- Checks JavaScript files for type errors on save
## Requirements
- Requires [Flow][flow] to be installed and available on your path
- Requires the project to be initialised with `flow init`
- Requires JavaScript files to be marked with `/* @flow */` or `/* @flow weak */` at the top
## Installation
### [Pathogen][pathogen]
cd ~/.vim/bundle
git clone git://github.com/flowtype/vim-flow.git
### [NeoBundle][neobundle]
Add this to your `~/.vimrc`
```VimL
NeoBundleLazy 'flowtype/vim-flow', {
\ 'autoload': {
\ 'filetypes': 'javascript'
\ }}
```
#### With [Flow][flow] build step, using [flow-bin][flowbin]
```VimL
NeoBundleLazy 'flowtype/vim-flow', {
\ 'autoload': {
\ 'filetypes': 'javascript'
\ },
\ 'build': {
\ 'mac': 'npm install -g flow-bin',
\ 'unix': 'npm install -g flow-bin'
\ }}
```
## Usage
Unless [disabled manually][gflowenable], vim-flow will check JavaScript and JSX files on save.
## Commands
#### `FlowMake`
Triggers a type check for the current file.
#### `FlowToggle`
Turns automatic checks on save on or off.
#### `FlowType`
Display the type of the variable under the cursor.
#### `FlowJumpToDef`
Jump to the definition of the variable under the cursor.
## Configuration
#### `g:flow#autoclose`
If this is set to `1`, the |quickfix| window opened when the plugin finds an error
will close automatically.
Default is `0`.
#### `g:flow#enable`
Typechecking is done automatically on `:w` if set to `1`.
To disable this, set to `0` in your ~/.vimrc, like so:
```VimL
let g:flow#enable = 0
```
Default is `1`.
#### `g:flow#errjmp`
Jump to errors after typechecking if set to `1`.
Default is `0`.
#### `g:flow#flowpath`
Leave this as default to use the flow executable defined on your path. To use
a custom flow executable, set this like so:
```VimL
let g:flow#flowpath = /your/flow-path/flow
```
#### `g:flow#omnifunc`
By default `omnifunc` will be set to provide omni completion. To disable it
(prevent overwriting an existed omnifunc), set this value to 0:
```VimL
let g:flow#omnifunc = 0
```
#### `g:flow#timeout`
By default `timeout` will be set to 2 seconds. If you are working on a larger
codebase, you may want to increase this to avoid errors when Flow initializes.
```VimL
let g:flow#timeout = 4
```
#### `g:flow#qfsize`
Leave this as default to let the plugin decide on the quickfix window size.
[gflowenable]: https://github.com/flowtype/vim-flow#gflowenable
[flow]: https://github.com/facebook/flow
[flowbin]: https://github.com/sindresorhus/flow-bin
[pathogen]: https://github.com/tpope/vim-pathogen
[neobundle]: https://github.com/Shougo/neobundle.vim

@ -0,0 +1,15 @@
" Vim filetype plugin
" Require the flow executable.
if !executable('flow')
finish
endif
" Omnicompletion.
if !exists("g:flow#omnifunc")
let g:flow#omnifunc = 1
endif
if exists('&omnifunc') && g:flow#omnifunc
setl omnifunc=flowcomplete#Complete
endif

@ -0,0 +1,74 @@
" Vim completion script
"
" This source code is licensed under the BSD-style license found in the
" LICENSE file in the toplevel directory of this source tree. An additional
" grant of patent rights can be found in the PATENTS file in the same
" directory.
" Magical flow autocomplete token.
let s:autotok = 'AUTO332'
" Omni findstart phase.
function! s:FindStart()
let line = getline('.')
let start = col('.') - 1
while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]'
let start -= 1
endwhile
return start
endfunction
function! flowcomplete#Complete(findstart, base)
if a:findstart
return s:FindStart()
endif
let lnum = line('.')
let cnum = col('.')
let lines = getline(1, '$')
" Insert the base and magic token into the current line.
let curline = lines[lnum - 1]
let lines[lnum - 1] = curline[:cnum - 1] . a:base . s:autotok . curline[cnum :]
" Pass the buffer to flow.
let buffer = join(lines, "\n")
let command = g:flow#flowpath.' autocomplete '.expand('%:p')
let result = system(command, buffer)
if result =~ '^Error: not enough type information to autocomplete' ||
\ result =~ '^Could not find file or directory'
return []
endif
let matches = []
" Parse the flow output.
for line in split(result, "\n")
if empty(line) | continue | endif
let entry = {}
let space = stridx(line, ' ')
let word = line[:space - 1]
let type = line[space + 1 :]
" Skip matches that don't start with the base"
if (stridx(word, a:base) != 0) | continue | endif
" This is pretty hacky. We're using regexes to recognize the different
" kind of matches. Really in the future we should somehow consume the json
" output
if type =~ '^(.*) =>'
let entry = { 'word': word, 'kind': a:base, 'menu': type }
elseif type =~ '^[class:'
let entry = { 'word': word, 'kind': 'c', 'menu': type }
else
let entry = { 'word': word, 'kind': 'v', 'menu': type }
endif
call add(matches, entry)
endfor
return matches
endfunction

@ -0,0 +1,52 @@
*vim-flow.txt*
*vim-flow*
==============================================================================
CONTENTS *vim-flow-contents*
Variables |vim-flow-variables|
------------------------------------------------------------------------------
VARIABLES *vim-flow-variables*
g:flow#autoclose *g:flow#autoclose*
If this is set to 1, the |quickfix| window opened when the plugin finds an error
will close automatically.
Default is 0.
g:flow#enable *g:flow#enable*
Typechecking is done automatically on :w if set to 1.
To disable this, set to 0 in your ~/.vimrc, like so:
let g:flow#enable = 0
Default is 1.
g:flow#errjmp *g:flow#errjmp*
Jump to errors after typechecking if set to 1.
Default is 0.
g:flow#flowpath *g:flow#flowpath*
Leave this as default to use the flow executable defined on your path. To use
a custom flow executable, set this like so:
let g:flow#flowpath = /your/flow-path/flow
g:flow#omnifunc *g:flow#omnifunc*
By default 'omnifunc' will be set to provide omni completion. To disable it
(prevent overwriting an existed omnifunc), set this value to 0:
let g:flow#omnifunc = 0
g:flow#qfsize *g:flow#qfsize*
Leave this as default to let the plugin decide on the |quickfix| window size.
vim:tw=78:ts=8:ft=help:norl:

@ -0,0 +1,192 @@
" flow.vim - Flow typechecker integration for vim
if exists("g:loaded_flow")
finish
endif
let g:loaded_flow = 1
" Configuration switches:
" - enable: Typechecking is done on :w.
" - autoclose: Quickfix window closes automatically.
" - errjmp: Jump to errors after typechecking; default off.
" - qfsize: Let the plugin control the quickfix window size.
" - flowpath: Path to the flow executable - default is flow in path
if !exists("g:flow#enable")
let g:flow#enable = 1
endif
if !exists("g:flow#autoclose")
let g:flow#autoclose = 0
endif
if !exists("g:flow#errjmp")
let g:flow#errjmp = 0
endif
if !exists("g:flow#qfsize")
let g:flow#qfsize = 1
endif
if !exists("g:flow#flowpath")
let g:flow#flowpath = "flow"
endif
if !exists("g:flow#timeout")
let g:flow#timeout = 2
endif
" Require the flow executable.
if !executable(g:flow#flowpath)
finish
endif
" flow error format.
let s:flow_errorformat = '%EFile "%f"\, line %l\, characters %c-%.%#,%Z%m,'
" flow from editor.
let s:flow_from = '--from vim'
" Call wrapper for flow.
function! <SID>FlowClientCall(cmd, suffix)
" Invoke typechecker.
" We also concatenate with the empty string because otherwise
" cgetexpr complains about not having a String argument, even though
" type(flow_result) == 1.
let command = g:flow#flowpath.' '.a:cmd.' '.s:flow_from.' '.a:suffix
let flow_result = system(command)
" Handle the server still initializing
if v:shell_error == 1
echohl WarningMsg
echomsg 'Flow server is still initializing...'
echohl None
cclose
return 0
endif
" Handle timeout
if v:shell_error == 3
echohl WarningMsg
echomsg 'Flow timed out, please try again!'
echohl None
cclose
return 0
endif
return flow_result
endfunction
" Main interface functions.
function! flow#typecheck()
" Flow current outputs errors to stderr and gets fancy with single character
" files
let flow_result = <SID>FlowClientCall('--timeout '.g:flow#timeout.' --retry-if-init false'.expand('%:p'), '2> /dev/null')
let old_fmt = &errorformat
let &errorformat = s:flow_errorformat
if g:flow#errjmp
cexpr flow_result
else
cgetexpr flow_result
endif
if g:flow#autoclose
botright cwindow
else
botright copen
endif
let &errorformat = old_fmt
endfunction
" Get the Flow type at the current cursor position.
function! flow#get_type()
let pos = fnameescape(expand('%')).' '.line('.').' '.col('.')
let cmd = g:flow#flowpath.' type-at-pos '.pos
let output = 'FlowType: '.system(cmd)
let output = substitute(output, '\n$', '', '')
echo output
endfunction
" Toggle auto-typecheck.
function! flow#toggle()
if g:flow#enable
let g:flow#enable = 0
else
let g:flow#enable = 1
endif
endfunction
" Jump to Flow definition for the current cursor position
function! flow#jump_to_def()
let pos = fnameescape(expand('%')).' '.line('.').' '.col('.')
let flow_result = <SID>FlowClientCall('get-def '.pos, '')
" Output format is:
" File: "/path/to/file", line 1, characters 1-11
" Flow returns a single line-feed if no result
if strlen(flow_result) == 1
echo 'No definition found'
return
endif
let parts = split(flow_result, ",")
if len(parts) < 2
echo 'cannot find definition'
return
endif
" File: "/path/to/file" => /path/to/file
let file = substitute(substitute(parts[0], '"', '', 'g'), 'File ', '', '')
" line 1 => 1
let row = split(parts[1], " ")[1]
" characters 1-11 => 1
let col = 0
if len(parts) == 3
let col = split(split(parts[2], " ")[1], "-")[0]
endif
if filereadable(file)
execute 'edit' file
call cursor(row, col)
end
endfunction
" Open importers of current file in quickfix window
function! flow#get_importers()
let flow_result = <SID>FlowClientCall('get-importers '.expand('%').' --strip-root', '')
let importers = split(flow_result, '\n')[1:1000]
let l:flow_errorformat = '%f'
let old_fmt = &errorformat
let &errorformat = l:flow_errorformat
if g:flow#errjmp
cexpr importers
else
cgetexpr importers
endif
if g:flow#autoclose
botright cwindow
else
botright copen
endif
let &errorformat = old_fmt
endfunction
" Commands and auto-typecheck.
command! FlowToggle call flow#toggle()
command! FlowMake call flow#typecheck()
command! FlowType call flow#get_type()
command! FlowJumpToDef call flow#jump_to_def()
command! FlowGetImporters call flow#get_importers()
au BufWritePost *.js,*.jsx if g:flow#enable | call flow#typecheck() | endif
" Keep quickfix window at an adjusted height.
function! <SID>AdjustWindowHeight(minheight, maxheight)
exe max([min([line("$"), a:maxheight]), a:minheight]) . "wincmd _"
endfunction
au FileType qf if g:flow#qfsize | call <SID>AdjustWindowHeight(3, 10) | endif
Loading…
Cancel
Save