#![allow(dead_code, non_snake_case)]
use crate::ported::buffer::buflist_findnr;
use crate::ported::eval_h::{FAIL, OK};
use crate::ported::window::{curwin, pos_T};
use std::cell::RefCell;
use std::collections::HashMap;
thread_local! {
static MARKS: RefCell<HashMap<(i32, u8), pos_T>> = RefCell::new(HashMap::new());
}
pub fn setmark_pos(c: i32, pos: &pos_T, fnum: i32) -> i32 {
if c < 0 {
return FAIL;
}
let cc = c as u8;
if cc == b'\'' || cc == b'`' {
let _ = curwin.with(|c| c.borrow().is_some());
MARKS.with(|m| m.borrow_mut().insert((0, cc), *pos));
return OK; }
if buflist_findnr(fnum).is_none() {
return FAIL; }
if cc == b'"' || cc == b'[' || cc == b']' || cc == b'<' || cc == b'>' {
MARKS.with(|m| m.borrow_mut().insert((fnum, cc), *pos));
return OK;
}
if cc.is_ascii_lowercase() {
MARKS.with(|m| m.borrow_mut().insert((fnum, cc), *pos));
return OK; }
if cc.is_ascii_uppercase() || cc.is_ascii_digit() {
MARKS.with(|m| m.borrow_mut().insert((0, cc), *pos));
return OK; }
FAIL
}
#[cfg(test)]
mod tests {
fn mark_get_pos(fnum: i32, c: u8) -> Option<pos_T> {
super::MARKS.with(|m| m.borrow().get(&(fnum, c)).copied())
}
use super::*;
use crate::ported::buffer::{buflist_new, curbuf, firstbuf, lastbuf, top_file_num, BLN_LISTED};
#[test]
fn setmark_pos_lower_requires_buffer() {
MARKS.with(|m| m.borrow_mut().clear());
firstbuf.with(|f| *f.borrow_mut() = None);
lastbuf.with(|l| *l.borrow_mut() = None);
curbuf.with(|c| *c.borrow_mut() = None);
top_file_num.with(|t| t.set(1));
let pos = pos_T {
lnum: 3,
col: 5,
coladd: 0,
};
assert_eq!(setmark_pos(b'a' as i32, &pos, 999), FAIL);
let buf = buflist_new(Some("/tmp/mk".into()), None, 0, BLN_LISTED).unwrap();
let fnum = buf.borrow().handle;
curbuf.with(|c| *c.borrow_mut() = Some(buf.clone()));
assert_eq!(setmark_pos(b'a' as i32, &pos, fnum), OK);
assert_eq!(mark_get_pos(fnum, b'a'), Some(pos));
}
#[test]
fn setmark_pos_rejects_negative_and_junk() {
assert_eq!(setmark_pos(-1, &pos_T::default(), 0), FAIL);
assert_eq!(setmark_pos(b'!' as i32, &pos_T::default(), 0), FAIL);
}
#[test]
fn setmark_pos_context_mark_no_buffer() {
MARKS.with(|m| m.borrow_mut().clear());
let pos = pos_T {
lnum: 7,
col: 1,
coladd: 0,
};
assert_eq!(setmark_pos(b'`' as i32, &pos, 0), OK);
assert_eq!(mark_get_pos(0, b'`'), Some(pos));
}
}