├── .gitignore ├── LICENSE ├── README.md ├── autoload └── ncm2_bufword.vim ├── ncm2-plugin └── ncm2_bufword.vim └── pythonx └── ncm2_bufword.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyc 3 | __pycache__ 4 | /node_modules 5 | /doc/tags 6 | /.envrc 7 | /test.vim 8 | /nvim.log* 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2018 roxma@qq.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ncm2-bufword 2 | 3 | This ncm2 plugin provide words from current buffer for completion. 4 | 5 | ![ncm2-bufword](https://user-images.githubusercontent.com/4538941/51012266-50b82080-1597-11e9-96df-7e5dcbff4b81.png) 6 | 7 | -------------------------------------------------------------------------------- /autoload/ncm2_bufword.vim: -------------------------------------------------------------------------------- 1 | if get(s:, 'loaded', 0) 2 | finish 3 | endif 4 | let s:loaded = 1 5 | 6 | let g:ncm2_bufword#proc = yarp#py3({ 7 | \ 'module': 'ncm2_bufword', 8 | \ 'on_load': { -> ncm2#set_ready(g:ncm2_bufword#source)} 9 | \ }) 10 | 11 | let g:ncm2_bufword#source = extend(get(g:, 'ncm2_bufword#source', {}), { 12 | \ 'name': 'bufword', 13 | \ 'ready': 0, 14 | \ 'priority': 5, 15 | \ 'mark': 'b', 16 | \ 'on_complete': 'ncm2_bufword#on_complete', 17 | \ 'on_warmup': 'ncm2_bufword#on_warmup', 18 | \ }, 'keep') 19 | 20 | func! ncm2_bufword#init() 21 | call ncm2#register_source(g:ncm2_bufword#source) 22 | endfunc 23 | 24 | func! ncm2_bufword#on_warmup(ctx) 25 | call g:ncm2_bufword#proc.jobstart() 26 | endfunc 27 | 28 | func! ncm2_bufword#on_complete(ctx) 29 | call g:ncm2_bufword#proc.try_notify('on_complete', a:ctx) 30 | endfunc 31 | 32 | -------------------------------------------------------------------------------- /ncm2-plugin/ncm2_bufword.vim: -------------------------------------------------------------------------------- 1 | call ncm2_bufword#init() 2 | -------------------------------------------------------------------------------- /pythonx/ncm2_bufword.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import vim 4 | from ncm2 import Ncm2Source, getLogger 5 | import re 6 | from copy import deepcopy 7 | 8 | logger = getLogger(__name__) 9 | 10 | 11 | class Source(Ncm2Source): 12 | 13 | def on_complete(self, ctx): 14 | pat = re.compile(ctx['word_pattern']) 15 | lines = 1000 16 | 17 | lnum = ctx['lnum'] 18 | ccol = ctx['ccol'] 19 | b = ctx['base'] 20 | 21 | bufnr = ctx['bufnr'] 22 | buf = vim.buffers[bufnr] 23 | 24 | matches = [] 25 | 26 | matcher = self.matcher_get(ctx) 27 | 28 | matches = [] 29 | seen = {} 30 | 31 | def add_match(bufnr, re_match, lnum): 32 | w = re_match.group() 33 | if w in seen: 34 | item = seen[w] 35 | ud = item['user_data'] 36 | else: 37 | item = self.match_formalize(ctx, w) 38 | if not matcher(b, item): 39 | return 40 | seen[w] = item 41 | ud = item['user_data'] 42 | ud['word'] = w 43 | matches.append(item) 44 | 45 | beginl = max(lnum - 1 - int(lines / 2), 0) 46 | endl = lnum - 1 + int(lines / 2) 47 | stepl = 1000 48 | 49 | for lidx in range(beginl, endl, stepl): 50 | lines = buf[lidx: min(lidx + stepl, endl)] 51 | 52 | # convert 0 base to 1 base 53 | for i, line in enumerate(lines): 54 | scan_lnum = lidx + i + 1 55 | if scan_lnum == lnum: 56 | for word in pat.finditer(line): 57 | span = word.span() 58 | 59 | # filter-out the word at current cursor 60 | if (ccol - 1 >= span[0]) and (ccol - 1 <= span[1]): 61 | continue 62 | 63 | add_match(bufnr, word, scan_lnum) 64 | else: 65 | for word in pat.finditer(line): 66 | add_match(bufnr, word, scan_lnum) 67 | 68 | self.complete(ctx, ctx['startccol'], matches) 69 | 70 | 71 | source = Source(vim) 72 | 73 | on_complete = source.on_complete 74 | --------------------------------------------------------------------------------