nvim-oxi provides safe and idiomatic Rust bindings to the rich API exposed by the Neovim text editor.

Overview

🔗 nvim-oxi

Latest version CI Docs

nvim-oxi provides safe and idiomatic Rust bindings to the rich API exposed by the Neovim text editor.

The project is mostly intended for plugin authors, although nothing's stopping end users from writing their Neovim configs in Rust.

How

The traditional way to write Neovim plugins in languages other than the "builtin" ones, i.e. Vimscript or Lua, is via RPC channels. This approach comes with a few limitations mostly due to having to (de)serialize everything to MessagePack-encoded messages, prohibiting things like attaching callbacks to keymaps or scheduling functions.

nvim-oxi takes a different approach. It leverages Rust's foreign function interface (FFI) support to hook straight into the Neovim C code, allowing feature parity with "in process" plugins while also avoiding the need for an extra IO layer.

This thread on the Neovim discourse goes into a bit more detail for anyone who's interested.

Why

Why bother when Neovim already has Lua as a first-class citizen? Mainly two reasons:

  • access to the Rust ecosystem: Lua is a great, minimal scripting language but can also be limiting when writing more complex plugins. In contrast Rust is a fully-fledged, statically typed language with a huge ecosystem of crates for (de)serialization, networking, IO, green threads, etc;

  • nvim-oxi provides a fully typed API: everything from optional function fields to callback arguments is checked at compile-time. This allows plugin authors to spend less time reading through the help docs and more time iterating via cargo checks.

Examples

The examples directory contains several examples of how to use nvim-oxi. It also contains instructions on how to setup your Rust crate, where to place the compiled artifacts and how to load the final plugin from Neovim.

If you're still not sure about something feel free to open a new issue and I might add a new example documenting your use case (if it can be done).

Testing

The test feature flag enables the #[nvim_oxi::test] proc macro. This macro replaces the regular #[test] annotations and can be used to test a piece of code from within a Neovim instance using Rust's excellent testing framework.

For example:

use nvim_oxi::{self as oxi, api};

#[oxi::test]
fn set_get_del_var() {
    api::set_var("foo", 42).unwrap();
    assert_eq!(Ok(42), api::get_var("foo"));
    assert_eq!(Ok(()), api::del_var("foo"));
}

Then cargo test will spawn a new Neovim process with an empty config, run that code and exit. There are a couple of gotchas:

  • after changing a piece of code, cargo build has to be run before you can test that with cargo test;

  • you cannot have two test functions with the same name, even if they belong to different modules. For example this won't work:

mod a {
    #[nvim_oxi::test]
    fn foo() {}
}

mod b {
    #[nvim_oxi::test]
    fn foo() {}
}
Comments
  • `LuaFun::from_fn_mut` and `LuaFun::from_fn_once` are unsound

    `LuaFun::from_fn_mut` and `LuaFun::from_fn_once` are unsound

    • use after move in from_fn_once: if called twice, on second call, we call Box::from_raw is called on a value is that already moved in previous call.

    https://github.com/noib3/nvim-oxi/blob/09d6934c343f556ec605be84d84e5c5086119282/nvim-oxi/src/lua/luafun.rs#L165-L172


    • mutable aliasing in from_fn_mut: if called recursively, we create two mutable references to same closure.

    https://github.com/noib3/nvim-oxi/blob/09d6934c343f556ec605be84d84e5c5086119282/nvim-oxi/src/lua/luafun.rs#L143-L150

    bug 
    opened by Maan2003 18
  • Can't build this repository on Windows.

    Can't build this repository on Windows.

    Rustc: rustc 1.59.0 (9d1b2106e 2022-02-23) Cargo: cargo 1.59.0 (49d8809dc 2022-02-10) NeoVim: NVIM v0.8.0-dev+296-g307c5c63e Error: изображение

    Translation of some parts of error message: ссылка на неразрешённый внешний символ -> link to forbidden external symbol в функции -> in function неразрешенных внешних элементов -> forbidden external elements создается библиотека -> creating a library

    build 
    opened by n-shift 18
  • the mlua example is broken

    the mlua example is broken

    # build in `nvim-oxi/examples/mlua`
    cargo b -r && mkdir lua -p && mv target/release/liblua.so lua/lua.so -fn
    # nvim
    set_rtp=":set rtp+=$PWD"
    cmd=":lua require'lua'.greetings()"
    nvim -u NONE --headless +"$set_rtp" +"$cmd" +quit
    

    And I got

    Hello from Rust..
    Hello from Rust.. function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    Hello from Rust.. function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18 function: builtin#18
    ...
    

    If :lua require'lua'.greetings() is run in nvim cmd, nvim just always prints them without stop.

    The mlua features I use is this: mlua = { version = "0.8", features = ["luajit", "vendored"] } because Lua is not installed locally.

    bug 
    opened by zjp-CN 12
  • Adapt to breaking changes in nightly

    Adapt to breaking changes in nightly

    • A new parameter of type Arena* has been added to some nvim API functions, this caused a crash anytime one of those functions would yield an error (since the new parameter has been inserted before the err one)
    • New fields in the structs for highlights options
    • New fields in the structs for windows options
    opened by calops 10
  • NvimError(

    NvimError("\'ctermbg\' must be string or integer")',

    when i try to compile the plugin with nyoom

    thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NvimError("\'ctermbg\' must be string or integer")', /Users/luxus/.cargo/git/checkouts/nvim-oxi-68d2fdc1d1cdbe82/15fb30d/nvim-oxi/src/lua/lua.rs:41:12
    stack backtrace:
       0:        0x103ecf8a0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::he13a97dfe3ba6dc4
       1:        0x103ef73e4 - core::fmt::write::hd751207b60c12d4c
       2:        0x103ed9954 - std::io::Write::write_fmt::h08841cca3656c74a
       3:        0x103ee4404 - std::panicking::default_hook::{{closure}}::h8d96478a0c41fbb8
       4:        0x103ee40c8 - std::panicking::default_hook::haca5b586a55289c5
       5:        0x103ee4918 - std::panicking::rust_panic_with_hook::h419d889b0a87beff
       6:        0x103ecfcfc - std::panicking::begin_panic_handler::{{closure}}::hf9a5ae5699838d81
       7:        0x103ecf9b4 - std::sys_common::backtrace::__rust_end_short_backtrace::h6248404e1e92c641
       8:        0x103ee4518 - _rust_begin_unwind
       9:        0x103efb92c - core::panicking::panic_fmt::ha964b6658f104372
      10:        0x103efb988 - core::result::unwrap_failed::hf92687bbd06849b8
      11:        0x103ec9334 - _luaopen_oxocarbon
      12:        0x101246258 - <unknown>
      13:        0x1012be51c - _luaL_openlibs
      14:        0x101246258 - <unknown>
      15:        0x10125995c - _lua_pcall
      16:        0x100cdbdc4 - _nlua_require
      17:        0x101246258 - <unknown>
      18:        0x10125995c - _lua_pcall
      19:        0x100cd94bc - _nlua_pcall
      20:        0x100cda3a8 - _nlua_exec_file
      21:        0x100db0fa0 - _do_source
      22:        0x100dadbbc - _do_in_cached_path
      23:        0x100dad140 - _source_runtime
      24:        0x100cbc97c - _load_colors
      25:        0x100c81ba4 - _ex_colorscheme
      26:        0x100c7d33c - _execute_cmd0
      27:        0x100c7d050 - _execute_cmd
      28:        0x100bce964 - _nvim_cmd
      29:        0x100bbc2f0 - _nlua_api_nvim_cmd
      30:        0x101246258 - <unknown>
      31:        0x1012be51c - _luaL_openlibs
      32:        0x101246258 - <unknown>
      33:        0x10125995c - _lua_pcall
      34:        0x100cdbdc4 - _nlua_require
      35:        0x101246258 - <unknown>
      36:        0x1012be51c - _luaL_openlibs
      37:        0x101246258 - <unknown>
      38:        0x10125995c - _lua_pcall
      39:        0x100cdbdc4 - _nlua_require
      40:        0x101246258 - <unknown>
      41:        0x10125995c - _lua_pcall
      42:        0x100cd94bc - _nlua_pcall
      43:        0x100cda3a8 - _nlua_exec_file
      44:        0x100db0fa0 - _do_source
      45:        0x100ce3344 - _main
    fatal runtime error: Rust panics must be rethrown
    fish: Job 1, 'RUST_BACKTRACE=full bin/nyoom...' terminated by signal SIGABRT (Abort)
    
    rustc --version
    rustc 1.62.1
    
    cargo --version
    cargo 1.62.0
    
    bug 
    opened by luxus 10
  • Publish to crates.io

    Publish to crates.io

    Hey @noib3, I'm in the middle of refactoring out neovim logic from Xmas core, and I thought I might give nvim-oxi a try. Though unfortunately it isn't publish yet to crate io and current version is at 0.0.0 which a bit odd don't you think? or is it saying don't used me 🤣. Anyways I'm browse through the codebase right now, amazing progress so far, congrats

    opened by kkharji 9
  • Support for `vim.lsp` and `vim.diagnostic`

    Support for `vim.lsp` and `vim.diagnostic`

    Hey 👋🏾

    First of all, thank you very much for all the effort and time you put into this project. I really appreciate it and it gave the necessary motivation to start working on NeoVim plugins again.

    I'm now in need to make some calls to functions that are globally defined in Lua by NeoVim. Means I want to access vim.lsp, vim.diagnostic, ... Unfortunately I don't see how this should be possible right now. But maybe I'm blind. 🙈 I took a look into your noib3/nvim-compleet project to checkout how you do it there. But it seems like this includes a huge amount of boilerplate code with a bridge etc. pp. completely independent of this library here. I'm not sure if there is any better way to do it, because I honestly have no clue about this topic. But in any case, do you plan to integrate this feature into nvim-oxi too? It looks like you did already all the work for it in the other project, so it would be just a matter of putting it here too and wrap it nicely. Am I wrong?

    Looking forward to hear what you think. 🙃

    enhancement 
    opened by weilbith 8
  • Async support

    Async support

    Just to give a little bit of context, Rust's async functions return Futures that need an executor to drive them to completion. The usual way to achieve this is to let the async runtime, e.g. tokio, control the "main" thread. This is not a viable option in our case since it would block the UI thread, i.e. the one Neovim runs in, defeating the whole point of concurrent code.

    However it should be possible (emphasis on the should) to use libuv, which Neovim uses for the event loop, as the executor. We could expose something like a Task object that wraps an async {} block and drives it to completion by scheduling it via libuv.

    good first issue 
    opened by noib3 8
  • Double free on Array

    Double free on Array

    Im trying to handle the complete function in the nvim-cmp, in mlua i made it works with the same signature, here i have a double free error. maybe i create Array incorrectly or i do something weird in the func? Im trying to create something like that arr = { { "label" = "Jan"} } where it is in index 0.

    the same in mlua: image

    image

    image

    bug waiting response 
    opened by yotam5 7
  • error in compiling part of `api` example

    error in compiling part of `api` example

    good day to you!

    im trying to compile some part of api example, but keep receiveing errors in build

    image

    lib.rs:

    use nvim_oxi::api::{self, opts::*, types::*, Window};
    use nvim_oxi::{self as oxi, print, Dictionary, Function};
    
    #[oxi::module]
    fn api() -> oxi::Result<i32> {
        api::set_keymap(Mode::Insert, "hi", "hello", Default::default())?;
        Ok(42)
    }
    
    opened by fedoranvar 5
  • Got fatal issue when creating user command

    Got fatal issue when creating user command

    After loading the .so library and call it from neovim, the neovim crash and report that:

    thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NvimError("keepscript is not a boolean")'
    

    My neovim version:

    NVIM v0.8.0-dev-1146-g7a70e9587c
    Build type: RelWithDebInfo
    LuaJIT 2.1.0-beta3
    

    Example code: https://github.com/Avimitin/cargo-add-cmp.nvim/blob/master/src/lib.rs#L123-L137

    opened by Avimitin 5
  • Can't locate `lua_pushlstring`

    Can't locate `lua_pushlstring`

    require("foo") gives me this

    E5108: Error executing lua vim/_init_packages.lua:40: dlopen failed: cannot
     locate symbol "lua_pushlstring" referenced by "/data/data/com.termux/files
    /home/foobar/lua/foo.so"...
    stack traceback:
            [C]: in function 'error'
            vim/_init_packages.lua:40: in function <vim/_init_packages.lua:15>
            [C]: in function 'require'
            [string ":lua"]:1: in main chunk
    

    Anyone know why? I'm on Termux

    opened by pseudoparenchymatous 0
  • The libuv example doesn't work

    The libuv example doesn't work

    E5108: Error executing lua error loading module 'uv' from file './uv.so':
            ./uv.so: undefined symbol: luaopen_uv
    stack traceback:
            [C]: at 0x5574be6219d0
            [C]: in function 'require'
            [string ":lua"]:1: in main chunk
    

    Reproduce

    cargo b --example libuv --features neovim-nightly,libuv
    cd target/debug/examples
    cp liblibuv.so uv.so
    nvim --headless --noplugin +":lua require'uv'" +q
    
    opened by zjp-CN 0
  • Test complete API

    Test complete API

    Is there a good way to get comprehensive testing on the nvim api?

    To avoid having problems with breaking changes, I opted to add all functionality I use to the tests e.g. #106.

    Would it be a good idea to have tests for every single function in the API and is that even feasible?

    opened by ModProg 0
  • Issue when trying to use the api example open_window() command.

    Issue when trying to use the api example open_window() command.

    Hey there, I am having issues with the API examples (api.open_window() command). I came across a testing script in another thread and gave it a try to see if it was just me that was doing something wrong or not. I ran the script and ended up with the same issue as my original plugin: E5108: Error executing lua Value of type () couldn't be pushed on the stack: "non-float cannot have \'row\'".. When I ran the tests that were included in ths repo (using nightly nvim), all the window ones passed, which threw me off a bit.

    Doing some searching on the issue, it seems like it may have something to do with setting row/column and then having to set the window relative setting again after that? Unfortunately, I don't know enough about the nvim backend yet to try and do much more diagnostic, myself, outside of doing something silly:

    I didn't expect much from this, but figured it might be worth a shot, lol.

    let config = WindowConfig::builder()
         .relative(WindowRelativeTo::Editor)
         .width(10)
         .row(3)
         .col(3)
         .relative(WindowRelativeTo::Editor)
         .build();
    

    Upon running the script, it looks like there might be another issue with the mlua example that I had not noticed, but wanted to still report it.

    _ ✗  ./examples.sh
    === example: api ===
    Hello from Rust
    Error detected while processing command line:
    E5108: Error executing lua Value of type () couldn\'t be pushed on the stack: "non-float cannot have \'row\'"
    stack traceback:
            [C]: in function 'open_window'
            [string ":lua"]:7: in main chunk
    hello
    === example: mlua ===
    Hello from nvim-oxi..
    ..and goodbye from mlua!
    Error detected while processing command line:
    E5108: Error executing lua [string ":lua"]:1: attempt to index a boolean value
    stack traceback:
            [string ":lua"]:1: in main chunk
    === example: calc ===
    42
    42
    42
    42
    === example: mechanic ===
    Hands on the wheel!!
    
    opened by MostHated 5
  • Doesn't detect panics properly

    Doesn't detect panics properly

    If the test prints to stderr, it will be erroneously interpreted as a panic. Neovim also sometimes prints to stderr for some reason, which will be interpreted as a panic. A more robust way to detect panics is needed.

    opened by oberblastmeister 0
Facilitates navigating between tmux and nvim with C-hjkl

neovim-tmux-navigator Usage Use C-<hjkl> to navigate left, down, up, right, respectively. neovim-tmux-navigator will switch between vim splits and tmu

Amiel Martin 1 Dec 2, 2021
A tool to dump exposed .git repositories

git-dumper This repository houses a tool to dump exposed .git repositories. This is a rewrite from the original GitTools's Dumper project, but in a re

HoLLy 10 Dec 13, 2022
A tool to dump exposed .git repositories

git-dumper This repository houses a tool to dump exposed .git repositories. This is a rewrite from the original GitTools's Dumper project, but in a re

HoLLy 8 Nov 1, 2022
A safe and idiomatic wrapper over shared memory APIs in rust with proper cleanups.

shmem-bind A safe and idiomatic wrapper over shared memory APIs in rust with proper cleanups. Quick start: check the message-passing example for bette

ArshiA Akhavan 3 Apr 6, 2024
Simple yet powerful multi-line text editor widget for tui-rs and ratatui

tui-textarea tui-textarea is a simple yet powerful text editor widget like <textarea> in HTML for tui-rs and ratatui. Multi-line text editor can be ea

Linda_pp 126 Jul 12, 2023
A basic text editor, written in Rust (hence the name).

rut A basic text editor, written in Rust (hence the name). Why, though? I just wanted a basic TUI text editor (like Nano) that could: Be used with all

Lowell Thoerner 4 Feb 3, 2023
Amp: A text editor for your terminal.

Amp: A text editor for your terminal. Heavily inspired by Vi/Vim. Amp aims to take the core interaction model of Vim, simplify it, and bundle in the e

Jordan MacDonald 3.3k Jan 3, 2023
A lightweight but incredibly powerful and feature-rich BitTorrent tracker. Supports UDP + HTTP(S) and a private tracker mode.

Torrust Tracker Project Description Torrust Tracker is a lightweight but incredibly powerful and feature-rich BitTorrent tracker made using Rust. Feat

Torrust 162 Dec 31, 2022
Estratto is a powerful and user-friendly Rust library designed for extracting rich audio features from digital audio signals.

estratto 〜 An Audio Feature Extraction Library estratto is a powerful and user-friendly Rust library designed for extracting rich audio features from

Amber J Blue 5 Aug 25, 2023
🔭 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
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
🖥 A feature rich terminal UI file transfer and explorer with support for SCP/SFTP/FTP/S3

?? A feature rich terminal UI file transfer and explorer with support for SCP/SFTP/FTP/S3

Christian Visintin 574 Jan 5, 2023
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
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
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
Idiomatic inotify wrapper for the Rust programming language

inotify-rs Idiomatic inotify wrapper for the Rust programming language. extern crate inotify; use std::env; use inotify::{ EventMask, Watch

Hanno Braun 220 Dec 26, 2022
`matchable` provides a convenient enum for checking if a piece of text is matching a string or a regex.

matchable matchable provides a convenient enum for checking if a piece of text is matching a string or a regex. The common usage of this crate is used

Pig Fang 6 Dec 19, 2022
Fast, minimal, feature-rich, extended formatting syntax for Rust!

Formatting Tools Fast, minimal, feature-rich, extended formatting syntax for Rust! Features include: Arbitrary expressions inside the formatting brace

Casper 58 Dec 26, 2022
An implementation of Piet's text interface using cosmic-text

piet-cosmic-text Implements piet's Text interface using the cosmic-text crate. License piet-cosmic-text is free software: you can redistribute it and/

John Nunley 7 Mar 12, 2023