mirror of https://github.com/helix-editor/helix
Improve auto completion for shell commands
This makes the very first argument of shell commands (like run-shell-command or pipe) auto complete programs instead of files.pull/12883/head
parent
0ee5850016
commit
28349fb8cf
|
@ -6315,7 +6315,7 @@ fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBeha
|
|||
cx,
|
||||
prompt,
|
||||
Some('|'),
|
||||
ui::completers::filename,
|
||||
ui::completers::shell,
|
||||
move |cx, input: &str, event: PromptEvent| {
|
||||
if event != PromptEvent::Validate {
|
||||
return;
|
||||
|
|
|
@ -68,6 +68,13 @@ impl CommandCompleter {
|
|||
var_args: completer,
|
||||
}
|
||||
}
|
||||
|
||||
const fn hybrid(completers: &'static [Completer], fallback: Completer) -> Self {
|
||||
Self {
|
||||
positional_args: completers,
|
||||
var_args: fallback,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn quit(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {
|
||||
|
|
|
@ -372,6 +372,7 @@ pub mod completers {
|
|||
use super::Utf8PathBuf;
|
||||
use crate::ui::prompt::Completion;
|
||||
use helix_core::fuzzy::fuzzy_match;
|
||||
use helix_core::shellwords::Shellwords;
|
||||
use helix_core::syntax::LanguageServerFeature;
|
||||
use helix_view::document::SCRATCH_BUFFER_NAME;
|
||||
use helix_view::theme;
|
||||
|
@ -677,4 +678,48 @@ pub mod completers {
|
|||
.map(|(name, _)| ((0..), name.into()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn program(_editor: &Editor, input: &str) -> Vec<Completion> {
|
||||
static PROGRAMS_IN_PATH: Lazy<Vec<String>> = Lazy::new(|| {
|
||||
// Go through the entire PATH and read all files into a vec.
|
||||
let mut vec = std::env::var("PATH")
|
||||
.unwrap_or("".to_owned())
|
||||
.split(":")
|
||||
.flat_map(|s| {
|
||||
std::fs::read_dir(s)
|
||||
.map_or_else(|_| vec![], |res| res.into_iter().collect::<Vec<_>>())
|
||||
})
|
||||
.filter_map(|it| it.ok())
|
||||
.map(|f| f.path())
|
||||
.filter(|p| !p.is_dir())
|
||||
.filter_map(|p| p.file_name().and_then(|s| s.to_str().map(|s| s.to_owned())))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Paths can share programs like /bin and /usr/bin sometimes contain the same.
|
||||
vec.dedup();
|
||||
|
||||
vec
|
||||
});
|
||||
|
||||
fuzzy_match(input, PROGRAMS_IN_PATH.iter(), false)
|
||||
.into_iter()
|
||||
.map(|(name, _)| ((0..), name.clone().into()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn shell(editor: &Editor, input: &str) -> Vec<Completion> {
|
||||
let shellwords = Shellwords::from(input);
|
||||
let words = shellwords.words();
|
||||
|
||||
if words.len() > 1 || shellwords.ends_with_whitespace() {
|
||||
let offset = words[0].len() + 1;
|
||||
// Theoretically one could now parse bash completion scripts, but filename should suffice for now.
|
||||
let mut completions = filename(editor, &input[offset..]);
|
||||
for completion in completions.iter_mut() {
|
||||
completion.0.start += offset;
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
program(editor, input)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue