Framework
maralla/completor.vim avatar
maralla/completor.vim

completor.vim is a completion framework, and the completers are pluggable

Async completion framework made ease.

1,316 stars60 forksPythonMIT

At a glance

What is it?
completor.vim is an asynchronous code completion framework for vim8 with a Python core, built on the new features of vim8 to keep the completion engine fast and low overhead. It ships built-in completers for filenames, buffers, snippets and includes, and delegates semantic completion to external tools, with jedi for Python, tern for JavaScript, clang for C and C++, racer for Rust and gocode for Go.
Who is it for?
completor.vim is the right choice if you want one completion menu that mixes semantic results with your own buffers, filenames, snippets and include paths, because the framework is the part that solves the merging and the timing, and the language engines are replaceable pieces.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A framework, with the completers as separate pieces

The description is an asynchronous code completion framework for vim8, and the README says the new features of vim8 are used to implement the fast completion engine with low overhead. The architecture that implies is a core that owns the menu, the timing and the merging, and a set of completers that each produce candidates. The core is written in Vim script with a Python component, in the pythonx/ directory, and the repository layout shows the pieces, with autoload/ for the lazily loaded functions, plugin/ for the commands, doc/ for the help files, tests/ for the unit test suite, and the Makefile at the root. The requirements are short and non-negotiable, vim8 and a vim compiled with python or python3. The audience is a vim user who wants a single completion menu that draws on several sources at once, rather than one engine per language, and the design bet is that the interesting problem is the merging and the asynchrony, not the individual language engines.

Three ways to install it

The plugin installs the way vim plugins usually do, and the README lists all three because each suits a different setup. The vim8 builtin package manager route is a clone into the packages directory:

bash
$ mkdir -p ~/.vim/pack/completor/start
$ cd ~/.vim/pack/completor/start
$ git clone https://github.com/maralla/completor.vim.git

The second option is the pack plugin, which is the author's own package manager:

bash
$ pack install maralla/completor.vim

The third is vim-plug, with a single line in the plugin list:

vim
Plug 'maralla/completor.vim'

The vim-plug route has a wrinkle for the JavaScript completer, which needs a build step, and the plugin manager can run it for you with a post install hook:

vim
Plug 'ternjs/tern_for_vim', { 'do': 'npm install' }
Plug 'maralla/completor.vim', { 'do': 'make js' }

That is the same build the Makefile performs, which changes into the javascript completer directory and runs yarn install if yarn is available and npm install otherwise.

The completers that work with no extra tools

Four completers are covered first, and they are the ones that make the framework useful even if you never configure a language engine. The filename completer matches file path patterns and completes the file name automatically. The buffer completer is the fallback, used when no semantic completer is found, completing from the contents of the current buffers. Snippet support is on by default for Ultisnips, so if ultisnips is installed its candidates appear in the completion popup, and neosnippet and vim-vsnip are supported through separate plugins, completor-neosnippet and completor-vsnip. And neoinclude is supported by default too, so include candidates show up in the same menu if neoinclude is installed. Four more completers exist as separate plugins rather than built-ins: dictionary completion through completor-dictionary, shell command completion through completor-shell, completion from words in tmux panes through completor-tmux, and completion from syntax files through completor-necosyntax.

One variable per language engine, and the tools they need

The semantic side is a list of external tools, and each has its own binary path variable so you are not at the mercy of PATH. For Python it is jedi, installed with pip install jedi into a global environment or a virtualenv, with the interpreter chosen by let g:completor_python_binary. For Rust it is racer, with let g:completor_racer_binary. For JavaScript it is tern, which needs node and either npm or yarn, and the path is set with let g:completor_node_binary. For C and C++ it is clang, with let g:completor_clang_binary. For Go it is gocode, with let g:completor_gocode_binary. The rest are delegated to other plugins, with completor-swift for Swift, alchemist.vim for Elixir, completor-necovim for vim script and completor-typescript for TypeScript. The pattern is consistent throughout, one global variable naming the executable, and it means a user on a machine with several interpreters can point the plugin at the one that has the language tooling installed, rather than reinstalling the tooling for the wrong Python.

Extra clang arguments come from a file in your project

The C and C++ completer has an escape hatch that is worth knowing, because clang completion without the right include paths is the usual reason clang completion feels useless. To pass extra clang arguments, you create a file named .clang_complete under the project root directory or any parent directory, and every argument goes on its own line. The example in the README is a list of include paths and a standard:

code
-std=c++11
-I/Users/maralla/Workspace/src/dji-sdk/Onboard-SDK/lib/inc
-I/Users/maralla/Workspace/src/dji-sdk/Onboard-SDK/sample/Linux/inc

The search for the file walks up from the project root, so the same mechanism covers a monorepo with several roots without any configuration in the plugin. The completer also ships a key mapping, the <Plug>CompletorCppJumpToPlaceholder mapping, which you can bind to jump between the placeholders clang leaves in a completion candidate, and the README shows the two lines that bind it in insert and normal mode:

vim
map <tab> <Plug>CompletorCppJumpToPlaceholder
imap <tab> <Plug>CompletorCppJumpToPlaceholder

The omni_trigger pattern for the languages it does not know

For a language that completor does not implement natively, the README says auto completion can still be used if an omni function is defined for the file type, but an option has to be defined to specify the trigger. The option name follows a pattern, let g:completor_{filetype}_omni_trigger, set to a Python regular expression, and the example given is for CSS:

vim
let g:completor_css_omni_trigger = '([\w-]+|@[\w-]*|[\w-]+:\s*[\w-]*)$'

The regular expression matches the text before the cursor, which is what decides when the omni function is worth calling. This is the mechanism that makes the framework extensible to languages nobody has written a completer for, and it is also where a user can cause trouble, since a greedy trigger fires the completer on every keystroke and the cost is paid in latency on a slow language. The same caution applies to the default behaviour, since the framework auto triggers as you type unless you set g:completor_auto_trigger to 0, and the configuration tips in the README are mostly about the interaction between the auto trigger and the key mapping you use.

The Tab key, and what the configuration tips are actually for

The longest part of the documentation is about one key. The basic advice is to let Tab select from the completion menu, using three expression mappings, one for Tab, one for Shift Tab and one for Enter, each of which checks whether the popup is visible and behaves accordingly:

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

The alternative is to use Tab to trigger completion instead of select it, which requires turning the auto trigger off with let g:completor_auto_trigger = 0 and mapping Tab to a call of completor#do('complete'). The README then offers a better way, a Tab_Or_Complete function that opens the completion menu when you are in the middle of typing a word and inserts a literal tab otherwise, which is the behaviour most people want. The framing in the comment is worth repeating, that the usual completion is on Ctrl-n but it is more trouble to press all the time. On maintenance, the repository is not archived, the last push was on 2026-10-10, there are no GitHub releases, and the licence is MIT.

Editorial conclusion

completor.vim is the right choice if you want one completion menu that mixes semantic results with your own buffers, filenames, snippets and include paths, because the framework is the part that solves the merging and the timing, and the language engines are replaceable pieces. It is the wrong tool if you want LSP-native completion, since the documented backends are language tools rather than a language server client, and it is a poor fit if your vim is not compiled with Python, because that is a hard requirement. Before adopting it, pick one language backend and prove it works, because the README is explicit that for semantic completion external completion tools should be installed, and check the key mapping you intend to use, since the default suggestion is to trigger on Tab and the framework can also auto-trigger as you type.

Frequently asked questions

What are the requirements for completor.vim?

vim8 and a vim compiled with python or python3. For semantic completion you also need external completion tools installed, since the README states that external completion tools should be installed for that purpose.

How do I install completor.vim?

With the vim8 builtin package manager, by cloning into ~/.vim/pack/completor/start, with the pack plugin using pack install maralla/completor.vim, or with vim-plug using Plug 'maralla/completor.vim'. The JavaScript completer needs an extra build step, which the plugin manager can run as a post install hook with { 'do': 'make js' }.

Which completers work without installing extra tools?

The filename completer, the buffer completer as a fallback, Ultisnips snippets and neoinclude includes are supported by default. Dictionary, shell, tmux and syntax file completion come from separate plugins, and language completion comes from external tools such as jedi, tern, clang, racer and gocode.

How do I get clang completion to find my headers?

Create a file named .clang_complete under the project root or any parent directory, with one clang argument per line, such as -std=c++11 and your -I include paths. The completer reads that file, and the <Plug>CompletorCppJumpToPlaceholder mapping can be bound to jump between the placeholders in a candidate.

Official sources

  1. Issues
  2. License: MIT
  3. maralla/completor.vim on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/maralla-completor-vim.svg)](https://hysenlabs.com/projects/maralla-completor-vim)

Was this useful?