Skip to main content

ytil_noxi/
jumplist.rs

1//! Neovim jumplist utilities for accessing jump history.
2
3use nvim_oxi::Array;
4use nvim_oxi::Object;
5use nvim_oxi::conversion::FromObject;
6use nvim_oxi::lua::Poppable;
7use nvim_oxi::lua::ffi::State;
8use serde::Deserialize;
9
10/// Represents a single entry in Neovim's jumplist.
11#[derive(Clone, Debug, Deserialize)]
12pub struct JumpEntry {
13    pub bufnr: i32,
14    pub col: i32,
15    pub coladd: i32,
16    pub lnum: i32,
17}
18
19/// Retrieves the current jumplist from Neovim.
20pub fn get() -> Option<Vec<JumpEntry>> {
21    Some(
22        nvim_oxi::api::call_function::<_, JumpList>("getjumplist", Array::new())
23            .inspect_err(|err| crate::notify::error(format!("error getting jumplist | error={err:?}")))
24            .ok()?
25            .0,
26    )
27}
28
29/// Internal representation of Neovim's jumplist structure.
30#[derive(Debug, Deserialize)]
31#[expect(
32    dead_code,
33    reason = "jumplist index is decoded to match Neovim return shape but not currently used"
34)]
35struct JumpList(Vec<JumpEntry>, usize);
36
37impl FromObject for JumpList {
38    fn from_object(obj: Object) -> Result<Self, nvim_oxi::conversion::Error> {
39        Self::deserialize(nvim_oxi::serde::Deserializer::new(obj)).map_err(Into::into)
40    }
41}
42
43impl Poppable for JumpList {
44    unsafe fn pop(lstate: *mut State) -> Result<Self, nvim_oxi::lua::Error> {
45        // SAFETY: The caller (nvim-oxi framework) guarantees that:
46        // 1. `lstate` is a valid pointer to an initialized Lua state
47        // 2. The Lua stack has at least one value to pop
48        unsafe {
49            let obj = Object::pop(lstate)?;
50            Self::from_object(obj).map_err(nvim_oxi::lua::Error::pop_error_from_err::<Self, _>)
51        }
52    }
53}