It’s been just over a year since
iCompleteMe’s inception. It’s a
hard fork of
YouCompleteMe, a powerful code completion system for Vim.
iCompleteMe project spawned as an attempt to implement Swift code completion via
The project started as an attempt to build a Swift code completion system ontop
sourcekitd for Vim.
YouCompleteMe’s stable and widely used codebase,
made it a good choice for a platform. But, it wasn’t possible to integrate
Swift code completion into
YouCompleteMe in an ad-hoc way: it needed to be
integrated directly into the core source code.
After code completion was working good, it seemed like a great fit to upstream
YouCompleteMe. Until it wasn’t. A hard fork ended up being the solution.
The YouCompleteMe team is absolutely a pleasure to work with - the fork
spawned for technical reasons..
YouCompleteMe consists of several features in addition to code completion
including diagnostics rendering, go to definition, and more. The system
vertically integrates several different backends like
Jedi for Python and
Racerd for Rust.
Here’s a simplified summary of how
YouCompleteMe completion works:
autocmdsand callbacks trigger completion in
- The VimScript calls into the completion system. ( Written in Python ).
- The Python code returns code completions to Vim via VimScript
- In the Vim Python process,
YouCompleteMegets code completions by delegating to a backend HTTP server,
ycmd. Some completions are computed in the Vim process directly.
Completer’s which all except the clang one, make HTTP requests to language level servers.
- To get semantic completion, the actual language severs interface with program language tools ( like the Swift compiler )
One design advantage of
YouCompleteMe is that the semantic code completion
engines are run in isolated process. Since
ycmd is decoupled from Vim,
it is reusable in other contexts, like emacs.
icmd has recently been
integrated into emacs as well.
Now for the challenges.
Maintainability and Support
The system is a massive polygot project encompassing VimScript, Python 2 ( and 3 ), C++, Boost, and all of third party code: C#, Rust, Java, and more.
As all of these technologies evolve, the project needs to be updated to deal
iCompleteMe succeeded in reducing the surface by focusing
exclusively on Swift.
A search of
YouCompleteMe’s Github issues ( and
@jerrymarino’s ), shows
a dedidicated and perpetual effort to hold it all together.
The standard installation process of
YouCompleteMe expects that the user’s
machine can compile the transitive dependency graph. Building a complex program
like this in arbitrary environments is not for the faint hearted. Installation
is one of the main challenges the project faces.
Since Vim plugins run in a shared process, there was a huge conflict with
YouCompleteMe. Vim plugin code, global variables and import paths all
conflicted. Most of the
YouCompleteMe code running in Vim’s process had to be
iCompleteMe. This namespacing and literal source renaming
hardened the forking and renders most patches difficult to apply without
YouCompleteMe supports both 2 and 3. Keeping python working is effort, even
for Vim its self. For example, using
3.7 pops warnings about deprecated
functionality used in Vim’s
There was push back on having custom VimScript for Swift completion. For
function completions, it inserts placeholders where the arguments belong. As
tab’s, argument placeholders are automatically deleted as the cursor
automatically jumps to the argument. For Xcode users, this behavior is
YouCompleteMe, this feature isn’t implemented. Clang’s
completion API has long exposed placeholders for methods
The philosophy of all encompassing
YouCompleteMe can’t support language
specific behaviors: the antithesis of a unified experience across all
iCompleteMe inherited both the good parts and bad parts of
Swift brings a lot to the table for Vim plugin development, and SwiftForVim
makes it a reality.
Many problems of
YouCompleteMe could be solved by writing the core engine and
plugin in a single language and distributing it as statically compiled native
binary. This approach would make installation trivial and reduce maintenance
The impending Swift rewrite of
YouCompleteMe could improve a lot more.
Here’s a few ideas:
- Leverage the safety and type system of Swift to make it stable.
- Build features in modules that can be reused in other plugins.
- Use a library based approach to reduce complexity, server abstractions, and processes.
- Writing it as functional as possible could make it easier to reason about.
- Strip out all features configuration options. Users instead create variants with permissibly licensed core libraries.
- Move away from an monolithic project and ownership model. A single monolithic code completion system is hard to support and evolve.
Starting up and progress
Things went into motion this early this summer.
1) Break the problem into small reasonable pieces and prototype.
2) SwiftPackageManager.vim is the test ground for prototyping starting with the diagnostics feature.
3) Implement Swift support ( Factor SwiftForVim ) out of
This is just the beginning.