From 2216b2ed95df3990f61ca9bde0d7eebaf2c718f0 Mon Sep 17 00:00:00 2001 From: roxma Date: Mon, 30 Jul 2018 17:39:35 +0800 Subject: [PATCH] port to ncm2 test vimrc ```vim set nocompatible syntax on filetype plugin indent on set encoding=utf-8 fileencodings=ucs-bom,utf-8,gbk,gb18030,latin1 termencoding=utf-8 execute 'source ' . $WORKSPACE_DIR . '/plug.vim' call plug#begin($WORKSPACE_DIR) Plug 'ncm2/ncm2' Plug 'roxma/nvim-yarp' autocmd BufEnter * call ncm2#enable_for_buffer() set completeopt=noinsert,menuone,noselect set shortmess+=c inoremap pumvisible() ? "\" : "\" inoremap pumvisible() ? "\" : "\" " snippet support Plug 'ncm2/ncm2-snipmate' Plug 'tomtom/tlib_vim' Plug 'marcweber/vim-addon-mw-utils' Plug 'garbas/vim-snipmate' inoremap ncm2_snipmate#expand_or("\", 'n') inoremap ncm2_snipmate#expand_or("\snipMateTrigger", "m") let g:snips_no_mappings = 1 vmap snipMateNextOrTrigger vmap snipMateBack imap pumvisible() ? "\\snipMateBack" : "\snipMateBack" imap pumvisible() ? "\\snipMateNextOrTrigger" : "\snipMateNextOrTrigger" " phpactor support Plug 'roxma/ncm2-phpactor' Plug 'phpactor/phpactor' Plug 'ncm2/ncm2-bufword' call plug#end() ``` --- README.md | 10 +-- autoload/ncm2_phpactor.vim | 44 ++++++++++ ncm2-plugin/ncm2_phpactor.vim | 1 + .../phpactor.py => ncm2_phpactor.py} | 80 ++++++++----------- 4 files changed, 82 insertions(+), 53 deletions(-) create mode 100644 autoload/ncm2_phpactor.vim create mode 100644 ncm2-plugin/ncm2_phpactor.vim rename pythonx/{cm_sources/phpactor.py => ncm2_phpactor.py} (52%) diff --git a/README.md b/README.md index 7db5c98..26ef32e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ [phpactor](https://github.com/phpactor/phpactor) integration for -[nvim-completion-manager](https://github.com/roxma/nvim-completion-manager) - -![phpactor](https://user-images.githubusercontent.com/4538941/30627852-67643a22-9e05-11e7-90d1-aa75c2d0654c.gif) +[ncm2](https://github.com/ncm2/ncm2) ## Installation @@ -9,12 +7,8 @@ Assuming you're using [vim-plug](https://github.com/junegunn/vim-plug) ```vim -" requires nvim-completion-manager -Plug 'roxma/nvim-completion-manager' - " requires phpactor Plug 'phpactor/phpactor' , {'do': 'composer install'} - -Plug 'roxma/ncm-phpactor' +Plug 'roxma/ncm2-phpactor', {} ``` diff --git a/autoload/ncm2_phpactor.vim b/autoload/ncm2_phpactor.vim new file mode 100644 index 0000000..a89483d --- /dev/null +++ b/autoload/ncm2_phpactor.vim @@ -0,0 +1,44 @@ +if get(s:, 'loaded', 0) + finish +endif +let s:loaded = 1 + +let g:ncm2_phpactor#proc = yarp#py3({ + \ 'module': 'ncm2_phpactor', + \ 'on_load': { -> ncm2#set_ready(g:ncm2_phpactor#source)} + \ }) + +let g:ncm2_phpactor#source = extend(get(g:, 'ncm2_phpactor#source', {}), { + \ 'name': 'phpactor', + \ 'ready': 0, + \ 'priority': 9, + \ 'mark': 'b', + \ 'word_pattern': '[\w]+', + \ 'complete_pattern': ['$', '-\>', '::'], + \ 'subscope_enable': 1, + \ 'on_complete': 'ncm2_phpactor#on_complete', + \ 'on_warmup': 'ncm2_phpactor#on_warmup', + \ }, 'keep') + +func! ncm2_phpactor#init() + call ncm2#register_source(g:ncm2_phpactor#source) +endfunc + +func! ncm2_phpactor#on_warmup(ctx) + call g:ncm2_phpactor#proc.jobstart() +endfunc + +func! ncm2_phpactor#on_complete(ctx) + " g:phpactorPhpBin and g:phpactorbinpath, g:phpactorInitialCwd is defined in + " phpactor plugin + call g:ncm2_phpactor#proc.try_notify('on_complete', + \ a:ctx, + \ getline(1, '$'), + \ getcwd(), + \ [g:phpactorPhpBin, + \ g:phpactorbinpath, + \ 'complete', '-d', g:phpactorInitialCwd, + \ '--format=json', '--', 'stdin' + \ ]) +endfunc + diff --git a/ncm2-plugin/ncm2_phpactor.vim b/ncm2-plugin/ncm2_phpactor.vim new file mode 100644 index 0000000..6589466 --- /dev/null +++ b/ncm2-plugin/ncm2_phpactor.vim @@ -0,0 +1 @@ +call ncm2_phpactor#init() diff --git a/pythonx/cm_sources/phpactor.py b/pythonx/ncm2_phpactor.py similarity index 52% rename from pythonx/cm_sources/phpactor.py rename to pythonx/ncm2_phpactor.py index 333270b..6417872 100644 --- a/pythonx/cm_sources/phpactor.py +++ b/pythonx/ncm2_phpactor.py @@ -1,59 +1,38 @@ # -*- coding: utf-8 -*- -# For debugging, use this command to start neovim: -# -# NVIM_PYTHON_LOG_FILE=nvim.log NVIM_PYTHON_LOG_LEVEL=INFO nvim -# -# -# Please register source before executing any other code, this allow cm_core to -# read basic information about the source without loading the whole module, and -# modules required by this module -from cm import register_source, getLogger, Base - -register_source(name='phpactor', - priority=9, - abbreviation='php', - word_pattern=r'[\w]+', - scoping=True, - scopes=['php'], - early_cache=1, - cm_refresh_patterns=[r'$', r'-\>', r'::'],) +import vim +from ncm2 import Ncm2Source, getLogger +import re -import json -import os import subprocess -import glob -import re +from ncm2 import Popen +import json logger = getLogger(__name__) -class Source(Base): - - def __init__(self, nvim): - super(Source, self).__init__(nvim) +class Source(Ncm2Source): - self._phpactor = nvim.eval(r"""globpath(&rtp, 'bin/phpactor', 1)""") + def on_complete(self, ctx, lines, cwd, phpactor_complete): + src = "\n".join(lines) + src = self.get_src(src, ctx) - if not self._phpactor: - self.message('error', 'phpactor not found, please install https://github.com/phpactor/phpactor') + lnum = ctx['lnum'] - def cm_refresh(self, info, ctx, *args): + # use byte addressing + bcol = ctx['bcol'] + src = src.encode() - src = self.get_src(ctx).encode('utf-8') - lnum = ctx['lnum'] - col = ctx['col'] - filepath = ctx['filepath'] - startcol = ctx['startcol'] + pos = self.lccol2pos(lnum, bcol, src) + args = phpactor_complete + args += [str(pos)] - args = ['php', self._phpactor, 'complete', '--format=json', 'stdin', '%s' % self.get_pos(lnum, col, src)] - proc = subprocess.Popen(args=args, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL, - cwd=self.nvim.eval('getcwd()')) + proc = Popen(args=args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) - result, errs = proc.communicate(src, timeout=30) + result, errs = proc.communicate(src, timeout=5) result = result.decode() @@ -116,10 +95,21 @@ def cm_refresh(self, info, ctx, *args): ph0 = self.snippet_placeholder(0) snippet = '%s(%s)%s' % (word, snip_args, ph0) - item['snippet'] = snippet + item['user_data'] = {'snippet': snippet, 'is_snippet': 1} matches.append(item) - logger.debug("startcol [%s] matches: [%s]", startcol, matches) + self.complete(ctx, ctx['startccol'], matches) + + def snippet_placeholder(self, num, txt=''): + txt = txt.replace('\\', '\\\\') + txt = txt.replace('$', r'\$') + txt = txt.replace('}', r'\}') + if txt == '': + return '${%s}' % num + return '${%s:%s}' % (num, txt) + + +source = Source(vim) - self.complete(info, ctx, startcol, matches) +on_complete = source.on_complete