on master help sign in
jumplist picker (#3033)
2f53644Bob
book/src/keymap.md+1
@@ -238,6 +238,7 @@ This layer is a kludge of mappings, mostly pickers.
238| ----- | ----------- | ------- |
238| ----- | ----------- | ------- |
239| `f` | Open file picker | `file_picker` |
239| `f` | Open file picker | `file_picker` |
240| `b` | Open buffer picker | `buffer_picker` |
240| `b` | Open buffer picker | `buffer_picker` |
241+| `j` | Open jumplist picker | `jumplist_picker` |
241| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
242| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
242| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
243| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
243| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
244| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
helix-term/src/commands.rs+82
@@ -264,6 +264,7 @@ impl MappableCommand {
264 file_picker_in_current_directory, "Open file picker at current working directory",
264 file_picker_in_current_directory, "Open file picker at current working directory",
265 code_action, "Perform code action",
265 code_action, "Perform code action",
266 buffer_picker, "Open buffer picker",
266 buffer_picker, "Open buffer picker",
267+ jumplist_picker, "Open jumplist picker",
267 symbol_picker, "Open symbol picker",
268 symbol_picker, "Open symbol picker",
268 select_references_to_symbol_under_cursor, "Select symbol references",
269 select_references_to_symbol_under_cursor, "Select symbol references",
269 workspace_symbol_picker, "Open workspace symbol picker",
270 workspace_symbol_picker, "Open workspace symbol picker",
@@ -2270,6 +2271,87 @@ fn buffer_picker(cx: &mut Context) {
2270 cx.push_layer(Box::new(overlayed(picker)));
2271 cx.push_layer(Box::new(overlayed(picker)));
2271}
2272}
2272
2273
2274+fn jumplist_picker(cx: &mut Context) {
2275+ struct JumpMeta {
2276+ id: DocumentId,
2277+ path: Option<PathBuf>,
2278+ selection: Selection,
2279+ text: String,
2280+ is_current: bool,
2281+ }
2282+
2283+ impl ui::menu::Item for JumpMeta {
2284+ type Data = ();
2285+
2286+ fn label(&self, _data: &Self::Data) -> Spans {
2287+ let path = self
2288+ .path
2289+ .as_deref()
2290+ .map(helix_core::path::get_relative_path);
2291+ let path = match path.as_deref().and_then(Path::to_str) {
2292+ Some(path) => path,
2293+ None => SCRATCH_BUFFER_NAME,
2294+ };
2295+
2296+ let mut flags = Vec::new();
2297+ if self.is_current {
2298+ flags.push("*");
2299+ }
2300+
2301+ let flag = if flags.is_empty() {
2302+ "".into()
2303+ } else {
2304+ format!(" ({})", flags.join(""))
2305+ };
2306+ format!("{} {}{} {}", self.id, path, flag, self.text).into()
2307+ }
2308+ }
2309+
2310+ let new_meta = |view: &View, doc_id: DocumentId, selection: Selection| {
2311+ let doc = &cx.editor.documents.get(&doc_id);
2312+ let text = doc.map_or("".into(), |d| {
2313+ selection
2314+ .fragments(d.text().slice(..))
2315+ .map(Cow::into_owned)
2316+ .collect::<Vec<_>>()
2317+ .join(" ")
2318+ });
2319+
2320+ JumpMeta {
2321+ id: doc_id,
2322+ path: doc.and_then(|d| d.path().cloned()),
2323+ selection,
2324+ text,
2325+ is_current: view.doc == doc_id,
2326+ }
2327+ };
2328+
2329+ let picker = FilePicker::new(
2330+ cx.editor
2331+ .tree
2332+ .views()
2333+ .flat_map(|(view, _)| {
2334+ view.jumps
2335+ .get()
2336+ .iter()
2337+ .map(|(doc_id, selection)| new_meta(view, *doc_id, selection.clone()))
2338+ })
2339+ .collect(),
2340+ (),
2341+ |cx, meta, action| {
2342+ cx.editor.switch(meta.id, action);
2343+ let (view, doc) = current!(cx.editor);
2344+ doc.set_selection(view.id, meta.selection.clone());
2345+ },
2346+ |editor, meta| {
2347+ let doc = &editor.documents.get(&meta.id)?;
2348+ let line = meta.selection.primary().cursor_line(doc.text().slice(..));
2349+ Some((meta.path.clone()?, Some((line, line))))
2350+ },
2351+ );
2352+ cx.push_layer(Box::new(overlayed(picker)));
2353+}
2354+
2273impl ui::menu::Item for MappableCommand {
2355impl ui::menu::Item for MappableCommand {
2274 type Data = ReverseKeymap;
2356 type Data = ReverseKeymap;
2275
2357
helix-term/src/keymap/default.rs+1
@@ -205,6 +205,7 @@ pub fn default() -> HashMap<Mode, Keymap> {
205 "f" => file_picker,
205 "f" => file_picker,
206 "F" => file_picker_in_current_directory,
206 "F" => file_picker_in_current_directory,
207 "b" => buffer_picker,
207 "b" => buffer_picker,
208+ "j" => jumplist_picker,
208 "s" => symbol_picker,
209 "s" => symbol_picker,
209 "S" => workspace_symbol_picker,
210 "S" => workspace_symbol_picker,
210 "g" => diagnostics_picker,
211 "g" => diagnostics_picker,
helix-view/src/view.rs+4
@@ -58,6 +58,10 @@ impl JumpList {
58 pub fn remove(&mut self, doc_id: &DocumentId) {
58 pub fn remove(&mut self, doc_id: &DocumentId) {
59 self.jumps.retain(|(other_id, _)| other_id != doc_id);
59 self.jumps.retain(|(other_id, _)| other_id != doc_id);
60 }
60 }
61+
62+ pub fn get(&self) -> &[Jump] {
63+ &self.jumps
64+ }
61}
65}
62
66
63pub struct View {
67pub struct View {