From 5096de5e123066b8f06ec3c69cbbdb793fc69adf Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 13 Nov 2021 14:41:44 +0800 Subject: [PATCH] Add last modified file (gm) --- book/src/keymap.md | 3 ++- helix-term/src/commands.rs | 19 +++++++++++++++++-- helix-term/src/keymap.rs | 3 ++- helix-view/src/document.rs | 6 ++++++ helix-view/src/editor.rs | 14 ++++++++++++-- helix-view/src/view.rs | 6 ++++++ 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 88610a77947a..4aec6035527b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -159,13 +159,14 @@ Jumps to various locations. | `l` | Go to the end of the line | `goto_line_end` | | `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` | | `t` | Go to the top of the screen | `goto_window_top` | -| `m` | Go to the middle of the screen | `goto_window_middle` | +| `c` | Go to the middle of the screen | `goto_window_center` | | `b` | Go to the bottom of the screen | `goto_window_bottom` | | `d` | Go to definition (**LSP**) | `goto_definition` | | `y` | Go to type definition (**LSP**) | `goto_type_definition` | | `r` | Go to references (**LSP**) | `goto_reference` | | `i` | Go to implementation (**LSP**) | `goto_implementation` | | `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` | +| `m` | Go to the last modified/alternate file | `goto_last_modified_file` | | `n` | Go to next buffer | `goto_next_buffer` | | `p` | Go to previous buffer | `goto_previous_buffer` | | `.` | Go to last modification in current file | `goto_last_modification` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 8c0a005cc816..f5e6139bbfe5 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -257,9 +257,10 @@ impl Command { goto_file_end, "Goto file end", goto_reference, "Goto references", goto_window_top, "Goto window top", - goto_window_middle, "Goto window middle", + goto_window_center, "Goto window center", goto_window_bottom, "Goto window bottom", goto_last_accessed_file, "Goto last accessed file", + goto_last_modified_file, "Goto last modified file", goto_last_modification, "Goto last modification", goto_line, "Goto line", goto_last_line, "Goto last line", @@ -653,7 +654,7 @@ fn goto_window_top(cx: &mut Context) { goto_window(cx, Align::Top) } -fn goto_window_middle(cx: &mut Context) { +fn goto_window_center(cx: &mut Context) { goto_window(cx, Align::Center) } @@ -3334,6 +3335,20 @@ fn goto_last_modification(cx: &mut Context) { } } +fn goto_last_modified_file(cx: &mut Context) { + let view = view!(cx.editor); + let alternate_file = view + .last_modified_docs + .into_iter() + .flatten() + .find(|&id| id != view.doc); + if let Some(alt) = alternate_file { + cx.editor.switch(alt, Action::Replace); + } else { + cx.editor.set_error("no last modified buffer".to_owned()) + } +} + fn select_mode(cx: &mut Context) { let (view, doc) = current!(cx.editor); let text = doc.text().slice(..); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 010714dcb4db..e97d13ce7d95 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -520,9 +520,10 @@ impl Default for Keymaps { "r" => goto_reference, "i" => goto_implementation, "t" => goto_window_top, - "m" => goto_window_middle, + "c" => goto_window_center, "b" => goto_window_bottom, "a" => goto_last_accessed_file, + "m" => goto_last_modified_file, "n" => goto_next_buffer, "p" => goto_previous_buffer, "." => goto_last_modification, diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 76b19a07d9b5..2cb33fe32edb 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -104,6 +104,7 @@ pub struct Document { last_saved_revision: usize, version: i32, // should be usize? + pub(crate) modified_since_accessed: bool, diagnostics: Vec, language_server: Option>, @@ -127,6 +128,7 @@ impl fmt::Debug for Document { // .field("history", &self.history) .field("last_saved_revision", &self.last_saved_revision) .field("version", &self.version) + .field("modified_since_accessed", &self.modified_since_accessed) .field("diagnostics", &self.diagnostics) // .field("language_server", &self.language_server) .finish() @@ -344,6 +346,7 @@ impl Document { history: Cell::new(History::default()), savepoint: None, last_saved_revision: 0, + modified_since_accessed: false, language_server: None, } } @@ -639,6 +642,9 @@ impl Document { selection.clone().ensure_invariants(self.text.slice(..)), ); } + + // set modified since accessed + self.modified_since_accessed = true; } if !transaction.changes().is_empty() { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index e401570762d0..cea42bea6a1c 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -260,7 +260,8 @@ impl Editor { .tree .traverse() .any(|(_, v)| v.doc == doc.id && v.id != view.id); - let view = view_mut!(self); + + let (view, doc) = current!(self); if remove_empty_scratch { // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable // borrow, invalidating direct access to `doc.id`. @@ -269,7 +270,16 @@ impl Editor { } else { let jump = (view.doc, doc.selection(view.id).clone()); view.jumps.push(jump); - view.last_accessed_doc = Some(view.doc); + // Set last accessed doc if it is a different document + if doc.id != id { + view.last_accessed_doc = Some(view.doc); + // Set last modified doc if modified and last modified doc is different + if std::mem::take(&mut doc.modified_since_accessed) + && view.last_modified_docs[0] != Some(id) + { + view.last_modified_docs = [Some(view.doc), view.last_modified_docs[0]]; + } + } } view.doc = id; view.offset = Position::default(); diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 6a624ded2836..4c8288fa3ce8 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -65,6 +65,11 @@ pub struct View { pub jumps: JumpList, /// the last accessed file before the current one pub last_accessed_doc: Option, + /// the last modified files before the current one + /// ordered from most frequent to least frequent + // uses two docs because we want to be able to swap between the + // two last modified docs which we need to manually keep track of + pub last_modified_docs: [Option; 2], } impl View { @@ -76,6 +81,7 @@ impl View { area: Rect::default(), // will get calculated upon inserting into tree jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel last_accessed_doc: None, + last_modified_docs: [None, None], } }