├── .gitignore ├── LICENSE ├── README.md └── rplugin └── python3 └── deoplete └── source └── phpactor.py /.gitignore: -------------------------------------------------------------------------------- 1 | .mypy_cache 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kristijan Husak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deoplete-phpactor 2 | [Phpactor](https://github.com/phpactor/phpactor) integration for [deoplete.nvim](https://github.com/Shougo/deoplete.nvim) 3 | 4 | 5 | ## Installation 6 | 7 | Using [vim-plug](https://github.com/junegunn/vim-plug) 8 | 9 | ``` 10 | Plug 'Shougo/deoplete.nvim' 11 | Plug 'phpactor/phpactor' , {'do': 'composer install', 'for': 'php'} 12 | Plug 'kristijanhusak/deoplete-phpactor' 13 | ``` 14 | 15 | If you are using a custom setting for sources in deoplete don't forget: 16 | ``` 17 | call deoplete#custom#option('sources', {'php' : ['omni', 'phpactor', 'ultisnips', 'buffer']}) 18 | ``` 19 | 20 | Add the phpactor source is important or phpactor itself is not running. 21 | -------------------------------------------------------------------------------- /rplugin/python3/deoplete/source/phpactor.py: -------------------------------------------------------------------------------- 1 | from .base import Base 2 | import re 3 | import json 4 | import subprocess 5 | 6 | 7 | class Source(Base): 8 | def __init__(self, vim): 9 | Base.__init__(self, vim) 10 | 11 | self.name = 'phpactor' 12 | self.mark = '[phpactor]' 13 | self.filetypes = ['php'] 14 | self.is_bytepos = True 15 | self.input_pattern = '\w+|[^. \t]->\w*|\w+::\w*|\\\\' 16 | self.rank = 500 17 | self.max_pattern_length = -1 18 | self.matchers = ['matcher_full_fuzzy'] 19 | 20 | def get_complete_position(self, context): 21 | return len(re.sub('[\$0-9A-Za-z_]+$', '', context['input'])) 22 | 23 | def gather_candidates(self, context): 24 | self._phpactor = self.vim.eval( 25 | r"""globpath(&rtp, 'bin/phpactor', 1)""" 26 | ) 27 | 28 | if not self._phpactor: 29 | self.print_error( 30 | 'phpactor not found,' 31 | ' please install https://github.com/phpactor/phpactor' 32 | ) 33 | 34 | candidates = [] 35 | 36 | line_offset = int(self.vim.eval('line2byte(line("."))')) 37 | column_offset = int(self.vim.eval('col(".")')) - 2 38 | offset = line_offset + column_offset + len(context['complete_str']) 39 | 40 | args = [ 41 | self.vim.eval('g:phpactorPhpBin'), 42 | self._phpactor, 43 | 'rpc', 44 | '--working-dir=%s' % self.vim.eval('getcwd()') 45 | ] 46 | 47 | proc = subprocess.Popen( 48 | args=args, 49 | stdin=subprocess.PIPE, 50 | stdout=subprocess.PIPE, 51 | stderr=subprocess.PIPE 52 | ) 53 | 54 | source = self.vim.eval('join(getline(1, "$"), "\n")') 55 | data = json.dumps({ 56 | 'action': 'complete', 57 | 'parameters': {'source': source, 'offset': offset} 58 | }) 59 | result, errs = proc.communicate(data.encode('utf-8')) 60 | 61 | errs = errs.decode() 62 | if errs: 63 | return self.print_error(errs) 64 | 65 | result = json.loads(result.decode()) 66 | 67 | if 'parameters' not in result or 'value' not in result['parameters']: 68 | return candidates 69 | 70 | result = result['parameters']['value'] 71 | 72 | if 'issues' in result: 73 | if len(result['issues']) > 0: 74 | self.vim.call( 75 | 'deoplete#util#print_error', 76 | ', '.join(result['issues']), 77 | 'deoplete-phpactor' 78 | ) 79 | 80 | if isinstance(result, list): 81 | suggestions = result 82 | else: 83 | suggestions = result['suggestions'] 84 | 85 | if len(suggestions) > 0: 86 | for suggestion in suggestions: 87 | candidates.append({ 88 | 'word': suggestion['name'], 89 | 'menu': suggestion['info'], 90 | 'kind': suggestion['type'] 91 | }) 92 | 93 | return candidates 94 | --------------------------------------------------------------------------------