├── README.md ├── plugin └── deoplete-flow.vim └── rplugin └── python3 └── deoplete └── sources └── flow.py /README.md: -------------------------------------------------------------------------------- 1 | # deoplete-flow 2 | 3 | A plugin for [deoplete](https://github.com/Shougo/deoplete.nvim) to get flow 4 | autocompletion functionality. 5 | 6 | ## Installation 7 | 8 | Currently only tested with NeoVim and Python3 client. 9 | Check out the deoplete documentation to get the basic setup. 10 | 11 | Install this plugin with your favourite plugin manager. 12 | 13 | Also make sure to install your `flow-bin` in your project directory: 14 | 15 | ``` 16 | npm install flow-bin 17 | ``` 18 | 19 | ## Configuration 20 | 21 | ``` 22 | # Binary path to your flow, defaults to your $PATH flow 23 | let g:deoplete#sources#flow#flow_bin = 'flow' 24 | ``` 25 | 26 | **Local vs. global flow-bin**: 27 | 28 | Most of the time you will probably want your `flow-bin` installed in your 29 | `node_modules` directory of your current project. This example configuration 30 | will preferably take the local version before the global one: 31 | 32 | ``` 33 | function! StrTrim(txt) 34 | return substitute(a:txt, '^\n*\s*\(.\{-}\)\n*\s*$', '\1', '') 35 | endfunction 36 | 37 | let g:flow_path = StrTrim(system('PATH=$(npm bin):$PATH && which flow')) 38 | 39 | if g:flow_path != 'flow not found' 40 | let g:deoplete#sources#flow#flow_bin = g:flow_path 41 | endif 42 | ``` 43 | -------------------------------------------------------------------------------- /plugin/deoplete-flow.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_deoplete_flow') 2 | finish 3 | endif 4 | 5 | let g:loaded_deoplete_flow = 1 6 | 7 | let g:deoplete#sources#flow#flow_bin = get(g:, 'deoplete#sources#flow#flow_bin', 'flow') 8 | -------------------------------------------------------------------------------- /rplugin/python3/deoplete/sources/flow.py: -------------------------------------------------------------------------------- 1 | import json 2 | import deoplete.util 3 | 4 | from deoplete.logger import getLogger 5 | from subprocess import Popen, PIPE 6 | from .base import Base 7 | 8 | log = getLogger('logging') 9 | 10 | class Source(Base): 11 | def __init__(self, vim): 12 | Base.__init__(self, vim); 13 | 14 | self.flow_bin = self.vim.vars['deoplete#sources#flow#flow_bin'] or 'flow' 15 | self.rank = 600 16 | self.name = 'flow' 17 | self.mark = '[FL]' 18 | self.min_pattern_length = 0 19 | self.filetypes = ['javascript'] 20 | 21 | def get_complete_position(self, context): 22 | pos = context['input'].rfind('.') 23 | return pos if pos < 0 else pos + 1 24 | 25 | def gather_candidates(self, context): 26 | line = str(self.vim.current.window.cursor[0]) 27 | column = str(self.vim.current.window.cursor[1] + 1) 28 | command = [self.flow_bin, 'autocomplete', '--json', '--no-auto-start', line, column] 29 | 30 | log.debug(command) 31 | buf = '\n'.join(self.vim.current.buffer[:]) 32 | 33 | try: 34 | process = Popen(command, stdout=PIPE, stdin=PIPE) 35 | command_results = process.communicate(input=str.encode(buf))[0] 36 | 37 | if process.returncode != 0: 38 | return [] 39 | 40 | results = json.loads(command_results.decode('utf-8')) 41 | 42 | return [{'word': x['name'], 'kind': x['type']} for x in results['result']] 43 | except FileNotFoundError: 44 | pass # ignore file not found error 45 | --------------------------------------------------------------------------------