mirror of https://github.com/helix-editor/helix
Merge 46f6a62aea
into 205e7ece70
commit
4a34d06853
|
@ -2663,7 +2663,8 @@ fn global_search(cx: &mut Context) {
|
||||||
Some((path.as_path().into(), Some((*line_num, *line_num))))
|
Some((path.as_path().into(), Some((*line_num, *line_num))))
|
||||||
})
|
})
|
||||||
.with_history_register(Some(reg))
|
.with_history_register(Some(reg))
|
||||||
.with_dynamic_query(get_files, Some(275));
|
.with_dynamic_query(get_files, Some(275))
|
||||||
|
.with_title("Search".into());
|
||||||
|
|
||||||
cx.push_layer(Box::new(overlaid(picker)));
|
cx.push_layer(Box::new(overlaid(picker)));
|
||||||
}
|
}
|
||||||
|
@ -3199,7 +3200,8 @@ fn buffer_picker(cx: &mut Context) {
|
||||||
(cursor_line, cursor_line)
|
(cursor_line, cursor_line)
|
||||||
});
|
});
|
||||||
Some((meta.id.into(), lines))
|
Some((meta.id.into(), lines))
|
||||||
});
|
})
|
||||||
|
.with_title("Buffers".into());
|
||||||
cx.push_layer(Box::new(overlaid(picker)));
|
cx.push_layer(Box::new(overlaid(picker)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3290,7 +3292,8 @@ fn jumplist_picker(cx: &mut Context) {
|
||||||
let doc = &editor.documents.get(&meta.id)?;
|
let doc = &editor.documents.get(&meta.id)?;
|
||||||
let line = meta.selection.primary().cursor_line(doc.text().slice(..));
|
let line = meta.selection.primary().cursor_line(doc.text().slice(..));
|
||||||
Some((meta.id.into(), Some((line, line))))
|
Some((meta.id.into(), Some((line, line))))
|
||||||
});
|
})
|
||||||
|
.with_title("Jump List".into());
|
||||||
cx.push_layer(Box::new(overlaid(picker)));
|
cx.push_layer(Box::new(overlaid(picker)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3372,7 +3375,8 @@ fn changed_file_picker(cx: &mut Context) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_preview(|_editor, meta| Some((meta.path().into(), None)));
|
.with_preview(|_editor, meta| Some((meta.path().into(), None)))
|
||||||
|
.with_title("Changed Files".into());
|
||||||
let injector = picker.injector();
|
let injector = picker.injector();
|
||||||
|
|
||||||
cx.editor
|
cx.editor
|
||||||
|
@ -3464,7 +3468,8 @@ pub fn command_palette(cx: &mut Context) {
|
||||||
doc.append_changes_to_history(view);
|
doc.append_changes_to_history(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.with_title("Command Palette".into());
|
||||||
compositor.push(Box::new(overlaid(picker)));
|
compositor.push(Box::new(overlaid(picker)));
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
|
@ -296,6 +296,7 @@ fn diag_picker(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_preview(move |_editor, diag| location_to_file_location(&diag.location))
|
.with_preview(move |_editor, diag| location_to_file_location(&diag.location))
|
||||||
|
.with_title("Diagnostics".into())
|
||||||
.truncate_start(false)
|
.truncate_start(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +425,7 @@ pub fn symbol_picker(cx: &mut Context) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_preview(move |_editor, item| location_to_file_location(&item.location))
|
.with_preview(move |_editor, item| location_to_file_location(&item.location))
|
||||||
|
.with_title("Document Symbols".into())
|
||||||
.truncate_start(false);
|
.truncate_start(false);
|
||||||
|
|
||||||
compositor.push(Box::new(overlaid(picker)))
|
compositor.push(Box::new(overlaid(picker)))
|
||||||
|
@ -551,6 +553,7 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
|
||||||
)
|
)
|
||||||
.with_preview(|_editor, item| location_to_file_location(&item.location))
|
.with_preview(|_editor, item| location_to_file_location(&item.location))
|
||||||
.with_dynamic_query(get_symbols, None)
|
.with_dynamic_query(get_symbols, None)
|
||||||
|
.with_title("Workspace Symbols".into())
|
||||||
.truncate_start(false);
|
.truncate_start(false);
|
||||||
|
|
||||||
cx.push_layer(Box::new(overlaid(picker)));
|
cx.push_layer(Box::new(overlaid(picker)));
|
||||||
|
@ -841,7 +844,12 @@ impl Display for ApplyEditErrorKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Precondition: `locations` should be non-empty.
|
/// Precondition: `locations` should be non-empty.
|
||||||
fn goto_impl(editor: &mut Editor, compositor: &mut Compositor, locations: Vec<Location>) {
|
fn goto_impl(
|
||||||
|
title: &'static str,
|
||||||
|
editor: &mut Editor,
|
||||||
|
compositor: &mut Compositor,
|
||||||
|
locations: Vec<Location>,
|
||||||
|
) {
|
||||||
let cwdir = helix_stdx::env::current_working_dir();
|
let cwdir = helix_stdx::env::current_working_dir();
|
||||||
|
|
||||||
match locations.as_slice() {
|
match locations.as_slice() {
|
||||||
|
@ -866,7 +874,8 @@ fn goto_impl(editor: &mut Editor, compositor: &mut Compositor, locations: Vec<Lo
|
||||||
let picker = Picker::new(columns, 0, locations, cwdir, |cx, location, action| {
|
let picker = Picker::new(columns, 0, locations, cwdir, |cx, location, action| {
|
||||||
jump_to_location(cx.editor, location, action)
|
jump_to_location(cx.editor, location, action)
|
||||||
})
|
})
|
||||||
.with_preview(|_editor, location| location_to_file_location(location));
|
.with_preview(|_editor, location| location_to_file_location(location))
|
||||||
|
.with_title(title.into());
|
||||||
compositor.push(Box::new(overlaid(picker)));
|
compositor.push(Box::new(overlaid(picker)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -925,7 +934,7 @@ where
|
||||||
if locations.is_empty() {
|
if locations.is_empty() {
|
||||||
editor.set_error("No definition found.");
|
editor.set_error("No definition found.");
|
||||||
} else {
|
} else {
|
||||||
goto_impl(editor, compositor, locations);
|
goto_impl("Goto Implementation", editor, compositor, locations);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Callback::EditorCompositor(Box::new(call)))
|
Ok(Callback::EditorCompositor(Box::new(call)))
|
||||||
|
@ -1002,7 +1011,7 @@ pub fn goto_reference(cx: &mut Context) {
|
||||||
if locations.is_empty() {
|
if locations.is_empty() {
|
||||||
editor.set_error("No references found.");
|
editor.set_error("No references found.");
|
||||||
} else {
|
} else {
|
||||||
goto_impl(editor, compositor, locations);
|
goto_impl("Goto Reference", editor, compositor, locations);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Callback::EditorCompositor(Box::new(call)))
|
Ok(Callback::EditorCompositor(Box::new(call)))
|
||||||
|
|
|
@ -1460,7 +1460,8 @@ fn lsp_workspace_command(
|
||||||
move |cx, (ls_id, command), _action| {
|
move |cx, (ls_id, command), _action| {
|
||||||
cx.editor.execute_lsp_command(command.clone(), *ls_id);
|
cx.editor.execute_lsp_command(command.clone(), *ls_id);
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
.with_title("LSP Commands".into());
|
||||||
compositor.push(Box::new(overlaid(picker)))
|
compositor.push(Box::new(overlaid(picker)))
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
|
@ -274,7 +274,8 @@ pub fn file_picker(editor: &Editor, root: PathBuf) -> FilePicker {
|
||||||
cx.editor.set_error(err);
|
cx.editor.set_error(err);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with_preview(|_editor, path| Some((path.as_path().into(), None)));
|
.with_preview(|_editor, path| Some((path.as_path().into(), None)))
|
||||||
|
.with_title("Files".into());
|
||||||
let injector = picker.injector();
|
let injector = picker.injector();
|
||||||
let timeout = std::time::Instant::now() + std::time::Duration::from_millis(30);
|
let timeout = std::time::Instant::now() + std::time::Duration::from_millis(30);
|
||||||
|
|
||||||
|
@ -321,7 +322,7 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
|
||||||
columns,
|
columns,
|
||||||
0,
|
0,
|
||||||
directory_content,
|
directory_content,
|
||||||
(root, directory_style),
|
(root.clone(), directory_style),
|
||||||
move |cx, (path, is_dir): &(PathBuf, bool), action| {
|
move |cx, (path, is_dir): &(PathBuf, bool), action| {
|
||||||
if *is_dir {
|
if *is_dir {
|
||||||
let new_root = helix_stdx::path::normalize(path);
|
let new_root = helix_stdx::path::normalize(path);
|
||||||
|
@ -345,7 +346,8 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_preview(|_editor, (path, _is_dir)| Some((path.as_path().into(), None)));
|
.with_preview(|_editor, (path, _is_dir)| Some((path.as_path().into(), None)))
|
||||||
|
.with_title("File Explorer".into());
|
||||||
|
|
||||||
Ok(picker)
|
Ok(picker)
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,6 +268,7 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
|
||||||
/// An event handler for syntax highlighting the currently previewed file.
|
/// An event handler for syntax highlighting the currently previewed file.
|
||||||
preview_highlight_handler: Sender<Arc<Path>>,
|
preview_highlight_handler: Sender<Arc<Path>>,
|
||||||
dynamic_query_handler: Option<Sender<DynamicQueryChange>>,
|
dynamic_query_handler: Option<Sender<DynamicQueryChange>>,
|
||||||
|
title: Option<Spans<'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
|
@ -389,6 +390,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
file_fn: None,
|
file_fn: None,
|
||||||
preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(),
|
preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(),
|
||||||
dynamic_query_handler: None,
|
dynamic_query_handler: None,
|
||||||
|
title: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +410,11 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_title(mut self, title: Spans<'static>) -> Self {
|
||||||
|
self.title = Some(title);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_preview(
|
pub fn with_preview(
|
||||||
mut self,
|
mut self,
|
||||||
preview_fn: impl for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>> + 'static,
|
preview_fn: impl for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>> + 'static,
|
||||||
|
@ -680,12 +687,14 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
let background = cx.editor.theme.get("ui.background");
|
let background = cx.editor.theme.get("ui.background");
|
||||||
surface.clear_with(area, background);
|
surface.clear_with(area, background);
|
||||||
|
|
||||||
const BLOCK: Block<'_> = Block::bordered();
|
let block: Block<'_> = self.title.as_ref().map_or(Block::bordered(), |title| {
|
||||||
|
Block::bordered().title(title.clone())
|
||||||
|
});
|
||||||
|
|
||||||
// calculate the inner area inside the box
|
// calculate the inner area inside the box
|
||||||
let inner = BLOCK.inner(area);
|
let inner = block.inner(area);
|
||||||
|
|
||||||
BLOCK.render(area, surface);
|
block.render(area, surface);
|
||||||
|
|
||||||
// -- Render the input bar:
|
// -- Render the input bar:
|
||||||
|
|
||||||
|
@ -991,7 +1000,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
|
|
||||||
impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I, D> {
|
impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I, D> {
|
||||||
fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||||
// +---------+ +---------+
|
// +--title--+ +---------+
|
||||||
// |prompt | |preview |
|
// |prompt | |preview |
|
||||||
// +---------+ | |
|
// +---------+ | |
|
||||||
// |picker | | |
|
// |picker | | |
|
||||||
|
|
Loading…
Reference in New Issue