Skip to content

Commit

Permalink
jumplist picker (#3033)
Browse files Browse the repository at this point in the history
* jumplist picker

* remove jumps slicing

Co-authored-by: Benoît Cortier <[email protected]>

* remove unnecessary deref format! parameter

Co-authored-by: Benoît Cortier <[email protected]>

Co-authored-by: Benoît Cortier <[email protected]>
  • Loading branch information
QiBaobin and CBenoit authored Jul 22, 2022
1 parent e560212 commit 2f53644
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions book/src/keymap.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ This layer is a kludge of mappings, mostly pickers.
| ----- | ----------- | ------- |
| `f` | Open file picker | `file_picker` |
| `b` | Open buffer picker | `buffer_picker` |
| `j` | Open jumplist picker | `jumplist_picker` |
| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
Expand Down
82 changes: 82 additions & 0 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions helix-term/src/keymap/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions helix-view/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ impl JumpList {
pub fn remove(&mut self, doc_id: &DocumentId) {
self.jumps.retain(|(other_id, _)| other_id != doc_id);
}

pub fn get(&self) -> &[Jump] {
&self.jumps
}
}

pub struct View {
Expand Down

0 comments on commit 2f53644

Please sign in to comment.