#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub type handle_T = i32;
pub type linenr_T = i32;
pub type colnr_T = i32;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct pos_T {
pub lnum: linenr_T,
pub col: colnr_T,
pub coladd: colnr_T,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct WinConfig {
pub focusable: bool,
pub hide: bool,
}
pub use crate::ported::buffer::buf_T;
#[derive(Default)]
pub struct win_T {
pub handle: handle_T,
pub w_buffer: Option<Rc<RefCell<buf_T>>>,
pub w_prev: Option<Weak<RefCell<win_T>>>,
pub w_next: Option<Rc<RefCell<win_T>>>,
pub w_cursor: pos_T,
pub w_p_pvw: bool,
pub w_floating: bool,
pub w_config: WinConfig,
}
#[derive(Default)]
pub struct tabpage_T {
pub handle: handle_T,
pub tp_next: Option<Rc<RefCell<tabpage_T>>>,
pub tp_curwin: Option<Rc<RefCell<win_T>>>,
pub tp_prevwin: Option<Rc<RefCell<win_T>>>,
pub tp_firstwin: Option<Rc<RefCell<win_T>>>,
pub tp_lastwin: Option<Rc<RefCell<win_T>>>,
}
thread_local! {
pub static firstwin: RefCell<Option<Rc<RefCell<win_T>>>> = const { RefCell::new(None) };
pub static lastwin: RefCell<Option<Rc<RefCell<win_T>>>> = const { RefCell::new(None) };
pub static curwin: RefCell<Option<Rc<RefCell<win_T>>>> = const { RefCell::new(None) };
pub static first_tabpage: RefCell<Option<Rc<RefCell<tabpage_T>>>> = const { RefCell::new(None) };
pub static curtab: RefCell<Option<Rc<RefCell<tabpage_T>>>> = const { RefCell::new(None) };
}
pub fn find_tabpage(n: i32) -> Option<Rc<RefCell<tabpage_T>>> {
let mut i = 1;
if n == 0 {
return curtab.with(|c| c.borrow().clone()); }
let mut tp = first_tabpage.with(|c| c.borrow().clone());
while let Some(cur) = tp.clone() {
if i == n {
break;
}
i += 1; tp = cur.borrow().tp_next.clone();
}
tp }
pub fn win_get_tabwin(id: handle_T, tabnr: &mut i32, winnr: &mut i32) {
*tabnr = 0; *winnr = 0;
let mut tnum = 1; let mut wnum = 1; let mut tp = first_tabpage.with(|c| c.borrow().clone());
while let Some(tp_rc) = tp.clone() {
let is_curtab =
curtab.with(|c| c.borrow().as_ref().is_some_and(|ct| Rc::ptr_eq(ct, &tp_rc)));
let mut wp = if is_curtab {
firstwin.with(|c| c.borrow().clone())
} else {
tp_rc.borrow().tp_firstwin.clone()
};
while let Some(wp_rc) = wp.clone() {
if wp_rc.borrow().handle == id {
if crate::ported::eval::window::win_has_winnr(&wp_rc, &tp_rc) {
*winnr = wnum; *tabnr = tnum; }
return; }
wnum += crate::ported::eval::window::win_has_winnr(&wp_rc, &tp_rc) as i32; wp = wp_rc.borrow().w_next.clone();
}
tnum += 1; wnum = 1; tp = tp_rc.borrow().tp_next.clone();
}
}
#[cfg(test)]
mod tests {
use super::*;
fn build_two_windows() -> (
Rc<RefCell<tabpage_T>>,
Rc<RefCell<win_T>>,
Rc<RefCell<win_T>>,
) {
let w0 = Rc::new(RefCell::new(win_T {
handle: 1000,
w_config: WinConfig {
focusable: true,
hide: false,
},
..Default::default()
}));
let w1 = Rc::new(RefCell::new(win_T {
handle: 1001,
w_config: WinConfig {
focusable: true,
hide: false,
},
..Default::default()
}));
w0.borrow_mut().w_next = Some(w1.clone());
w1.borrow_mut().w_prev = Some(Rc::downgrade(&w0));
let tab = Rc::new(RefCell::new(tabpage_T {
handle: 1,
tp_firstwin: Some(w0.clone()),
tp_lastwin: Some(w1.clone()),
tp_curwin: Some(w0.clone()),
..Default::default()
}));
firstwin.with(|c| *c.borrow_mut() = Some(w0.clone()));
lastwin.with(|c| *c.borrow_mut() = Some(w1.clone()));
curwin.with(|c| *c.borrow_mut() = Some(w0.clone()));
first_tabpage.with(|c| *c.borrow_mut() = Some(tab.clone()));
curtab.with(|c| *c.borrow_mut() = Some(tab.clone()));
(tab, w0, w1)
}
#[test]
fn find_tabpage_number_and_zero() {
let (tab, _w0, _w1) = build_two_windows();
let cur = find_tabpage(0).unwrap();
assert!(Rc::ptr_eq(&cur, &tab));
let first = find_tabpage(1).unwrap();
assert!(Rc::ptr_eq(&first, &tab));
assert!(find_tabpage(2).is_none());
}
#[test]
fn win_get_tabwin_finds_and_misses() {
let (_tab, _w0, _w1) = build_two_windows();
let mut tabnr = -1;
let mut winnr = -1;
win_get_tabwin(1001, &mut tabnr, &mut winnr);
assert_eq!((tabnr, winnr), (1, 2));
let mut tabnr2 = -1;
let mut winnr2 = -1;
win_get_tabwin(9999, &mut tabnr2, &mut winnr2);
assert_eq!((tabnr2, winnr2), (0, 0));
}
}