An async autocompletion framework for Neovim

Overview

nvim-compleet

This plugin is still in early development.

preview

📖 Table of Contents

📦 Installation

nvim-compleet requires Neovim 0.7+. Also, since the Rust code has to be compiled it needs the rustup toolchain to be available (follow this guide for instructions on how to install Rust) with rustc version 1.58+, together with the make and ar utilities.

Then installing the plugin is as easy as

require("packer").startup(function()
  use({
    "noib3/nvim-compleet",
    config = function()
      require("compleet").setup()
    end,
    run = "./install.sh release",
  })
end)

🚀 Features

Config validation

validation1 validation2 validation3

🔧 Configuration

nvim-compleet is configured by passing a table to the setup function. The default config is

require('compleet').setup({
  ui = {
    menu = {
      -- Where to anchor the completion menu, either "cursor" or "match".
      anchor = "cursor",

      -- Whether to automatically show the menu every time there are
      -- completions available.
      autoshow = true,

      -- The maximum height (in rows) of the completion menu.
      max_height = nil,

      border = {
        -- Whether to add a border to the completion menu's floating window.
        enable = false,

        -- Any of the style formats listed in `:h nvim_open_win`.
        style = "single"
      },
    },

    details = {
      border = {
        -- Whether to add a border to the details's floating window.
        enable = true,

        -- Same as `ui.menu.border.style`.
        style = {
          "",
          "",
          "",
          {" ", "CompleetDetails"},
        }
      },
    },

    hint = {
      -- Whether to show completion hints.
      enable = false,
    }
  },

  completion = {
    -- Whether to enable completion while deleting characters.
    while_deleting = false,
  },

  sources = {
    lipsum = {
      enable = false,
    },
  }
})

Commands

nvim-compleet provides two commands: CompleetStop{!} to stop the completion and CompleetStart{!} to restart it. The versions with the bang ! stop/start the completion in all the buffers, the ones without it only affect the current buffer.

🎹 Mappings

The following key mappings are exposed:

  • (compleet-next-completion): selects the next item in the completion menu;

  • (compleet-prev-completion): selects the previous item in the completion menu;

  • (compleet-insert-selected-completion): inserts the currently selected completion item into the buffer;

  • (compleet-insert-first-completion): inserts the first completion into the buffer. Useful when hints are enabled and ui.menu.autoshow is set to false;

  • (compleet-show-completions): shows all the available completions at the current cursor position.

A possible configuration could be:

(compleet-next-completion)") or (compleet.has_completions() and "(compleet-show-completions)") or "" end local s_tab = function() return compleet.is_menu_open() and "(compleet-prev-completion)" or "" end local right = function() return compleet.is_hint_visible() and "(compleet-insert-first-completion)" or "" end local cr = function() return compleet.is_completion_selected() and "(compleet-insert-selected-completion)" or "" end local opts = { expr = true, remap = true } keymap.set("i", "", tab, opts) keymap.set("i", "", s_tab, opts) keymap.set("i", "", right, opts) keymap.set("i", "", cr, opts)">
local compleet = require('compleet')
local keymap = vim.keymap

local tab = function()
  return
    (compleet.is_menu_open() and "(compleet-next-completion)")
    or (compleet.has_completions() and "(compleet-show-completions)")
    or ""
end

local s_tab = function()
  return
    compleet.is_menu_open()
    and "(compleet-prev-completion)"
     or ""
end

local right = function()
  return
    compleet.is_hint_visible()
    and "(compleet-insert-first-completion)"
     or ""
end

local cr = function()
  return
    compleet.is_completion_selected()
    and "(compleet-insert-selected-completion)"
     or ""
end

local opts = { expr = true, remap = true }

keymap.set("i", "", tab, opts)
keymap.set("i", "", s_tab, opts)
keymap.set("i", "", right, opts)
keymap.set("i", "", cr, opts)

📈 Roadmap

  • Add LSP source;
  • Add Filepath source;
  • Add Treesitter source;
  • Integrate with snippets engines;
  • Stabilize api, document how to add sources in Rust, add option to provide user-defined sources in Lua;
  • ...
Comments
  • honestly im interested in how this turns out

    honestly im interested in how this turns out

    i've actually thought about writing coq in rust like half a dozen times, I probably would have if i wasn't caught up in a huge rust project for work atm.

    i wonder how little / much optimization you can do to beat coq in completion speeds, recently i actually rewrote coq's tokenizer to run in randomized order, both lengthwise, and front <-> backwards so when you have an input that is too long, and it exceeds the ingestion limit, you don't have a bias to avoid things not ever getting indexed if they are in the middle of it.


    honestly i think a straight up rust port of coq with minor adjustments would smash it by a large margin, the python RPC client is like, written with gevent and stitched together with asyncio is like, really weird.

    anyways heres what i've learned by writing coq that i can can be also applicable here:

    • the 30000 word txt file is gonna really suck the first time you use it, you realize if your fuzzy search is any good, the dictionary will dominate any other search result, or at least fill up all the spots where other sources do not.

    • treesitter is really slow, if you dont do it right, but for each tree sitter node, you can get it's line begin, and line end, and with some event handling, you can like progressively map the buffers via indexing small slices each time

    • paths completion is really tricky, to the point where Shougo of deoplete.nvim actually gave up on implementing it for his rewrite, at least i saw him saying he gave up, no idea if he redid it or not. you have to account for both windows and posix and for windows you need to account for both / and \\ while being able to make sure the returned results can be ranked relatively sanely.

    • honestly try your best to not expose too much custom api surface to third party lua / vimscript. you will probably regret it. just make them talk to you using the LSP / omnifunc protocol. its not that bad.

    • figuring out when to invalidate cache is hard, too lax and you give people garbage results, too strict and you are not returning any results, since the LSPs expect you to have things cached, coq just takes an multiset intersection of previous symbol under cursor to current symbol under cursor, this always gives you a score between 0 and 1, and if you score above a threshold, you do not invalidate cache.


    anyways looking forward to this :)

    opened by ms-jpq 14
  • Not working on ubuntu 20.04

    Not working on ubuntu 20.04

    Thank you for the pure Rust plugin for nvim! But this plugin doesn't run on my computer. I use nvim0.6 and update nvim to 0.7 for nvim-compleet. Version: NVIM v0.7.0-dev+1341-g79dcd045d (officially build binary on github release today)

    https://user-images.githubusercontent.com/25300418/160394054-177e684c-286f-4604-8fb8-00d10307f65b.mp4

    Here is the minimum configuration just for nvim-compleet. You can see the CompleetStart and CompleetStop commands exists, and nothing occurs when keys are stroked

    question 
    opened by zjp-CN 12
  • accurately calculate available screen space

    accurately calculate available screen space

    This changes the calculation of available screen space for the positioning of the windows and which also should fix this. It takes into consideration users' cmdheight, laststatus and tabline settings during the calculation.

    opened by MurdeRM3L0DY 7
  • How can I start to contribute?

    How can I start to contribute?

    I can see lots of TODO in the code, but I don't know which one I should pick up first. Do you have any issue that you can assign to me to get more familiar with the code base?

    question 
    opened by sandangel 5
  • no argument named `profile`

    no argument named `profile`

    The run command is failing here. See the output below:

    ➜ cargo build --release
       Compiling proc-macro2 v1.0.36
       Compiling unicode-xid v0.2.2
       Compiling syn v1.0.86
       Compiling cc v1.0.73
       Compiling serde_derive v1.0.136
       Compiling serde v1.0.136
       Compiling memchr v2.4.1
       Compiling autocfg v1.1.0
       Compiling pkg-config v0.3.24
       Compiling erased-serde v0.3.20
       Compiling once_cell v1.9.0
       Compiling rustc-hash v1.1.0
       Compiling compleet v0.1.0 (/[HIDDEN_PATH]/nvim-compleet)
    error: there is no argument named `profile`
      --> build.rs:10:15
       |
    10 |     @cp ./target/{profile}/libcompleet.so ./lua/compleet.so
       |                  ^^^^^^^^^
    
    error: there is no argument named `profile`
      --> build.rs:11:15
       |
    11 |     @cp ./target/{profile}/deps/*.rlib ./lua/deps
       |                  ^^^^^^^^^
    
    error: could not compile `compleet` due to 2 previous errors
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    
    question 
    opened by KadoBOT 4
  • expose nvim-binding as a crate

    expose nvim-binding as a crate

    Hello @noib3, amazing work so far, I'm facing similar issues that I found nvim-binding supper helpful and I was considering creating one similar. It would be great if you can extract it to it's own repo and release it on crate.io. I intend to use so maybe I could contribute as I go

    Thanks.

    opened by kkharji 3
  • Performance Issue

    Performance Issue

    Hi, Have you ever tested the performance of mlua? From my experience, it's really slow to cross the boundary between the lua part and the rust part (i.e., calling a rust function from lua or calling a lua function from rust). I'm afraid that the performance will be an issue in the future.

    Thanks

    opened by litao91 3
  • Take some appreciation ;)

    Take some appreciation ;)

    You're a machine! I've been visiting this repo for the past few months every once in a while and each time I do I see you committing something a few days ago.

    Seeing a project of this size and nvim-oxi being held up by one person is a feat to admire. Take your time and have fun developing this ;)

    other 
    opened by RaafatTurki 1
  • Assets commited to repo

    Assets commited to repo

    As the purpose of this repository is to be used as a neovim plugin the assets for the readme should not be commited into the repo. Plugins for neovim are just git clones of repositories. There is no need for a user to download assets every time (waste of download time and space). Since they are also committed into git a copy of them is zlib compressed into the objects folder and will live for the existence of the project.

    Instead of adding them to the repo you can either create an issue that you lock and use it to upload images that you link, or use the wiki to host the files instead.

    As an example of the first method I use this method to host my screenshots for my colorscheme nightfox (issue). I also close it so no one really sees it and I can just upload images there.

    As the plugin is still very new you can rewrite your git history to remove the references to the assets. This can be done with the git command filter-repo. This will rewrite your git history to remove references to the images.

    The command would be

    git filter-repo --invert-paths --path .github/assets/
    

    Here is the results before and after

    Before

    nvim-compleet ➜ dua
       4.10 KB .cargo
       4.10 KB .gitignore
       4.10 KB Cargo.toml
       4.10 KB LICENSE
       4.10 KB build.rs
       4.10 KB rustfmt.toml
       8.19 KB Cargo.lock
       8.19 KB README.md
      77.82 KB neovim
     249.86 KB src
       1.90 MB .github
       4.51 MB .git
       6.78 MB total
    

    After

    nvim-compleet  ➜ dua
       4.10 KB .cargo
       4.10 KB .github
       4.10 KB .gitignore
       4.10 KB Cargo.toml
       4.10 KB LICENSE
       4.10 KB build.rs
       4.10 KB rustfmt.toml
       8.19 KB Cargo.lock
       8.19 KB README.md
      77.82 KB neovim
     249.86 KB src
     438.27 KB .git
     811.01 KB total
    

    Removing the references change the repo size from 6.78 MB to 811.01 KB !

    enhancement 
    opened by EdenEast 1
  • segfaults when calling setup

    segfaults when calling setup

    Hi. Would you mind sharing what versions of neovim, nvim-oxi and rustc you use to test nvim-completion? I've tried with rustc 1.65.0-nightly/1.63.0, neovim (NVIM v0.8.0-dev-1021-g24fbda04b Build type: Release), nvim-oxi latest master. Could you also share your config options for nvim-completion? Thanks.

    opened by MurdeRM3L0DY 4
  • Changelog

    Changelog

    I've been interested in this project and looking back every once in a while to see if there have been any changes. Unfortunately, all I can really do is look at commit messages which is quite tedious. Is there any way you could supply a changelog file to keep track of all the new updates?

    opened by ok-nick 2
Owner
Riccardo Mazzarini
Riccardo Mazzarini
🔭 Search Dash.app from Neovim with Telescope. Built with Rust 🦀 and Lua

Dash.nvim Query Dash.app within Neovim with a Telescope picker! The theme used in the recording is lighthaus.nvim. Note: Dash is a Mac-only app, so yo

Mat Jones 193 Dec 28, 2022
Neovide - No Nonsense Neovim Client in Rust

Neovide This is a simple graphical user interface for Neovim (an aggressively refactored and updated Vim editor). Where possible there are some graphi

Neovide 9.3k Jan 5, 2023
Xcode Neovim Replacement-ish.

An XCode replacement-ish development environment that aims to be your reliable XCode alternative to develop exciting new [apple] software products ??

null 272 Dec 30, 2022
Failed experiment in downloading random cat image, turning it into ascii and displaying it in Neovim.

cat.nvim Failed experiment in downloading random cat image, turning it into ascii and displaying it in Neovim. Failed as I realized far too late, that

James Vero 4 Aug 5, 2022
Neovim Configuration Manager (Swap/Backup/Try Configurations Easily)

ncm-rs Neovim Configuration Manager (Swap/Backup/Try Configurations Easily) I created this package because I wanted to try out Lazyvim (which is why i

instance.id 4 Mar 5, 2023
Neovim plugin for moving lines up and down, written in Rust

Moveline.nvim Moveline is a simple plugin for moving lines up and down. It's written in Rust using my library nvim-utils. Installation Moveline can be

Will Hopkins 34 Mar 18, 2023
WIP. Goals: Treesitter highlighting, snippets, and a smooth intergration with neovim.

typst.nvim WIP. Goals: Tree-sitter highlighting, snippets, and a smooth integration with neovim. For the past week, I've been thinking what I want for

SeniorMars 66 Apr 9, 2023
this-week-in-neovim.org official webapp repository

This Week In Neovim This repository holds the source code of https://this-week-in-neovim.org. Architecture How does it run in production Automatic upd

Dimitri Sabadie 189 Jun 23, 2023
A dark and light Neovim theme written in fennel, inspired by IBM Carbon.

oxocarbon.nvim Note: The old rust version can be found on the rust branch of this repository Oxocarbon is looking for ports! If you're a user of anoth

Nyoom Engineering 690 Jun 29, 2023
nvim-oxi provides safe and idiomatic Rust bindings to the rich API exposed by the Neovim text editor.

?? nvim-oxi nvim-oxi provides safe and idiomatic Rust bindings to the rich API exposed by the Neovim text editor. The project is mostly intended for p

Riccardo Mazzarini 655 Jul 13, 2023
A CLI to easily switch between multiple Neovim configuration environments, written in Rust

Neovim Configuration Switcher Neovim Configuration Switcher (short nvims) is a CLI to easily switch between multiple Neovim configuration environments

Nhan Pham 3 Mar 30, 2024
A minimal readline with multiline and async support

RustyLine Async A minimal readline with multiline and async support. Inspired by rustyline , async-readline & termion-async-input.

Zyansheep 16 Dec 15, 2022
Russh - Async (tokio) SSH2 client and server rimplementation

Russh Async (tokio) SSH2 client and server rimplementation. This is a fork of Thrussh by Pierre-Étienne Meunier which adds: More safety guarantees AES

Warptech Industries 113 Dec 28, 2022
⚡ Blazing fast async/await HTTP client for Python written on Rust using reqwests

Reqsnaked Reqsnaked is a blazing fast async/await HTTP client for Python written on Rust using reqwests. Works 15% faster than aiohttp on average RAII

Yan Kurbatov 8 Mar 2, 2023
Async filesystem facade for Rust!

floppy-disk floppy disk is a WIP, async-only filesystem facade for Rust. What? Have you ever worked with std::fs? tokio::fs? Then you've probably real

amy null 8 Apr 2, 2023
A simple Rust library for OpenAI API, free from complex async operations and redundant dependencies.

OpenAI API for Rust A community-maintained library provides a simple and convenient way to interact with the OpenAI API. No complex async and redundan

null 6 Apr 4, 2023
⚡️ Blazing fast terminal file manager written in Rust, based on async I/O.

Yazi - ⚡️ Blazing Fast Terminal File Manager Yazi ("duck" in Chinese) is a terminal file manager written in Rust, based on non-blocking async I/O. It

三咲雅 · Misaki Masa 189 Aug 1, 2023
Fully-typed, async, reusable state management and synchronization for Dioxus 🧬

dioxus-query ?? ⚡ Fully-typed, async, reusable state management and synchronization for Dioxus ??. Inspired by TanStack Query. ⚠️ Work in progress ⚠️

Marc Espín 9 Aug 7, 2023