Giter VIP home page Giter VIP logo

nvim-completion-manager's Introduction

❤️ 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.

All in one screenshot

Table of Contents

Available Completion Sources

plugin builtin sources:

  • Keyword from current buffer
  • Tag completion. (:help 'tags', :help tagfiles())
  • Keyword from tmux session
  • Ultisnips hint, if you have installed ultisnips
  • Neosnippets hint, if you have installed neosnippets
  • File path completion
  • Python completion via jedi
  • Css completion via vim's builtin csscomplete#CompleteCSS

scoping features:

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

extra sources:

Requirements

  • Neovim.
  • Or vim8 with has("python") or has("python3")
  • python3 found in your $PATH env variable or setting g:python3_host_prog to the full path of your python3 executable.

Installation

" 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
# mistune for markdown completion (optional)
# psutil (optional)
# setproctitle (optional)
pip3 install --user neovim jedi mistune psutil setproctitle

(Optional) It's easier to use python-support.nvim to help manage your pip modules for neovim:

Plug 'roxma/python-support.nvim'
" for python completions
let g:python_support_python3_requirements = add(get(g:,'python_support_python3_requirements',[]),'jedi')
" language specific completions on markdown file
let g:python_support_python3_requirements = add(get(g:,'python_support_python3_requirements',[]),'mistune')

" utils, optional
let g:python_support_python3_requirements = add(get(g:,'python_support_python3_requirements',[]),'psutil')
let g:python_support_python3_requirements = add(get(g:,'python_support_python3_requirements',[]),'setproctitle')
  • (Optional) Install typical completion sources
" (optional) javascript completion
Plug 'roxma/nvim-cm-tern',  {'do': 'npm install'}
" (optional) language server protocol framework
Plug 'autozimu/LanguageClient-neovim', { 'do': ':UpdateRemotePlugins' }
" (optional) php completion via LanguageClient-neovim
Plug 'roxma/LanguageServer-php-neovim',  {'do': 'composer install && composer run-script parse-stubs'}
autocmd FileType php LanguageClientStart

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
  • Use tab to select the popup menu:
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <buffer> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")
  • If you're using ultisnips too, and you also want to use <Tab> to trigger ultisnips, this is what I'm using currently. And if there's an openning popup menu get in the way when you want ultisnips, use <c-y> to close the popup menu. Or simple imap another key, <c-u> in this example, to trigger ultisnips.
let g:UltiSnipsExpandTrigger        = "<Plug>(ultisnips_expand)"
let g:UltiSnipsJumpForwardTrigger   = "<Plug>(ultisnips_expand)"
let g:UltiSnipsJumpBackwardTrigger  = "<Plug>(ultisnips_backward)"
let g:UltiSnipsListSnippets         = "<Plug>(ultisnips_list)"
let g:UltiSnipsRemoveSelectModeMappings = 0 

vnoremap <expr> <Plug>(ultisnip_expand_or_jump_result) g:ulti_expand_or_jump_res?'':"\<Tab>"
inoremap <expr> <Plug>(ultisnip_expand_or_jump_result) g:ulti_expand_or_jump_res?'':"\<Tab>"
imap <silent> <expr> <Tab> (pumvisible() ? "\<C-n>" : "\<C-r>=UltiSnips#ExpandSnippetOrJump()\<cr>\<Plug>(ultisnip_expand_or_jump_result)")
xmap <Tab> <Plug>(ultisnips_expand)
smap <Tab> <Plug>(ultisnips_expand)

vnoremap <expr> <Plug>(ultisnips_backwards_result) g:ulti_jump_backwards_res?'':"\<S-Tab>"
inoremap <expr> <Plug>(ultisnips_backwards_result) g:ulti_jump_backwards_res?'':"\<S-Tab>"
imap <silent> <expr> <S-Tab> (pumvisible() ? "\<C-p>" : "\<C-r>=UltiSnips#JumpBackwards()\<cr>\<Plug>(ultisnips_backwards_result)")
xmap <S-Tab> <Plug>(ultisnips_backward)
smap <S-Tab> <Plug>(ultisnips_backward)

" optional mapping provided by NCM. If you press `<c-u>` and nothing has been
" typed, it will popup a list of snippets available
inoremap <silent> <c-u> <c-r>=cm#sources#ultisnips#trigger_or_popup("\<Plug>(ultisnips_expand)")<cr>
  • If you have only omnifunc available, you may register it as a source to the framework.
" 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',
		\ 'cm_refresh_patterns':[':\s+\w*$'],
		\ '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}
    \ }

How to extend this framework?

Please upload your screenshot here after you created the extension.

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 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.

IMHO, 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.

Related Projects

asyncomplete.vim

nvim-completion-manager's People

Contributors

katsel avatar ldong avatar pioupioum avatar prabirshrestha avatar roxma avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.