diff --git a/crates/oxi-api/Cargo.toml b/crates/oxi-api/Cargo.toml index 9205dc39..1263dfe4 100644 --- a/crates/oxi-api/Cargo.toml +++ b/crates/oxi-api/Cargo.toml @@ -14,6 +14,7 @@ neovim-nightly = [] [dependencies] oxi-luajit = { workspace = true } +oxi-macros = { workspace = true } oxi-types = { workspace = true } serde = { version = "1.0", features = ["derive"] } diff --git a/crates/oxi-api/src/buffer.rs b/crates/oxi-api/src/buffer.rs index 6eabe30c..5c1dda08 100644 --- a/crates/oxi-api/src/buffer.rs +++ b/crates/oxi-api/src/buffer.rs @@ -105,16 +105,23 @@ impl Buffer { opts: &BufAttachOpts, ) -> Result<()> { let mut err = nvim::Error::new(); + + #[cfg(not(feature = "neovim-nightly"))] let opts = Dictionary::from(opts); + let has_attached = unsafe { nvim_buf_attach( LUA_INTERNAL_CALL, self.0, send_buffer, + #[cfg(not(feature = "neovim-nightly"))] opts.non_owning(), + #[cfg(feature = "neovim-nightly")] + opts, &mut err, ) }; + choose!( err, match has_attached { diff --git a/crates/oxi-api/src/ffi/buffer.rs b/crates/oxi-api/src/ffi/buffer.rs index b987e882..be476b33 100644 --- a/crates/oxi-api/src/ffi/buffer.rs +++ b/crates/oxi-api/src/ffi/buffer.rs @@ -18,7 +18,8 @@ extern "C" { channel_id: u64, buf: BufHandle, send_buffer: bool, - opts: NonOwning, + #[cfg(not(feature = "neovim-nightly"))] opts: NonOwning, + #[cfg(feature = "neovim-nightly")] opts: *const BufAttachOpts, err: *mut Error, ) -> bool; diff --git a/crates/oxi-api/src/opts/buf_attach.rs b/crates/oxi-api/src/opts/buf_attach.rs index b82739c3..3333f498 100644 --- a/crates/oxi-api/src/opts/buf_attach.rs +++ b/crates/oxi-api/src/opts/buf_attach.rs @@ -1,4 +1,4 @@ -use oxi_types::{Dictionary, Object}; +use oxi_types as types; use crate::Buffer; use crate::ToFunction; @@ -84,17 +84,19 @@ pub type OnReloadArgs = (String, Buffer); pub type ShouldDetach = bool; /// Options passed to [`Buffer::attach`](crate::Buffer::attach). +#[cfg(not(feature = "neovim-nightly"))] #[derive(Clone, Debug, Default)] pub struct BufAttachOpts { - on_bytes: Object, - on_changedtick: Object, - on_detach: Object, - on_lines: Object, - on_reload: Object, - preview: Object, - utf_sizes: Object, + on_bytes: types::Object, + on_changedtick: types::Object, + on_detach: types::Object, + on_lines: types::Object, + on_reload: types::Object, + preview: types::Object, + utf_sizes: types::Object, } +#[cfg(not(feature = "neovim-nightly"))] impl BufAttachOpts { #[inline(always)] /// Creates a new [`BufAttachOptsBuilder`]. @@ -103,9 +105,11 @@ impl BufAttachOpts { } } +#[cfg(not(feature = "neovim-nightly"))] #[derive(Clone, Default)] pub struct BufAttachOptsBuilder(BufAttachOpts); +#[cfg(not(feature = "neovim-nightly"))] impl BufAttachOptsBuilder { /// Callback invoked on change. It receives more granular information about /// the change compared to [`on_lines`](BufAttachOptsBuilder::on_lines). @@ -114,7 +118,7 @@ impl BufAttachOptsBuilder { where F: ToFunction, { - self.0.on_bytes = Object::from_luaref(on_bytes.into_luaref()); + self.0.on_bytes = types::Object::from_luaref(on_bytes.into_luaref()); self } @@ -125,7 +129,7 @@ impl BufAttachOptsBuilder { F: ToFunction, { self.0.on_changedtick = - Object::from_luaref(on_changedtick.into_luaref()); + types::Object::from_luaref(on_changedtick.into_luaref()); self } @@ -135,7 +139,7 @@ impl BufAttachOptsBuilder { where F: ToFunction, { - self.0.on_detach = Object::from_luaref(on_detach.into_luaref()); + self.0.on_detach = types::Object::from_luaref(on_detach.into_luaref()); self } @@ -145,7 +149,7 @@ impl BufAttachOptsBuilder { where F: ToFunction, { - self.0.on_lines = Object::from_luaref(fun.into_luaref()); + self.0.on_lines = types::Object::from_luaref(fun.into_luaref()); self } @@ -156,7 +160,7 @@ impl BufAttachOptsBuilder { where F: ToFunction, { - self.0.on_reload = Object::from_luaref(on_reload.into_luaref()); + self.0.on_reload = types::Object::from_luaref(on_reload.into_luaref()); self } @@ -184,10 +188,10 @@ impl BufAttachOptsBuilder { } } -impl From<&BufAttachOpts> for Dictionary { +#[cfg(not(feature = "neovim-nightly"))] +impl From<&BufAttachOpts> for types::Dictionary { #[inline] fn from(opts: &BufAttachOpts) -> Self { - // TODO: don't clone by making non-owning version of Dictionary Self::from_iter([ ("on_bytes", opts.on_bytes.clone()), ("on_changedtick", opts.on_changedtick.clone()), @@ -199,3 +203,66 @@ impl From<&BufAttachOpts> for Dictionary { ]) } } + +/// Options passed to [`Buffer::attach`](crate::Buffer::attach). +#[cfg(feature = "neovim-nightly")] +#[derive(Clone, Debug, Default, oxi_macros::OptsBuilder)] +#[repr(C)] +pub struct BufAttachOpts { + #[builder(mask)] + mask: u64, + + /// Callback invoked on change. It receives more granular information about + /// the change compared to [`on_lines`](BufAttachOptsBuilder::on_lines). + #[builder( + generics = "F: ToFunction", + argtype = "F", + inline = "{0}.into_luaref()" + )] + on_bytes: types::LuaRef, + + /// Callback invoked on changedtick increment without text change. + #[builder( + generics = "F: ToFunction", + argtype = "F", + inline = "{0}.into_luaref()" + )] + on_changedtick: types::LuaRef, + + /// Callback invoked on detach. + #[builder( + generics = "F: ToFunction", + argtype = "F", + inline = "{0}.into_luaref()" + )] + on_detach: types::LuaRef, + + /// Callback invoked on change. + #[builder( + generics = "F: ToFunction", + argtype = "F", + inline = "{0}.into_luaref()" + )] + on_lines: types::LuaRef, + + /// Callback invoked on reload. The entire buffer content should be + /// considered changed. + #[builder( + generics = "F: ToFunction", + argtype = "F", + inline = "{0}.into_luaref()" + )] + on_reload: types::LuaRef, + + /// Whether to also attach to command preview (i.e. + /// [`inccommand`](https://neovim.io/doc/user/options.html#'inccommand')) + /// events. + #[builder(argtype = "bool")] + preview: types::Boolean, + + /// Whether to include the UTF-32 and UTF-16 sizes of the replaced region + /// as the last arguments of the + /// [`on_lines`](BufAttachOptsBuilder::on_lines) callback. + #[builder(argtype = "bool")] + utf_sizes: types::Boolean, +}