diff options
author | Bob | 2022-07-22 01:21:46 +0000 |
---|---|---|
committer | GitHub | 2022-07-22 01:21:46 +0000 |
commit | 2f53644c6d7d70b680a5d734c8732e5f367aacf3 (patch) | |
tree | 919441f181f0da37deb3e78e4ec48f4f997a6519 /helix-term/src | |
parent | e560212ec5336b3257b80bca5f815578d640d9e5 (diff) |
jumplist picker (#3033)
* jumplist picker
* remove jumps slicing
Co-authored-by: Benoît Cortier <bcortier@proton.me>
* remove unnecessary deref format! parameter
Co-authored-by: Benoît Cortier <bcortier@proton.me>
Co-authored-by: Benoît Cortier <bcortier@proton.me>
Diffstat (limited to 'helix-term/src')
-rw-r--r-- | helix-term/src/commands.rs | 82 | ||||
-rw-r--r-- | helix-term/src/keymap/default.rs | 1 |
2 files changed, 83 insertions, 0 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3ee75f6a..12d988d0 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -264,6 +264,7 @@ impl MappableCommand { file_picker_in_current_directory, "Open file picker at current working directory", code_action, "Perform code action", buffer_picker, "Open buffer picker", + jumplist_picker, "Open jumplist picker", symbol_picker, "Open symbol picker", select_references_to_symbol_under_cursor, "Select symbol references", workspace_symbol_picker, "Open workspace symbol picker", @@ -2270,6 +2271,87 @@ fn buffer_picker(cx: &mut Context) { cx.push_layer(Box::new(overlayed(picker))); } +fn jumplist_picker(cx: &mut Context) { + struct JumpMeta { + id: DocumentId, + path: Option<PathBuf>, + selection: Selection, + text: String, + is_current: bool, + } + + impl ui::menu::Item for JumpMeta { + type Data = (); + + fn label(&self, _data: &Self::Data) -> Spans { + let path = self + .path + .as_deref() + .map(helix_core::path::get_relative_path); + let path = match path.as_deref().and_then(Path::to_str) { + Some(path) => path, + None => SCRATCH_BUFFER_NAME, + }; + + let mut flags = Vec::new(); + if self.is_current { + flags.push("*"); + } + + let flag = if flags.is_empty() { + "".into() + } else { + format!(" ({})", flags.join("")) + }; + format!("{} {}{} {}", self.id, path, flag, self.text).into() + } + } + + let new_meta = |view: &View, doc_id: DocumentId, selection: Selection| { + let doc = &cx.editor.documents.get(&doc_id); + let text = doc.map_or("".into(), |d| { + selection + .fragments(d.text().slice(..)) + .map(Cow::into_owned) + .collect::<Vec<_>>() + .join(" ") + }); + + JumpMeta { + id: doc_id, + path: doc.and_then(|d| d.path().cloned()), + selection, + text, + is_current: view.doc == doc_id, + } + }; + + let picker = FilePicker::new( + cx.editor + .tree + .views() + .flat_map(|(view, _)| { + view.jumps + .get() + .iter() + .map(|(doc_id, selection)| new_meta(view, *doc_id, selection.clone())) + }) + .collect(), + (), + |cx, meta, action| { + cx.editor.switch(meta.id, action); + let (view, doc) = current!(cx.editor); + doc.set_selection(view.id, meta.selection.clone()); + }, + |editor, meta| { + let doc = &editor.documents.get(&meta.id)?; + let line = meta.selection.primary().cursor_line(doc.text().slice(..)); + Some((meta.path.clone()?, Some((line, line)))) + }, + ); + cx.push_layer(Box::new(overlayed(picker))); +} + impl ui::menu::Item for MappableCommand { type Data = ReverseKeymap; diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index b8c1a400..f6fb6140 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -205,6 +205,7 @@ pub fn default() -> HashMap<Mode, Keymap> { "f" => file_picker, "F" => file_picker_in_current_directory, "b" => buffer_picker, + "j" => jumplist_picker, "s" => symbol_picker, "S" => workspace_symbol_picker, "g" => diagnostics_picker, |