zamba is a language agnostic language server, which enables to navigate source code via an abstract syntax tree made by tree-sitter. It focuses on the most essential features a grey beard would expect; But offers some benefits along the way. zamba is free software licensed under MPLv2 (COPYING).
Reason
The server aims at sufficing my personal needs. For the next decades my environment should grow naturally with my demands. I want to be able to navigate any language within my editor of choice and receive essential IDE-like features.
I picked a portable version of scheme: Gambit-C Scheme. The server can be compiled to an executable or executed via the interpreter - both options are plenty fast. Even on my machines (2008 + 2011). Maybe there are precompiled binaries in the future.
Audience
People who want to use their preferred editor for programming, code exploration and system administration. Users who think language servers are too demanding. If you want to dispense the additional tooling for each programming language, zamba should help you get there. And people who appreciate free software, the conservative design or just want to give me a code review.
Goals
zamba shall be a simple tool:
- Be silent,
- Don’t bother with maintenance,
- Be resource efficient,
- Be portable,
- Be open to configuration,
- Be fast,
- Don’t be too smart and keep it simple..
Features
The LSP-protocol gives us the possibility to slim down the requirements of our editors. Here is a quick demo of the functionality. Note that my computer has trouble recording with termtosvg.
- Navigation: Exploring new code bases require hopping across the source. Capabilities:
textDocument/{definition,declaration,implementation,reference}
. - Completion: Offers completion candidates, respecting the file scope & And someday provide code-actions like importing a file, if neccessary. Completions can make use of the current abstract syntax tree to filter.
- Hover: Shows the current AST or(/and) the documentation, without ruining a jumplist.
- Low Computation Mode: One can disable the text synchronization to minimize the resource usage (CPU, that is). zamba then works like a tag generator, updating its buffer on save (
textDocument/didSave
required). - Workspaces: Indexes all projects within the same database, but knows which ones are accessible.
- Configuration Options: Defaults should be silent, but easy accessible.
- Diagnostics: Shows Syntax Errors while typing.
- Signature Help: upcoming
- Refactoring: upcoming
Installation
Since there are no pre-built binaries yet one has to install gambit-C Scheme in order to run (or compile) the server. This tasks is easy - You can find information about my configuration in the README of the repository.
Then, one has to clone the supported parsers + compile them as a shared library.
Supported parsers:
- Java
- Scheme
- C
- Python
Make the libraries accessible for the user executing zamba. Finally you can compile with either make
(natively compiled) or make deps
(interpreted).
Limitations
zamba does not fully comply with the language server protocol at these parts:
- only reading on stdio and TCP are implemented, currently
- it probably uses certain assumptions on configuration options.
zamba does not have a debounce mechanism implemented. It features request cancellation support via $/cancelRequest
.
The hover implementation is only useful for the live abstract syntax tree, but the documentation. This is due to the fact that I need to decide on a language agnostic implementation strategy to resolve the correct definition reliably. Currently the first declaration is taken, then the abstract syntax tree extracted to perform a query within the elected file. Most of the times, the wrong documentation is shown. Once this is implemented, signature help can be implemented easily. A strategy was elected and implementation has started.
Refactoring is a task which should be fully tested.
The same sqlite3-databases are used across multiple processes and no synchronization is performed yet.
The initial parsing of standard libraries is slow. Since this is a one-time effort, I did not optimize this task.
Text Synchronization works properly, even with the weirdest insertion motions of vim/evil. Nonetheless the implementation is not battle-proof yet. You can always just save a file to renew all bindings, syntax tree and the file content.
I had to create a dedicated test suite to start writing tests. But not every feature is tested yet.
I have no idea how to manage a open source project. And the git repository is probably not maintained with best-practices.
Repository
Repository at gitlab.com. If you have any questions, suggestions or critique, feel free to contact me via mail or use the issue tracker.
Interna
Following a few words on the architecture..
zamba stores bindings within an in-memory (local bindings, things on-demand) and a file SQLite-database. When opening a project, dependencies are discovered, parsed and member bindings stored. Large files (> 15000 LOC) with thousands of bindings are processed within milliseconds by the approach taken. Nonetheless, beeing a single-threaded server it can last long for huge code bases (250 MB in source files, e.g.) initially. After the files are indexed, it starts within milliseconds.
Initially, I wanted to omit the huge strings of the document contents. But this is required in order to read the correct textual representation of nodes. One can opt-out by not syncing the text, so that this server acts as a tag alternative. But this requires saving each time a function is requested when the cursor is after a text line which was invalidated.
Thank you for your attention.