Trivial jumplist implementation.

This commit is contained in:
Blaž Hrastnik 2021-03-24 18:01:26 +09:00
parent 4b176caded
commit 8657c57cf2
4 changed files with 70 additions and 1 deletions

View File

@ -1642,3 +1642,25 @@ pub fn match_brackets(cx: &mut Context) {
};
}
}
//
pub fn jump_forward(cx: &mut Context) {
let count = cx.count;
let view = cx.view();
if let Some((id, selection)) = view.jumps.forward(count) {
view.first_line = 0;
view.doc = *id;
};
}
pub fn jump_backward(cx: &mut Context) {
let count = cx.count;
let view = cx.view();
if let Some((id, selection)) = view.jumps.backward(count) {
view.first_line = 0;
view.doc = *id;
};
}

View File

@ -253,6 +253,9 @@ pub fn default() -> Keymaps {
shift!('K') => commands::hover,
// z family for save/restore/combine from/to sels from register
ctrl!('i') => commands::jump_forward, // TODO: ctrl-i conflicts tab
ctrl!('o') => commands::jump_backward,
);
// TODO: decide whether we want normal mode to also be select mode (kakoune-like), or whether
// we keep this separate select mode. More keys can fit into normal mode then, but it's weird

View File

@ -90,7 +90,11 @@ pub fn open(&mut self, path: PathBuf, action: Action) -> Result<DocumentId, Erro
use crate::tree::Layout;
match action {
Action::Replace => {
let view = self.view();
let jump = (view.doc, self.documents[view.doc].selection().clone());
let view = self.view_mut();
view.jumps.push(jump);
view.doc = id;
view.first_line = 0;
return Ok(id);

View File

@ -5,17 +5,56 @@
use crate::{Document, DocumentId, ViewId};
use helix_core::{
graphemes::{grapheme_width, RopeGraphemes},
Position, RopeSlice,
Position, RopeSlice, Selection,
};
use tui::layout::Rect;
pub const PADDING: usize = 5;
type Jump = (DocumentId, Selection);
pub struct JumpList {
jumps: Vec<Jump>,
current: usize,
}
impl JumpList {
pub fn new(initial: Jump) -> Self {
Self {
jumps: vec![initial],
current: 0,
}
}
pub fn push(&mut self, jump: Jump) {
self.jumps.truncate(self.current + 1);
self.jumps.push(jump);
self.current += 1;
}
pub fn forward(&mut self, count: usize) -> Option<&Jump> {
if self.current + count < self.jumps.len() {
self.current += count;
return self.jumps.get(self.current);
}
None
}
pub fn backward(&mut self, count: usize) -> Option<&Jump> {
if self.current.checked_sub(count).is_some() {
self.current -= count;
return self.jumps.get(self.current);
}
None
}
}
pub struct View {
pub id: ViewId,
pub doc: DocumentId,
pub first_line: usize,
pub area: Rect,
pub jumps: JumpList,
}
impl View {
@ -25,6 +64,7 @@ pub fn new(doc: DocumentId) -> Result<Self, Error> {
doc,
first_line: 0,
area: Rect::default(), // will get calculated upon inserting into tree
jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel
};
Ok(view)