Improve external command completions with spaces (#4420)

This commit is contained in:
JT 2022-02-11 07:05:48 -05:00 committed by GitHub
parent ba4d8ae8c3
commit e16d6ae00c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,5 +1,5 @@
use nu_engine::eval_block; use nu_engine::eval_block;
use nu_parser::{flatten_expression, parse}; use nu_parser::{flatten_expression, parse, trim_quotes};
use nu_protocol::{ use nu_protocol::{
ast::{Expr, Statement}, ast::{Expr, Statement},
engine::{EngineState, Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
@ -165,7 +165,7 @@ impl NuCompleter {
if let Statement::Pipeline(pipeline) = stmt { if let Statement::Pipeline(pipeline) = stmt {
for expr in pipeline.expressions { for expr in pipeline.expressions {
let flattened = flatten_expression(&working_set, &expr); let flattened = flatten_expression(&working_set, &expr);
for flat in flattened { for (flat_idx, flat) in flattened.into_iter().enumerate() {
if pos >= flat.0.start && pos <= flat.0.end { if pos >= flat.0.start && pos <= flat.0.end {
let prefix = working_set.get_span_contents(flat.0); let prefix = working_set.get_span_contents(flat.0);
@ -245,9 +245,7 @@ impl NuCompleter {
return v; return v;
} }
nu_parser::FlatShape::External _ => {
| nu_parser::FlatShape::InternalCall
| nu_parser::FlatShape::String => {
let subcommands = self.complete_commands( let subcommands = self.complete_commands(
&working_set, &working_set,
Span { Span {
@ -267,52 +265,48 @@ impl NuCompleter {
"".to_string() "".to_string()
}; };
let preceding_byte = if flat.0.start > offset {
working_set
.get_span_contents(Span {
start: flat.0.start - 1,
end: flat.0.start,
})
.to_vec()
} else {
vec![]
};
let prefix = working_set.get_span_contents(flat.0); let prefix = working_set.get_span_contents(flat.0);
let prefix = String::from_utf8_lossy(prefix).to_string(); let prefix = String::from_utf8_lossy(prefix).to_string();
return file_path_completion(flat.0, &prefix, &cwd) return file_path_completion(flat.0, &prefix, &cwd)
.into_iter() .into_iter()
.map(move |x| { .map(move |x| {
( if flat_idx == 0 {
reedline::Span { // We're in the command position
start: x.0.start - offset, if x.1.starts_with('"')
end: x.0.end - offset, && !matches!(preceding_byte.get(0), Some(b'^'))
}, {
x.1, let trimmed = trim_quotes(x.1.as_bytes());
) let trimmed = String::from_utf8_lossy(trimmed)
.to_string();
let expanded =
nu_path::canonicalize_with(trimmed, &cwd);
if let Ok(expanded) = expanded {
if is_executable::is_executable(expanded) {
(x.0, format!("^{}", x.1))
} else {
(x.0, x.1)
}
} else {
(x.0, x.1)
}
} else {
(x.0, x.1)
}
} else {
(x.0, x.1)
}
}) })
.chain(subcommands.into_iter())
.collect();
}
nu_parser::FlatShape::Filepath
| nu_parser::FlatShape::GlobPattern
| nu_parser::FlatShape::ExternalArg => {
// Check for subcommands
let subcommands = self.complete_commands(
&working_set,
Span {
start: expr.span.start,
end: pos,
},
offset,
);
// Check for args
let prefix = working_set.get_span_contents(flat.0);
let prefix = String::from_utf8_lossy(prefix).to_string();
let cwd = if let Some(d) = self.engine_state.env_vars.get("PWD")
{
match d.as_string() {
Ok(s) => s,
Err(_) => "".to_string(),
}
} else {
"".to_string()
};
let results = file_path_completion(flat.0, &prefix, &cwd);
return results
.into_iter()
.map(move |x| { .map(move |x| {
( (
reedline::Span { reedline::Span {
@ -325,16 +319,6 @@ impl NuCompleter {
.chain(subcommands.into_iter()) .chain(subcommands.into_iter())
.collect(); .collect();
} }
_ => {
return self.complete_commands(
&working_set,
Span {
start: expr.span.start,
end: pos,
},
offset,
)
}
} }
} }