Unnamed repository; edit this file 'description' to name the repository.
commands: Add line column to jumplist_picker (#15499)
* commands: Add line column to jumplist_picker
* commands: Merge line column and setup styles
This mirrors global_search code style.
* Clean up jumplist_picker picker creation
The old version unnecessarily guarded on a document not existing, but
every view always has a document. The option handling within the
new_meta block could be eliminated.
---------
Co-authored-by: Michael Davis <[email protected]>
| -rw-r--r-- | helix-term/src/commands.rs | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 20f6dd3f..43b1f789 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3370,10 +3370,11 @@ fn buffer_picker(cx: &mut Context) { } fn jumplist_picker(cx: &mut Context) { - struct JumpMeta { + struct JumpMeta<'a> { id: DocumentId, - path: Option<PathBuf>, + path: Option<Cow<'a, Path>>, selection: Selection, + line_start: usize, text: String, is_current: bool, } @@ -3386,36 +3387,67 @@ fn jumplist_picker(cx: &mut Context) { } 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(" ") - }); + let doc = doc!(cx.editor, &doc_id); + let text = doc.text().slice(..); + let contents = selection + .fragments(text) + .map(Cow::into_owned) + .collect::<Vec<_>>() + .join(" "); + let line_start = selection.primary().cursor_line(text); JumpMeta { id: doc_id, - path: doc.and_then(|doc| doc.path().map(ToOwned::to_owned)), + path: doc + .path() + .map(ToOwned::to_owned) + .map(helix_stdx::path::get_relative_path), selection, - text, + line_start, + text: contents, is_current: view.doc == doc_id, } }; + struct JumpListConfig { + directory_style: Style, + number_style: Style, + colon_style: Style, + } + + let config = JumpListConfig { + directory_style: cx.editor.theme.get("ui.text.directory"), + number_style: cx.editor.theme.get("constant.numeric.integer"), + colon_style: cx.editor.theme.get("punctuation"), + }; + let columns = [ ui::PickerColumn::new("id", |item: &JumpMeta, _| item.id.to_string().into()), - ui::PickerColumn::new("path", |item: &JumpMeta, _| { - let path = item + ui::PickerColumn::new("path", |item: &JumpMeta, config: &JumpListConfig| { + let mut spans = Vec::new(); + if let Some(ref path) = item.path { + let directories = path + .parent() + .filter(|p| !p.as_os_str().is_empty()) + .map(|p| format!("{}{}", p.display(), std::path::MAIN_SEPARATOR)) + .unwrap_or_default(); + spans.push(Span::styled(directories, config.directory_style)); + } + let filename = item .path - .as_deref() - .map(helix_stdx::path::get_relative_path); - path.as_deref() - .and_then(Path::to_str) - .unwrap_or(SCRATCH_BUFFER_NAME) - .to_string() - .into() + .as_ref() + .map_or(SCRATCH_BUFFER_NAME.into(), |path| { + path.file_name() + .expect("all document names are normalized (can't end in `..`)") + .to_string_lossy() + }); + spans.extend([ + Span::raw(filename), + Span::styled(":", config.colon_style), + Span::styled((item.line_start + 1).to_string(), config.number_style), + ]); + + Cell::from(Spans::from(spans)) }), ui::PickerColumn::new("flags", |item: &JumpMeta, _| { let mut flags = Vec::new(); @@ -3441,7 +3473,7 @@ fn jumplist_picker(cx: &mut Context) { .rev() .map(|(doc_id, selection)| new_meta(view, *doc_id, selection.clone())) }), - (), + config, |cx, meta, action| { cx.editor.switch(meta.id, action); let config = cx.editor.config(); |