nvim_rs/examples/handler_drop.rs
1//! # `handler_drop`
2//!
3//! An example of handling cleanup logic by implementing
4//! [`Drop`](std::ops::Drop) for the handler. The plugin attaches to the current
5//! buffer, then sets the first 2 lines, which get sent back to us with a
6//! `nvim_buf_lines_event` notification. We handle this notification by saving
7//! the lines in the handler. We then let nvim close the channel, and wait for
8//! the IO loop to finish. The handler gets dropped, and so our cleanup logic is
9//! executed.
10//!
11//! ## Usage
12//!
13//! First, build the neovim included as a submodule:
14//!
15//! ```sh
16//! cd neovim
17//! make
18//! ```
19//!
20//! See <https://github.com/neovim/neovim/wiki/Building-Neovim> for build options.
21//! Nothing is really needed to run the example.
22//!
23//! After that, run the example via
24//!
25//! ```sh
26//! cargo run --example handler_drop
27//! ```
28//!
29//! You can verify it worked by looking at the file `handler_drop.txt` in the
30//! project directory which should contain 2 lines ("xyz" and "abc").
31//!
32//! ## Description
33//!
34//! * The associated type for our [`Handler`](crate::rpc::handler::Handler) is
35//! the stdin of our child. But tokio's
36//! [`ChildStdin`](tokio::process::ChildStdin) does not implement
37//! [`futures::io::AsyncWrite`](futures::io::AsyncWrite), so it needs to be
38//! wrapped in the provided [`Compat`](crate::compat::tokio::Compat) type.
39//!
40//! * Implementing [`Drop`](std::ops::Drop) is straightforward, except that we
41//! cannot do so asynchronously. Since dropping the handler is one of the last
42//! things our plugin does, it's not problem to run even larger code bodies
43//! synchronously here.
44//!
45//! * The event handling code is not efficient, because we just read the
46//! arguments by reference and clone them. It's easy to take ownership directly
47//! by matching on the enum [`Value`](rmpv::Value) directly, though.
48//!
49//! * There's basically no error handling, other than `unwrap`ing all the
50//! `Result`s.
51//!
52//! * `await`ing the io future handle is probably not necessary, but feels like
53//! a nice thing to do.
54//!
55//! * As with the other examples, we implement [`Spawn`](futures::task::Spawn)
56//! for our `NeovimHandler` most trivially.