nvim_oxi_api/
tabpage.rs

1use std::fmt;
2use std::result::Result as StdResult;
3
4use luajit::{self as lua, Poppable, Pushable};
5use serde::{Deserialize, Serialize};
6use types::{
7    self as nvim,
8    conversion::{self, FromObject, ToObject},
9    Object,
10    TabHandle,
11};
12
13use crate::choose;
14use crate::ffi::tabpage::*;
15use crate::Result;
16use crate::SuperIterator;
17use crate::Window;
18
19/// A wrapper around a Neovim tab handle.
20#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
21pub struct TabPage(pub(crate) TabHandle);
22
23impl fmt::Debug for TabPage {
24    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25        f.debug_tuple("TabPage").field(&self.0).finish()
26    }
27}
28
29impl fmt::Display for TabPage {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        fmt::Debug::fmt(self, f)
32    }
33}
34
35impl<H: Into<TabHandle>> From<H> for TabPage {
36    fn from(handle: H) -> Self {
37        Self(handle.into())
38    }
39}
40
41impl From<TabPage> for Object {
42    fn from(tabpage: TabPage) -> Self {
43        tabpage.0.into()
44    }
45}
46
47impl Poppable for TabPage {
48    unsafe fn pop(
49        lstate: *mut lua::ffi::lua_State,
50    ) -> std::result::Result<Self, lua::Error> {
51        TabHandle::pop(lstate).map(Into::into)
52    }
53}
54
55impl Pushable for TabPage {
56    unsafe fn push(
57        self,
58        lstate: *mut lua::ffi::lua_State,
59    ) -> std::result::Result<std::ffi::c_int, lua::Error> {
60        self.0.push(lstate)
61    }
62}
63
64impl FromObject for TabPage {
65    fn from_object(obj: Object) -> StdResult<Self, conversion::Error> {
66        Ok(TabHandle::from_object(obj)?.into())
67    }
68}
69
70impl TabPage {
71    /// Shorthand for [`get_current_tabpage`](crate::get_current_tabpage).
72    #[inline(always)]
73    pub fn current() -> Self {
74        crate::get_current_tabpage()
75    }
76
77    /// Retrieve tabpage's underlying id/handle
78    #[inline(always)]
79    pub fn handle(&self) -> i32 {
80        self.0
81    }
82
83    /// Binding to [`nvim_tabpage_del_var()`][1].
84    ///
85    /// Removes a tab-scoped (`t:`) variable.
86    ///
87    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_del_var()
88    pub fn del_var(&mut self, name: &str) -> Result<()> {
89        let mut err = nvim::Error::new();
90        let name = nvim::String::from(name);
91        unsafe { nvim_tabpage_del_var(self.0, name.non_owning(), &mut err) };
92        choose!(err, ())
93    }
94
95    /// Binding to [`nvim_tabpage_get_number()`][1].
96    ///
97    /// Gets the tabpage number.
98    ///
99    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_get_number()
100    pub fn get_number(&self) -> Result<u32> {
101        let mut err = nvim::Error::new();
102        let number = unsafe { nvim_tabpage_get_number(self.0, &mut err) };
103        choose!(err, Ok(number.try_into().expect("always positive")))
104    }
105
106    /// Binding to [`nvim_tabpage_get_var()`][1].
107    ///
108    /// Gets a tab-scoped (`t:`) variable.
109    ///
110    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_get_var()
111    pub fn get_var<Var>(&self, name: &str) -> Result<Var>
112    where
113        Var: FromObject,
114    {
115        let mut err = nvim::Error::new();
116        let name = nvim::String::from(name);
117        let obj = unsafe {
118            nvim_tabpage_get_var(
119                self.0,
120                name.non_owning(),
121                #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
122                types::arena(),
123                &mut err,
124            )
125        };
126        choose!(err, Ok(Var::from_object(obj)?))
127    }
128
129    /// Binding to [`nvim_tabpage_get_win()`][1].
130    ///
131    /// Gets the current window in a tabpage.
132    ///
133    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_get_win()
134    pub fn get_win(&self) -> Result<Window> {
135        let mut err = nvim::Error::new();
136        let handle = unsafe { nvim_tabpage_get_win(self.0, &mut err) };
137        choose!(err, Ok(handle.into()))
138    }
139
140    /// Binding to [`nvim_tabpage_is_valid()`][1].
141    ///
142    /// Checks if a tabpage is valid.
143    ///
144    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_is_valid()
145    pub fn is_valid(&self) -> bool {
146        unsafe { nvim_tabpage_is_valid(self.0) }
147    }
148
149    /// Binding to [`nvim_tabpage_list_wins()`][1].
150    ///
151    /// Gets the windows in a tabpage.
152    ///
153    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_list_wins()
154    pub fn list_wins(&self) -> Result<impl SuperIterator<Window>> {
155        let mut err = nvim::Error::new();
156        let list = unsafe {
157            nvim_tabpage_list_wins(
158                self.0,
159                #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
160                types::arena(),
161                &mut err,
162            )
163        };
164        choose!(
165            err,
166            Ok({
167                list.into_iter().map(|obj| Window::from_object(obj).unwrap())
168            })
169        )
170    }
171
172    /// Binding to [`nvim_tabpage_set_var()`][1].
173    ///
174    /// Sets a tab-scoped (`t:`) variable.
175    ///
176    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_set_var()
177    pub fn set_var<Var>(&mut self, name: &str, value: Var) -> Result<()>
178    where
179        Var: ToObject,
180    {
181        let mut err = nvim::Error::new();
182        let name = nvim::String::from(name);
183        unsafe {
184            nvim_tabpage_set_var(
185                self.0,
186                name.non_owning(),
187                value.to_object()?.non_owning(),
188                &mut err,
189            )
190        };
191        choose!(err, ())
192    }
193
194    /// Binding to [`nvim_tabpage_set_win()`][1].
195    ///
196    /// Sets the current window in the tabpage.
197    ///
198    /// [1]: https://neovim.io/doc/user/api.html#nvim_tabpage_set_win()
199    #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly.
200    #[cfg_attr(
201        docsrs,
202        doc(cfg(any(feature = "neovim-0-10", feature = "neovim-nightly")))
203    )]
204    pub fn set_win(&mut self, win: &Window) -> Result<()> {
205        let mut err = nvim::Error::new();
206        unsafe { nvim_tabpage_set_win(self.0, win.0, &mut err) };
207        choose!(err, ())
208    }
209}