diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 810c98c1..3358f9d2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1308,7 +1308,7 @@ pub fn normal_mode(cx: &mut Context) { // Store a jump on the jumplist. fn push_jump(editor: &mut Editor) { let (view, doc) = editor.current(); - let jump = { (doc.id(), doc.selection(view.id).clone()) }; + let jump = (doc.id(), doc.selection(view.id).clone()); view.jumps.push(jump); } @@ -2446,7 +2446,7 @@ pub fn jump_backward(cx: &mut Context) { let count = cx.count(); let (view, doc) = cx.current(); - if let Some((id, selection)) = view.jumps.backward(count) { + if let Some((id, selection)) = view.jumps.backward(view.id, doc, count) { view.doc = *id; let selection = selection.clone(); let (view, doc) = cx.current(); // refetch doc diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index a6417cfd..39bd5f3b 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -280,7 +280,10 @@ pub fn default() -> Keymaps { // z family for save/restore/combine from/to sels from register - ctrl!('i') => commands::jump_forward, // TODO: ctrl-i conflicts tab + KeyEvent { // supposedly ctrl!('i') but did not work + code: KeyCode::Tab, + modifiers: KeyModifiers::NONE, + } => commands::jump_forward, ctrl!('o') => commands::jump_backward, // ctrl!('s') => commands::save_selection, diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index b7bfaa17..7bd31305 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -37,17 +37,24 @@ impl JumpList { 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); + self.jumps.get(self.current) + } else { + None } - 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); + // Taking view and doc to prevent unnecessary cloning when jump is not required. + pub fn backward(&mut self, view_id: ViewId, doc: &mut Document, count: usize) -> Option<&Jump> { + if let Some(current) = self.current.checked_sub(count) { + if self.current == self.jumps.len() { + let jump = (doc.id(), doc.selection(view_id).clone()); + self.push(jump); + } + self.current = current; + self.jumps.get(self.current) + } else { + None } - None } }