Faster than deoplete, Lighter than YouCompleteMe, a neovim completion framework
GitHub - roxma/nvim-completion-manager: :warning: PLEASE USE https://github.com/ncm2/ncm2 INSTEAD
⚠️ THIS REPO IS DEPRECATED. USE NCM2 INSTEAD.

❤️ for my favorite editor
A Completion Framework for Neovim
This is a fast, extensible, async completion framework for
neovim.  For more information about plugin
implementation, please read the Why section.
Future updates, announcements, screenshots will be posted
here.
Subscribe it if you are interested.

Table of Contents


Features
Scoping Sources:
Completion Sources
How to extend this framework?
Requirements
Installation
Optional Configuration Tips
Why?

Async architecture
Scoping
Experimental hacking


FAQ

Why Python?


Trouble-shooting
Related Projects


Features

Asynchronous completion support like deoplete.
Faster, all completions should run in parallel.
Smarter on files with different languages, for example, css/javascript
completion in html style/script tag.
Extensible async vimscript API and python3 API.
Function parameter expansion via
Ultisnips,
neosnippet.vim or
vim-snipmate.

Scoping Sources:

Language specific completion for markdown, reStructuredText
Javascript code completion in html script tag
Css code completion in html style tag

Completion Sources



Language / Description
Repository




Word from current buffer
builtin


Word from tmux session
builtin


ctags completion
builtin


Filepath completion
builtin


Python
builtin, requires jedi


Css
builtin, requires csscomplete#CompleteCSS


Golang
builtin, requires gocode


Ultisnips hint
builtin, requires Ultisnips


Snipmate hint
builtin, requires vim-snipmate


neosnippet hint
builtin, requires neosnippet.vim


Language Server Protocol
autozimu/LanguageClient-neovim


C/C++
clang_complete [DEPRECATED]


C/C++
ncm-clang


Javascript
nvim-cm-tern


Javascript
nvim-cm-flow


elm
ncm-elm-oracle


Clojure
clojure-async-clj-omni


Rust
nvim-cm-racer


Vimscript
Shougo/neco-vim


Ruby
ncm-rct-complete


PHP
LanguageServer-php-neovim


PHP
ncm-phpactor


Swift
dafufer/nvim-cm-swift-completer


gtags completion
jsfaint/gen_tags.vim


syntax completion
Shougo/neco-syntax


include completion
Shougo/neoinclude


github completion
ncm-github


mutt mails
#97 mutt-aliases.vim


deoplete
#50 deoplete


css
calebeby/ncm-css


lbdb (addressbook)
katsika/ncm-lbdb


Java
sassanh/nvim-cm-eclim


TypeScript
mhartington/nvim-typescript


Word from other buffers
fgrsnau/ncm-otherbuf


R
gaalcaras/ncm-R



How to extend this framework?

:help ncm-source-examples for minimal examples
Some real, small examples:
github-emoji,
nvim-cm-racer

Please announce your new plugin
here after
you've created the extension.
Requirements

For Neovim:

echo has("python3")


For Vim 8:

roxma/vim-hug-neovim-rpc
g:python3_host_prog pointed to your python3 executable, or echo exepath('python3') is not empty.
neovim python client (pip3 install neovim)



Installation

Assuming you're using vim-plug

" the framework
Plug 'roxma/nvim-completion-manager'

If you are vim8 user, you'll need
vim-hug-neovim-rpc. The vim8
support layer is still experimental, please 'upgrade' to
neovim if it's possible.

" Requires vim8 with has('python') or has('python3')
" Requires the installation of msgpack-python. (pip install msgpack-python)
if !has('nvim')
    Plug 'roxma/vim-hug-neovim-rpc'
endif

Install pip modules for your neovim python3:

# neovim is the required pip module
# jedi for python completion
# psutil (optional)
# setproctitle (optional)
pip3 install --user neovim jedi psutil setproctitle
(Optional) It's easier to use
python-support.nvim to help
manage your pip modules for neovim:
Optional Configuration Tips

Supress the annoying completion messages:

" don't give |ins-completion-menu| messages.  For example,
" '-- XXX completion (YYY)', 'match 1 of 2', 'The only match',
set shortmess+=c

When the  <Enter> key is pressed while the popup menu is visible, it only
hides the menu. Use this mapping to hide the menu and also start a new line.

inoremap <expr> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")

Here is an example for expanding snippet in the popup menu with <Enter>
key.  Suppose you use the <C-U> key for expanding snippet.

imap <expr> <CR>  (pumvisible() ?  "\<c-y>\<Plug>(expand_or_nl)" : "\<CR>")
imap <expr> <Plug>(expand_or_nl) (cm#completed_is_snippet() ? "\<C-U>":"\<CR>")

When using CTRL-C key to leave insert mode, it does not trigger the
autocmd InsertLeave. You should use CTRL-[, or map the <c-c> to
<ESC>.



Use <TAB> to select the popup menu:

inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"

If 'omnifunc' is the only available option, you may register it as a source
for NCM.

" css completion via `csscomplete#CompleteCSS`
" The `'cm_refresh_patterns'` is PCRE.
" Be careful with `'scoping': 1` here, not all sources, especially omnifunc,
" can handle this feature properly.
au User CmSetup call cm#register_source({'name' : 'cm-css',
        \ 'priority': 9, 
        \ 'scoping': 1,
        \ 'scopes': ['css','scss'],
        \ 'abbreviation': 'css',
        \ 'word_pattern': '[\w\-]+',
        \ 'cm_refresh_patterns':['[\w\-]+\s*:\s+'],
        \ 'cm_refresh': {'omnifunc': 'csscomplete#CompleteCSS'},
        \ })
Warning: omnifunc is implemented in a synchronouse style, and
vim-vimscript is single threaded, it would potentially block the ui with the
introduction of a heavy weight omnifunc, for example the builtin
phpcomplete. If you get some time, please try implementing a source for NCM as
a replacement for the old style omnifunc.


There's no guarantee that this plugin will be compatible with other
completion plugin in the same buffer. Use let g:cm_smart_enable=0 and
call cm#enable_for_buffer() to use this plugin for specific buffer.


This example shows how to disable NCM's builtin tag completion. It's also
possible to use g:cm_sources_override to override other default options of
a completion source.


let g:cm_sources_override = {
    \ 'cm-tags': {'enable':0}
    \ }
Why?
This project was started just for fun, and it's working pleasingly for me now.
However, it seems there's lots of differences between deoplete, YCM, and
nvim-completion-manager, by implementation.
I haven't read the source of YCM yet. So here I'm describing the basic
implementation of NCM (short for nvim-completion-manager) and some of the
differences between deoplete and this plugin.
Async architecture
Each completion source should be a thread or a standalone process, the manager
notifies the completion source for any text changing, even when popup menu is
visible.  The completion source notifies the manager if there's any complete
matches available. After some basic priority sorting between completion
sources, and some simple filtering, the completion popup menu will be
triggered with the complete() function by the completion manager.
If some of the completion source is calculating matches for a long long time,
the popup menu will still be shown quickly if other completion sources work
properly. And if the user hasn't changed anything, the popup menu will be
updated after the slow completion source finishes the work.
As the time as of this plugin being created, the completion sources of
deoplete are gathered with gather_candidates() of the Source object,
inside a for loop, in deoplete's process. A slow completion source may defer
the display of popup menu. Of course it will not block the ui.
The good news is that deoplete has supported async gather_candidates now.
But still, NCM is potentially faster because all completion sources run in
parallel.
Scoping
I write markdown files with code blocks quite often, so I've also implemented
language specific completion for markdown file. This is a framework feature,
which is called scoping. It should work for any markdown code block whose
language completion source is avaible to NCM. I've also added support for
javascript completion in script tag of html files, and css completion in style
tag.
The idea was originated in
vim-syntax-compl-pop. Since
it's pure vimscript implementation, and there are some limitations currently
with neovim's syntax api. It's very likely that vim-syntax-compl-pop doesn't
work, for example, javascript completion in markdown or html script tag.  So I
use custom parser in NCM to implement the scoping features.
Experimental hacking
Note that there's some hacking done in NCM. It uses a per 30ms timer to detect
changes even popup menu is visible, as well as using the TextChangedI event,
which only triggers when no popup menu is visible. This is important for
implementing the async architecture. I'm hoping one day neovim will offer
better option rather than a timer or the limited TextChangedI.
FAQ
Why Python?
YouCompleteMe has good
explanation.
Trouble-shooting
Moved to wiki
Related Projects
asyncomplete.vim
