Skip to content

Commit a72ad38

Browse files
authored
Fix nvim_oxi::api::notify() (#208)
* Remove `mlua` from the `dev-dependencies` * Test `api::notify()` * Fix `api::notify()`'s API * Test `api::notify()` w/ custom provider * Add an `Arena` argument to `nvim_notify` on 0.10 and Nightly * Directly implement `Error` for `types::Error` * Test that errors returned by `vim.notify` are propagated * Fix using `mlua` in CI * Don't test `notify_custom{_err}` on `v0.9.5` on macOS and Windows
1 parent 61cc490 commit a72ad38

File tree

12 files changed

+96
-55
lines changed

12 files changed

+96
-55
lines changed

.cargo/config.toml

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[target.x86_64-apple-darwin]
2-
rustflags = [
3-
"-C", "link-arg=-undefined",
4-
"-C", "link-arg=dynamic_lookup",
5-
]
2+
rustflags = ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup"]
63

74
[target.aarch64-apple-darwin]
8-
rustflags = [
9-
"-C", "link-arg=-undefined",
10-
"-C", "link-arg=dynamic_lookup",
11-
]
5+
rustflags = ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup"]
6+
7+
[target.x86_64-pc-windows-msvc]
8+
rustflags = ["-C", "link-args=/FORCE:MULTIPLE"]
9+
10+
[target.aarch64-pc-windows-msvc]
11+
rustflags = ["-C", "link-args=/FORCE:MULTIPLE"]

.github/workflows/ci.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@ jobs:
3434
with:
3535
neovim: true
3636
version: ${{ matrix.neovim }}
37+
- name: Install libluajit (Linux)
38+
if: runner.os == 'Linux'
39+
run: sudo apt-get update && sudo apt-get install -y libluajit-5.1-dev
40+
- name: Install libluajit (macOS)
41+
if: runner.os == 'macOS'
42+
run: brew install luajit
3743
- name: Install latest stable `rustc`
3844
uses: dtolnay/rust-toolchain@stable
3945
- name: Run tests
4046
run: cargo test --workspace ${{ matrix.features }}
41-
working-directory: .
4247

4348
clippy:
4449
name: clippy

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
- the argument of `SetHighlightOptsBuilder::link()` from `&str` to any type
3030
implementing `HlGroup`;
3131

32+
- `nvim_oxi::api::notify()` now takes a `&Dictionary` instead of `&NotifyOpts`
33+
at its third parameter, and returns `Result<Object>` instead of `Result<()>`
34+
([#208](https://github.com/noib3/nvim-oxi/pull/208));
35+
3236
### Removed
3337

3438
- the `SetHighlightOptsBuilder::global_link()` method. Use

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ cargo_metadata = { version = "0.19", optional = true }
6464
mlua = { version = "0.10", features = ["luajit"], optional = true }
6565

6666
[dev-dependencies]
67-
mlua = { version = "0.10", features = ["luajit", "module"] }
6867
serde = { version = "1.0", features = ["derive"] }
6968
tokio = { version = "1.0", features = ["full"] }
7069

crates/api/src/ffi/vim.rs

+2
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ extern "C" {
252252
msg: NonOwning<String>,
253253
log_level: Integer,
254254
opts: NonOwning<Dictionary>,
255+
#[cfg(feature = "neovim-0-10")] // On 0.10 and Nightly.
256+
arena: *mut Arena,
255257
err: *mut Error,
256258
) -> Object;
257259

crates/api/src/opts/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ mod get_mark;
2525
#[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
2626
mod get_namespace;
2727
mod get_text;
28-
mod notify;
2928
mod open_term;
3029
mod option;
3130
mod parse_cmd;
@@ -61,7 +60,6 @@ pub use get_mark::*;
6160
#[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
6261
pub use get_namespace::*;
6362
pub use get_text::*;
64-
pub use notify::*;
6563
pub use open_term::*;
6664
pub use option::*;
6765
pub use parse_cmd::*;

crates/api/src/opts/notify.rs

-28
This file was deleted.

crates/api/src/vim.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -715,20 +715,21 @@ pub fn load_context(ctx: EditorContext) {
715715
pub fn notify(
716716
msg: &str,
717717
log_level: LogLevel,
718-
opts: &NotifyOpts,
719-
) -> Result<()> {
718+
opts: &Dictionary,
719+
) -> Result<Object> {
720720
let msg = nvim::String::from(msg);
721-
let opts = Dictionary::from(opts);
722721
let mut err = nvim::Error::new();
723-
let _ = unsafe {
722+
let obj = unsafe {
724723
nvim_notify(
725724
msg.non_owning(),
726725
log_level as Integer,
727726
opts.non_owning(),
727+
#[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
728+
types::arena(),
728729
&mut err,
729730
)
730731
};
731-
choose!(err, ())
732+
choose!(err, Ok(obj))
732733
}
733734

734735
/// Binding to [`nvim_open_term()`][1].

crates/types/src/error.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ use std::error::Error as StdError;
22
use std::ffi::{c_char, CStr, CString};
33
use std::fmt;
44

5-
use thiserror::Error as ThisError;
6-
75
// https://github.com/neovim/neovim/blob/v0.9.0/src/nvim/api/private/defs.h#L64-L67
86
//
97
/// Binding to the error type used by Neovim.
10-
#[derive(Clone, ThisError, Eq, PartialEq, Hash)]
8+
#[derive(Clone, Eq, PartialEq, Hash)]
119
#[repr(C)]
1210
pub struct Error {
1311
r#type: ErrorType,
@@ -16,6 +14,7 @@ pub struct Error {
1614

1715
unsafe impl Send for Error {}
1816
unsafe impl Sync for Error {}
17+
impl StdError for Error {}
1918

2019
// https://github.com/neovim/neovim/blob/v0.9.0/src/nvim/api/private/defs.h#L27-L31
2120
#[derive(Copy, Clone, Eq, PartialEq, Hash)]

examples/mlua.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use mlua::prelude::LuaFunction;
2-
use nvim_oxi::{mlua::lua, print, Result};
2+
use nvim_oxi::{mlua, print, Result};
33

44
#[nvim_oxi::plugin]
55
fn mlua() -> Result<()> {
66
print!("Hello from nvim-oxi..");
7-
let lua = lua();
7+
let lua = mlua::lua();
88
let print: LuaFunction = lua.globals().get("print")?;
9-
print.call("..and goodbye from mlua!")?;
9+
print.call::<()>("..and goodbye from mlua!")?;
1010
Ok(())
1111
}

tests/Cargo.toml

+6-4
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ neovim-0-9 = ["nvim-oxi/neovim-0-9"]
1313
neovim-0-10 = ["neovim-0-9", "nvim-oxi/neovim-0-10"]
1414
neovim-nightly = ["neovim-0-10", "nvim-oxi/neovim-nightly"]
1515

16-
[target.'cfg(not(any(target_os = "windows", target_env = "msvc")))'.dependencies]
16+
[dependencies]
1717
all_asserts = "2.3"
18-
nvim-oxi = { path = "..", features = ["libuv", "test"] }
18+
thiserror = { workspace = true }
19+
20+
[target.'cfg(not(any(target_os = "windows", target_env = "msvc")))'.dependencies]
21+
nvim-oxi = { path = "..", features = ["libuv", "mlua", "test"] }
1922

2023
[target.'cfg(any(target_os = "windows", target_env = "msvc"))'.dependencies]
21-
all_asserts = "2.3"
22-
nvim-oxi = { path = "..", features = ["test"] }
24+
nvim-oxi = { path = "..", features = ["mlua", "test", "__vendored_luajit"] }
2325

2426
[build-dependencies]
2527
nvim-oxi = { path = "..", features = ["test"] }

tests/src/api/global.rs

+59
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
use std::sync::Arc;
2+
13
use all_asserts::*;
24
use nvim_oxi::api::{self, opts::*, types::*, Buffer, Window};
5+
use nvim_oxi::mlua::{Error as LuaError, IntoLuaMulti, Lua, Table};
6+
use nvim_oxi::{Dictionary, Object};
37

48
#[nvim_oxi::test]
59
fn chan_send_fail() {
@@ -176,6 +180,46 @@ fn list_wins() {
176180
);
177181
}
178182

183+
#[nvim_oxi::test]
184+
fn notify() {
185+
let opts = Dictionary::new();
186+
let ret = api::notify("", LogLevel::Error, &opts).unwrap();
187+
assert_eq!(ret, Object::nil());
188+
}
189+
190+
// Fails on 0.9.5 on macOS and Windows. Not sure why.
191+
#[nvim_oxi::test]
192+
#[cfg_attr(not(any(target_os = "linux", feature = "neovim-0-10")), ignore)]
193+
fn notify_custom() {
194+
let message = "Notifier was called!";
195+
196+
// Set up a custom notification provider.
197+
set_notification_provider(move |lua, _msg, _level, _opts| {
198+
lua.create_string(message)
199+
});
200+
201+
let opts = Dictionary::new();
202+
let ret = api::notify("", LogLevel::Error, &opts).unwrap();
203+
assert_eq!(ret, message.into());
204+
}
205+
206+
// Fails on 0.9.5 on macOS and Windows. Not sure why.
207+
#[nvim_oxi::test]
208+
#[cfg_attr(not(any(target_os = "linux", feature = "neovim-0-10")), ignore)]
209+
fn notify_custom_err() {
210+
#[derive(Debug, thiserror::Error)]
211+
#[error("")]
212+
struct CustomError;
213+
214+
// Set up a custom notification provider.
215+
set_notification_provider(move |_lua, _msg, _level, _opts| {
216+
Err::<(), _>(LuaError::ExternalError(Arc::new(CustomError)))
217+
});
218+
219+
let opts = Dictionary::new();
220+
let _err = api::notify("", LogLevel::Error, &opts).unwrap_err();
221+
}
222+
179223
#[nvim_oxi::test]
180224
fn set_get_del_current_line() {
181225
let res = api::set_current_line("foo");
@@ -273,3 +317,18 @@ fn hex_to_dec(hex_color: &str) -> u32 {
273317
|| ('a'..='f').contains(&c.to_ascii_lowercase())));
274318
u32::from_str_radix(&hex_color[1..], 16).unwrap()
275319
}
320+
321+
fn set_notification_provider<P, R>(mut provider: P)
322+
where
323+
P: FnMut(&Lua, String, u32, Table) -> Result<R, LuaError> + 'static,
324+
R: IntoLuaMulti,
325+
{
326+
let lua = nvim_oxi::mlua::lua();
327+
let vim = lua.globals().get::<Table>("vim").unwrap();
328+
let notify = lua
329+
.create_function_mut(move |lua, (msg, level, opts)| {
330+
provider(lua, msg, level, opts)
331+
})
332+
.unwrap();
333+
vim.set("notify", notify).unwrap();
334+
}

0 commit comments

Comments
 (0)