WIP param completions

This commit is contained in:
Jonathan Turner 2019-12-08 18:58:53 +13:00
parent 7a47905f11
commit b6ba7f97fd
4 changed files with 83 additions and 25 deletions

View File

@ -182,10 +182,10 @@ pub trait SignatureRegistry {
#[derive(Getters, new)] #[derive(Getters, new)]
pub struct ExpandContext<'context> { pub struct ExpandContext<'context> {
#[get = "pub(crate)"] #[get = "pub(crate)"]
registry: Box<dyn SignatureRegistry>, pub registry: Box<dyn SignatureRegistry>,
#[get = "pub(crate)"] #[get = "pub(crate)"]
source: &'context Text, pub source: &'context Text,
homedir: Option<PathBuf>, pub homedir: Option<PathBuf>,
} }
impl<'context> ExpandContext<'context> { impl<'context> ExpandContext<'context> {

View File

@ -6,7 +6,9 @@ pub mod parse_command;
pub use crate::commands::classified::{ClassifiedCommand, ClassifiedPipeline, InternalCommand}; pub use crate::commands::classified::{ClassifiedCommand, ClassifiedPipeline, InternalCommand};
pub use crate::commands::ExternalCommand; pub use crate::commands::ExternalCommand;
pub use crate::hir::syntax_shape::flat_shape::FlatShape; pub use crate::hir::syntax_shape::flat_shape::FlatShape;
pub use crate::hir::syntax_shape::{expand_syntax, ExpandSyntax, PipelineShape, SignatureRegistry}; pub use crate::hir::syntax_shape::{
expand_syntax, ExpandContext, ExpandSyntax, PipelineShape, SignatureRegistry,
};
pub use crate::hir::tokens_iterator::TokensIterator; pub use crate::hir::tokens_iterator::TokensIterator;
pub use crate::parse::files::Files; pub use crate::parse::files::Files;
pub use crate::parse::flag::Flag; pub use crate::parse::flag::Flag;

View File

@ -587,7 +587,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
} }
} }
fn classify_pipeline( pub fn classify_pipeline(
pipeline: &TokenNode, pipeline: &TokenNode,
context: &Context, context: &Context,
source: &Text, source: &Text,

View File

@ -16,9 +16,73 @@ impl NuCompleter {
pos: usize, pos: usize,
context: &rustyline::Context, context: &rustyline::Context,
) -> rustyline::Result<(usize, Vec<rustyline::completion::Pair>)> { ) -> rustyline::Result<(usize, Vec<rustyline::completion::Pair>)> {
use nu_source::{HasSpan, Text};
let commands: Vec<String> = self.commands.names(); let commands: Vec<String> = self.commands.names();
let mut completions = self.file_completer.complete(line, pos, context)?.1; let line_chars: Vec<_> = line[..pos].chars().collect();
let mut replace_pos = line_chars.len();
while replace_pos > 0 {
if line_chars[replace_pos - 1] == ' ' {
break;
}
replace_pos -= 1;
}
// See if we're a flag
let mut completions = vec![];
if pos > 0 && line_chars[pos - 1] == '-' {
let mut line_copy = line.to_string();
let replace_string = (replace_pos..pos).map(|_| " ").collect::<String>();
line_copy.replace_range(replace_pos..pos, &replace_string);
match nu_parser::parse(&line_copy) {
Ok(val) => {
let source = Text::from(line);
let pipeline_list = vec![val.clone()];
let mut iterator =
nu_parser::TokensIterator::all(&pipeline_list, source.clone(), val.span());
let expand_context = nu_parser::ExpandContext {
homedir: None,
registry: Box::new(self.commands.clone()),
source: &source,
};
let result = nu_parser::expand_syntax(
&nu_parser::PipelineShape,
&mut iterator,
&expand_context,
);
if let Ok(result) = result {
for command in result.commands.list {
match command {
nu_parser::ClassifiedCommand::Internal(
nu_parser::InternalCommand { args, .. },
) => {
if replace_pos >= args.span.start()
&& replace_pos <= args.span.end()
{
if let Some(named) = args.named {
for (name, _) in named.iter() {
completions.push(rustyline::completion::Pair {
display: format!("--{}", name),
replacement: format!("--{}", name),
});
}
}
}
}
_ => {}
}
}
}
}
_ => {}
}
} else {
completions = self.file_completer.complete(line, pos, context)?.1;
for completion in &mut completions { for completion in &mut completions {
if completion.replacement.contains("\\ ") { if completion.replacement.contains("\\ ") {
@ -37,15 +101,7 @@ impl NuCompleter {
} }
} }
} }
};
let line_chars: Vec<_> = line[..pos].chars().collect();
let mut replace_pos = line_chars.len();
while replace_pos > 0 {
if line_chars[replace_pos - 1] == ' ' {
break;
}
replace_pos -= 1;
}
for command in commands.iter() { for command in commands.iter() {
let mut pos = replace_pos; let mut pos = replace_pos;