Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-term/src/commands.rs157
1 files changed, 72 insertions, 85 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 43b1f789..98e876ee 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -2563,18 +2563,18 @@ fn make_search_word_bounded(cx: &mut Context) {
fn global_search(cx: &mut Context) {
#[derive(Debug)]
- struct FileResult {
- path: PathBuf,
+ struct FileResult<'a> {
+ path: Cow<'a, Path>,
/// 0 indexed line start
line_start: usize,
/// 0 indexed line end
line_end: usize,
}
- impl FileResult {
+ impl FileResult<'_> {
fn new(path: &Path, line_start: usize, line_end: usize) -> Self {
Self {
- path: path.to_path_buf(),
+ path: helix_stdx::path::get_relative_path(path.to_path_buf()),
line_start,
line_end,
}
@@ -2584,42 +2584,21 @@ fn global_search(cx: &mut Context) {
struct GlobalSearchConfig {
smart_case: bool,
file_picker_config: helix_view::editor::FilePickerConfig,
- directory_style: Style,
- number_style: Style,
- colon_style: Style,
+ style: PathStyleConfig,
}
let config = cx.editor.config();
let config = GlobalSearchConfig {
smart_case: config.search.smart_case,
file_picker_config: config.file_picker.clone(),
- 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"),
+ style: PathStyleConfig::new(&cx.editor.theme),
};
let columns = [
PickerColumn::new("path", |item: &FileResult, config: &GlobalSearchConfig| {
- let path = helix_stdx::path::get_relative_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();
-
- let filename = item
- .path
- .file_name()
- .expect("global search paths are normalized (can't end in `..`)")
- .to_string_lossy();
-
- Cell::from(Spans::from(vec![
- Span::styled(directories, config.directory_style),
- Span::raw(filename),
- Span::styled(":", config.colon_style),
- Span::styled((item.line_start + 1).to_string(), config.number_style),
- ]))
+ config
+ .style
+ .stylize(Some(&item.path), Some(item.line_start))
}),
PickerColumn::hidden("contents"),
];
@@ -2802,7 +2781,7 @@ fn global_search(cx: &mut Context) {
line_start,
line_end,
..
- }| { Some((path.as_path().into(), Some((*line_start, *line_end)))) },
+ }| { Some((path.as_ref().into(), Some((*line_start, *line_end)))) },
)
.with_history_register(Some(reg))
.with_dynamic_query(get_files, Some(275));
@@ -3287,12 +3266,54 @@ fn file_explorer_in_current_directory(cx: &mut Context) {
}
}
+struct PathStyleConfig {
+ directory_style: Style,
+ number_style: Style,
+ colon_style: Style,
+}
+
+impl PathStyleConfig {
+ fn new(theme: &helix_view::Theme) -> Self {
+ Self {
+ directory_style: theme.get("ui.text.directory"),
+ number_style: theme.get("constant.numeric.integer"),
+ colon_style: theme.get("punctuation"),
+ }
+ }
+
+ fn stylize<'a>(&self, path: Option<&'a Path>, line: Option<usize>) -> Cell<'a> {
+ let mut spans = Vec::new();
+ if let Some(path) = 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, self.directory_style));
+ }
+ let filename = path.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.push(Span::raw(filename));
+ if let Some(line) = line {
+ spans.extend([
+ Span::styled(":", self.colon_style),
+ Span::styled((line + 1).to_string(), self.number_style),
+ ]);
+ }
+
+ Cell::from(Spans::from(spans))
+ }
+}
+
fn buffer_picker(cx: &mut Context) {
let current = view!(cx.editor).doc;
- struct BufferMeta {
+ struct BufferMeta<'a> {
id: DocumentId,
- path: Option<PathBuf>,
+ path: Option<Cow<'a, Path>>,
is_modified: bool,
is_current: bool,
focused_at: std::time::Instant,
@@ -3300,7 +3321,10 @@ fn buffer_picker(cx: &mut Context) {
let new_meta = |doc: &Document| BufferMeta {
id: doc.id(),
- path: doc.path().map(ToOwned::to_owned),
+ path: doc
+ .path()
+ .map(ToOwned::to_owned)
+ .map(helix_stdx::path::get_relative_path),
is_modified: doc.is_modified(),
is_current: doc.id() == current,
focused_at: doc.focused_at,
@@ -3328,16 +3352,8 @@ fn buffer_picker(cx: &mut Context) {
}
flags.into()
}),
- PickerColumn::new("path", |meta: &BufferMeta, _| {
- let path = meta
- .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()
+ PickerColumn::new("path", |meta: &BufferMeta, config: &PathStyleConfig| {
+ config.stylize(meta.path.as_deref(), None)
}),
];
@@ -3354,9 +3370,15 @@ fn buffer_picker(cx: &mut Context) {
0
};
- let picker = Picker::new(columns, 2, items, (), |cx, meta, action| {
- cx.editor.switch(meta.id, action);
- })
+ let picker = Picker::new(
+ columns,
+ 2,
+ items,
+ PathStyleConfig::new(&cx.editor.theme),
+ |cx, meta, action| {
+ cx.editor.switch(meta.id, action);
+ },
+ )
.with_initial_cursor(initial_cursor)
.with_preview(|editor, meta| {
let doc = &editor.documents.get(&meta.id)?;
@@ -3409,45 +3431,10 @@ fn jumplist_picker(cx: &mut Context) {
}
};
- 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, 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_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("path", |item: &JumpMeta, config: &PathStyleConfig| {
+ config.stylize(item.path.as_deref(), Some(item.line_start))
}),
ui::PickerColumn::new("flags", |item: &JumpMeta, _| {
let mut flags = Vec::new();
@@ -3473,7 +3460,7 @@ fn jumplist_picker(cx: &mut Context) {
.rev()
.map(|(doc_id, selection)| new_meta(view, *doc_id, selection.clone()))
}),
- config,
+ PathStyleConfig::new(&cx.editor.theme),
|cx, meta, action| {
cx.editor.switch(meta.id, action);
let config = cx.editor.config();