nvim_api/opts/
buf_attach.rs

1use derive_builder::Builder;
2use nvim_types::{Dictionary, Object};
3
4use crate::Buffer;
5use crate::ToFunction;
6
7/// Arguments passed to the callback registered to
8/// [`on_lines`](BufAttachOptsBuilder::on_lines). The `(a, b, c, d, e, f, g, h,
9/// i)` tuple represents:
10///
11/// - `a`: the string literal `"lines"`;
12/// - `b`: the [`Buffer`] that triggered the callback;
13/// - `c`: the value of the buffer-local `b:changedtick` variable;
14/// - `d`: first row that changed (0-indexed);
15/// - `e`: last row that was changed;
16/// - `f`: last row in the updated range;
17/// - `g`: byte count of previous contents;
18/// - `h`: deleted UTF-32 codepoints (if
19/// [`utf_sizes`](BufAttachOptsBuilder::utf_sizes) was `true`);
20/// - `i`: deleted UTF-16 codeunits (if
21/// [`utf_sizes`](BufAttachOptsBuilder::utf_sizes) was `true`);
22pub type OnLinesArgs = (
23    String,
24    Buffer,
25    u32,
26    usize,
27    usize,
28    usize,
29    usize,
30    Option<usize>,
31    Option<usize>,
32);
33
34/// Arguments passed to the callback registered to [`on_bytes`](BufAttachOptsBuilder::on_bytes). The `(a, b, c, d, e, f, g, h, i, j, k, l)`
35/// - `a`: the string literal `"bytes"`;
36/// - `b`: the [`Buffer`] that triggered the callback;
37/// - `c`: the value of the buffer-local `b:changedtick` variable;
38/// - `d`: start row of the changed text (0-indexed);
39/// - `e`: start column of the changed text;
40/// - `f`: byte offset of the changed text from the start of the buffer;
41/// - `g`: number of rows deleted;
42/// - `h`: number of columns deleted;
43/// - `i`: number of bytes deleted;
44/// - `j`: number of rows added;
45/// - `k`: number of columns added;
46/// - `l`: number of bytes added;
47pub type OnBytesArgs = (
48    String,
49    Buffer,
50    u32,
51    usize,
52    usize,
53    usize,
54    usize,
55    usize,
56    usize,
57    usize,
58    usize,
59    usize,
60);
61
62/// Arguments passed to the callback registered to
63/// [`on_changedtick`](BufAttachOptsBuilder::on_changedtick). The first tuple
64/// element is the string literal `"changedtick"`, the second is the [`Buffer`]
65/// that triggered the callback and the third is current value of the
66/// buffer-local
67/// [`b:changedtick`](https://neovim.io/doc/user/eval.html#b:changedtick)
68/// variable.
69pub type OnChangedtickArgs = (String, Buffer, u32);
70
71/// Arguments passed to the callback registered to
72/// [`on_detach`](BufAttachOptsBuilder::on_detach). The first tuple element is
73/// the string literal `"detach"`, the second is the [`Buffer`] that triggered
74/// the callback.
75pub type OnDetachArgs = (String, Buffer);
76
77/// Arguments passed to the callback registered to
78/// [`on_reload`](BufAttachOptsBuilder::on_reload). The first tuple element is
79/// the string literal `"reload"`, the second is the [`Buffer`] that triggered
80/// the callback.
81pub type OnReloadArgs = (String, Buffer);
82
83/// All the registered callbacks can detach by returning `true`, as described
84/// in `:h api-lua-detach`.
85pub type ShouldDetach = bool;
86
87/// Options passed to [`Buffer::attach`](crate::Buffer::attach).
88#[derive(Clone, Debug, Default, Builder)]
89#[builder(default, build_fn(private, name = "fallible_build"))]
90pub struct BufAttachOpts {
91    #[builder(setter(custom))]
92    on_bytes: Object,
93
94    #[builder(setter(custom))]
95    on_changedtick: Object,
96
97    #[builder(setter(custom))]
98    on_detach: Object,
99
100    #[builder(setter(custom))]
101    on_lines: Object,
102
103    #[builder(setter(custom))]
104    on_reload: Object,
105
106    /// Whether to also attach to command preview (i.e.
107    /// [`inccommand`](https://neovim.io/doc/user/options.html#'inccommand'))
108    /// events.
109    preview: bool,
110
111    /// Whether to include the UTF-32 and UTF-16 sizes of the replaced region
112    /// as the last arguments of the
113    /// [`on_lines`](BufAttachOptsBuilder::on_lines) callback.
114    utf_sizes: bool,
115}
116
117impl BufAttachOpts {
118    #[inline(always)]
119    /// Creates a new [`BufAttachOptsBuilder`].
120    pub fn builder() -> BufAttachOptsBuilder {
121        BufAttachOptsBuilder::default()
122    }
123}
124
125impl BufAttachOptsBuilder {
126    /// Callback invoked on change. It receives more granular information about
127    /// the change compared to [`on_lines`](BufAttachOptsBuilder::on_lines).
128    pub fn on_bytes<F>(&mut self, fun: F) -> &mut Self
129    where
130        F: ToFunction<OnBytesArgs, ShouldDetach>,
131    {
132        self.on_bytes = Some(fun.to_object());
133        self
134    }
135
136    /// Callback invoked on changedtick increment without text change.
137    pub fn on_changedtick<F>(&mut self, fun: F) -> &mut Self
138    where
139        F: ToFunction<OnChangedtickArgs, ShouldDetach>,
140    {
141        self.on_changedtick = Some(fun.to_object());
142        self
143    }
144
145    /// Callback invoked on detach.
146    pub fn on_detach<F>(&mut self, fun: F) -> &mut Self
147    where
148        F: ToFunction<OnDetachArgs, ShouldDetach>,
149    {
150        self.on_detach = Some(fun.to_object());
151        self
152    }
153
154    /// Callback invoked on change.
155    pub fn on_lines<F>(&mut self, fun: F) -> &mut Self
156    where
157        F: ToFunction<OnLinesArgs, ShouldDetach>,
158    {
159        self.on_lines = Some(fun.to_object());
160        self
161    }
162
163    /// Callback invoked on reload. The entire buffer content should be
164    /// considered changed.
165    pub fn on_reload<F>(&mut self, fun: F) -> &mut Self
166    where
167        F: ToFunction<OnReloadArgs, ShouldDetach>,
168    {
169        self.on_reload = Some(fun.to_object());
170        self
171    }
172
173    pub fn build(&mut self) -> BufAttachOpts {
174        self.fallible_build().expect("never fails, all fields have defaults")
175    }
176}
177
178impl From<&BufAttachOpts> for Dictionary {
179    fn from(opts: &BufAttachOpts) -> Self {
180        // TODO: don't clone by making non-owning version of Dictionary
181        Self::from_iter([
182            ("on_bytes", opts.on_bytes.clone()),
183            ("on_changedtick", opts.on_changedtick.clone()),
184            ("on_detach", opts.on_detach.clone()),
185            ("on_lines", opts.on_lines.clone()),
186            ("on_reload", opts.on_reload.clone()),
187            ("preview", opts.preview.into()),
188            ("utf_sizes", opts.utf_sizes.into()),
189        ])
190    }
191}