From 8be56b0791eae18917303877ef990843ddb64e5e Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 14:10:01 -0600 Subject: [PATCH 1/7] add document_history to Editor, and buffer_reopen() command --- helix-term/src/commands/typed.rs | 33 ++++++++++++++++++++++++++++++++ helix-view/src/editor.rs | 5 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 200323e10..7821886fe 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -321,6 +321,28 @@ fn buffer_previous( Ok(()) } +fn buffer_reopen( + cx: &mut compositor::Context, + _args: Args, + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + let last_closed_doc_path: Option = if let Some(last_closed_doc_path) = cx.editor.document_history + .iter() + .filter(|path| cx.editor.document_by_path(path).is_none()) + .next() + { + Some(last_closed_doc_path.clone()) + } else { None };: + if let Some(path) = last_closed_doc_path { + cx.editor.open(&path, Action::Load)?; + } + Ok(()) +} + fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) -> anyhow::Result<()> { let config = cx.editor.config(); let jobs = &mut cx.jobs; @@ -2703,6 +2725,17 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ ..Signature::DEFAULT }, }, + TypableCommand { + name: "buffer-reopen", + aliases: &["bro"], + doc: "Re-open the most previously closed buffer.", + fun: buffer_reopen, + completer: CommandCompleter::none(), + signature: Signature { + positionals: (0, Some(0)), + ..Signature::DEFAULT + }, + }, TypableCommand { name: "write", aliases: &["w"], diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 9aa073fcf..5a06d628f 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1060,7 +1060,8 @@ pub struct Editor { pub tree: Tree, pub next_document_id: DocumentId, pub documents: BTreeMap, - + pub document_history: Vec, + // We Flatten<> to resolve the inner DocumentSavedEventFuture. For that we need a stream of streams, hence the Once<>. // https://stackoverflow.com/a/66875668 pub saves: HashMap>>, @@ -1211,6 +1212,7 @@ impl Editor { tree: Tree::new(area), next_document_id: DocumentId::default(), documents: BTreeMap::new(), + document_history: Vec::new(), saves: HashMap::new(), save_queue: SelectAll::new(), write_count: 0, @@ -1797,6 +1799,7 @@ impl Editor { let id = self.new_document(doc); self.launch_language_servers(id); + self.document_history.push(path); helix_event::dispatch(DocumentDidOpen { editor: self, From bc395cfa979747e12d9e896bf3610a8d21fffc99 Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 14:43:18 -0600 Subject: [PATCH 2/7] get last change instead of first --- helix-term/src/commands/typed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 7821886fe..1c22077a8 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -333,10 +333,10 @@ fn buffer_reopen( let last_closed_doc_path: Option = if let Some(last_closed_doc_path) = cx.editor.document_history .iter() .filter(|path| cx.editor.document_by_path(path).is_none()) - .next() + .last() { Some(last_closed_doc_path.clone()) - } else { None };: + } else { None }; if let Some(path) = last_closed_doc_path { cx.editor.open(&path, Action::Load)?; } From 56a55d784fd8eafcd292e0f38bdf46c6604586b8 Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 17:49:19 -0600 Subject: [PATCH 3/7] improve buffer_reopen() logic --- helix-term/src/commands/typed.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 1c22077a8..954fcd677 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -330,15 +330,13 @@ fn buffer_reopen( return Ok(()); } - let last_closed_doc_path: Option = if let Some(last_closed_doc_path) = cx.editor.document_history + if let Some(last_closed_doc_path) = cx.editor.document_history .iter() .filter(|path| cx.editor.document_by_path(path).is_none()) .last() + .cloned() { - Some(last_closed_doc_path.clone()) - } else { None }; - if let Some(path) = last_closed_doc_path { - cx.editor.open(&path, Action::Load)?; + cx.editor.open(&last_closed_doc_path, Action::Load)?; } Ok(()) } From 0b967fa5d97ff1e0a1aef97c4211a626d9622ec6 Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 18:25:35 -0600 Subject: [PATCH 4/7] better handling of the closed buffer history --- helix-term/src/commands/typed.rs | 9 +++------ helix-view/src/editor.rs | 8 +++++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 954fcd677..d0306265f 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -330,13 +330,10 @@ fn buffer_reopen( return Ok(()); } - if let Some(last_closed_doc_path) = cx.editor.document_history - .iter() - .filter(|path| cx.editor.document_by_path(path).is_none()) - .last() - .cloned() + if let Some(last_closed_doc_path) = cx.editor.closed_document_paths.pop() { - cx.editor.open(&last_closed_doc_path, Action::Load)?; + let id = cx.editor.open(&last_closed_doc_path, Action::Load)?; + cx.editor.switch(id, Action::Load); } Ok(()) } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5a06d628f..dedec6a6e 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1060,7 +1060,7 @@ pub struct Editor { pub tree: Tree, pub next_document_id: DocumentId, pub documents: BTreeMap, - pub document_history: Vec, + pub closed_document_paths: Vec, // We Flatten<> to resolve the inner DocumentSavedEventFuture. For that we need a stream of streams, hence the Once<>. // https://stackoverflow.com/a/66875668 @@ -1212,7 +1212,7 @@ impl Editor { tree: Tree::new(area), next_document_id: DocumentId::default(), documents: BTreeMap::new(), - document_history: Vec::new(), + closed_document_paths: Vec::new(), saves: HashMap::new(), save_queue: SelectAll::new(), write_count: 0, @@ -1799,7 +1799,6 @@ impl Editor { let id = self.new_document(doc); self.launch_language_servers(id); - self.document_history.push(path); helix_event::dispatch(DocumentDidOpen { editor: self, @@ -1872,6 +1871,9 @@ impl Editor { } let doc = self.documents.remove(&doc_id).unwrap(); + if let Some(path) = doc.path() { + self.closed_document_paths.push(path.clone()); + } // If the document we removed was visible in all views, we will have no more views. We don't // want to close the editor just for a simple buffer close, so we need to create a new view From 7bc6604038b8f774aa340106948456f5a3e6d9e1 Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 18:42:08 -0600 Subject: [PATCH 5/7] focus on re-opened buffer --- helix-term/src/commands/typed.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index d0306265f..026f525a0 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -332,8 +332,7 @@ fn buffer_reopen( if let Some(last_closed_doc_path) = cx.editor.closed_document_paths.pop() { - let id = cx.editor.open(&last_closed_doc_path, Action::Load)?; - cx.editor.switch(id, Action::Load); + cx.editor.open(&last_closed_doc_path, Action::Replace)?; } Ok(()) } From 865597b74fafba987df0bbeb851ce1699c2303df Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 19:06:55 -0600 Subject: [PATCH 6/7] change command aliases to be more in line with the other buffer ones --- helix-term/src/commands/typed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 026f525a0..0ac55ce72 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2721,7 +2721,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ }, TypableCommand { name: "buffer-reopen", - aliases: &["bro"], + aliases: &["br", "breopen"], doc: "Re-open the most previously closed buffer.", fun: buffer_reopen, completer: CommandCompleter::none(), From 749c16b9e9f62e30e3ad7fc6147c826f81db1ea8 Mon Sep 17 00:00:00 2001 From: Taylor Plewe Date: Sun, 18 May 2025 19:10:13 -0600 Subject: [PATCH 7/7] fix brace styling --- helix-term/src/commands/typed.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 0ac55ce72..2cf6259e8 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -330,8 +330,7 @@ fn buffer_reopen( return Ok(()); } - if let Some(last_closed_doc_path) = cx.editor.closed_document_paths.pop() - { + if let Some(last_closed_doc_path) = cx.editor.closed_document_paths.pop() { cx.editor.open(&last_closed_doc_path, Action::Replace)?; } Ok(())