use crate::mm::{BufferId, Position};
pub const MAX_JUMPLIST_SIZE: usize = 100;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JumpEntry {
pub buffer: BufferId,
pub position: Position,
}
impl JumpEntry {
#[must_use]
pub const fn new(buffer: BufferId, position: Position) -> Self {
Self { buffer, position }
}
}
#[derive(Debug, Default, Clone)]
pub struct Jumplist {
entries: Vec<JumpEntry>,
current: usize,
}
impl Jumplist {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
entries: Vec::with_capacity(capacity.min(MAX_JUMPLIST_SIZE)),
current: 0,
}
}
pub fn push(&mut self, entry: JumpEntry) -> bool {
if self.entries.last() == Some(&entry) {
self.current = self.entries.len();
return false;
}
self.entries.truncate(self.current);
self.entries.push(entry);
if self.entries.len() > MAX_JUMPLIST_SIZE {
self.entries.remove(0);
}
self.current = self.entries.len();
true
}
#[cfg_attr(coverage_nightly, coverage(off))]
pub fn push_current(&mut self, entry: JumpEntry) -> bool {
if self.entries.last() == Some(&entry) {
if !self.entries.is_empty() {
self.current = self.entries.len() - 1;
}
return false;
}
self.entries.push(entry);
if self.entries.len() > MAX_JUMPLIST_SIZE {
self.entries.remove(0);
}
self.current = self.entries.len();
true
}
pub fn backward(&mut self) -> Option<&JumpEntry> {
if self.current > 0 {
self.current -= 1;
self.entries.get(self.current)
} else {
None
}
}
pub fn forward(&mut self) -> Option<&JumpEntry> {
if self.current < self.entries.len() {
let entry = self.entries.get(self.current);
self.current += 1;
entry
} else {
None
}
}
#[must_use]
#[cfg_attr(coverage_nightly, coverage(off))]
pub fn current(&self) -> Option<&JumpEntry> {
if self.current > 0 && self.current <= self.entries.len() {
self.entries.get(self.current - 1)
} else {
None
}
}
#[must_use]
pub const fn current_index(&self) -> usize {
self.current
}
#[must_use]
pub fn entries(&self) -> &[JumpEntry] {
&self.entries
}
#[must_use]
#[allow(clippy::missing_const_for_fn)] pub fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
#[allow(clippy::missing_const_for_fn)] pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn clear(&mut self) {
self.entries.clear();
self.current = 0;
}
}