fix(completion): inline defined custom completion (#15318)

Fixes #6001 

# Description

<img width="485" alt="image"
src="https://github.com/user-attachments/assets/5aad23ee-07ec-4f1b-8410-a484c2210cd3"
/>

# User-Facing Changes

# Tests + Formatting

+1

# After Submitting
This commit is contained in:
zc he 2025-03-20 23:44:41 +08:00 committed by GitHub
parent 8b80ceac32
commit 2b4914608e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 23 deletions

View File

@ -5,7 +5,7 @@ use nu_engine::eval_call;
use nu_protocol::{ use nu_protocol::{
ast::{Argument, Call, Expr, Expression}, ast::{Argument, Call, Expr, Expression},
debugger::WithoutDebug, debugger::WithoutDebug,
engine::{Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
DeclId, PipelineData, Span, Type, Value, DeclId, PipelineData, Span, Type, Value,
}; };
use std::collections::HashMap; use std::collections::HashMap;
@ -42,28 +42,37 @@ impl<T: Completer> Completer for CustomCompletion<T> {
) -> Vec<SemanticSuggestion> { ) -> Vec<SemanticSuggestion> {
// Call custom declaration // Call custom declaration
let mut stack_mut = stack.clone(); let mut stack_mut = stack.clone();
let result = eval_call::<WithoutDebug>( let mut eval = |engine_state: &EngineState| {
working_set.permanent_state, eval_call::<WithoutDebug>(
&mut stack_mut, engine_state,
&Call { &mut stack_mut,
decl_id: self.decl_id, &Call {
head: span, decl_id: self.decl_id,
arguments: vec![ head: span,
Argument::Positional(Expression::new_unknown( arguments: vec![
Expr::String(self.line.clone()), Argument::Positional(Expression::new_unknown(
Span::unknown(), Expr::String(self.line.clone()),
Type::String, Span::unknown(),
)), Type::String,
Argument::Positional(Expression::new_unknown( )),
Expr::Int(self.line_pos as i64), Argument::Positional(Expression::new_unknown(
Span::unknown(), Expr::Int(self.line_pos as i64),
Type::Int, Span::unknown(),
)), Type::Int,
], )),
parser_info: HashMap::new(), ],
}, parser_info: HashMap::new(),
PipelineData::empty(), },
); PipelineData::empty(),
)
};
let result = if self.decl_id.get() < working_set.permanent_state.num_decls() {
eval(working_set.permanent_state)
} else {
let mut engine_state = working_set.permanent_state.clone();
let _ = engine_state.merge_delta(working_set.delta.clone());
eval(&engine_state)
};
let mut completion_options = orig_options.clone(); let mut completion_options = orig_options.clone();
let mut should_sort = true; let mut should_sort = true;

View File

@ -350,6 +350,21 @@ fn custom_arguments_vs_subcommands() {
match_suggestions(&expected, &suggestions); match_suggestions(&expected, &suggestions);
} }
#[test]
fn custom_completions_defined_inline() {
let (_, _, engine, stack) = new_engine();
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
let completion_str = "def animals [] { [cat dog] }
export def say [
animal: string@animals
] { }; say ";
let suggestions = completer.complete(completion_str, completion_str.len());
// including only subcommand completions
let expected: Vec<_> = vec!["cat", "dog"];
match_suggestions(&expected, &suggestions);
}
/// External command only if starts with `^` /// External command only if starts with `^`
#[test] #[test]
fn external_commands_only() { fn external_commands_only() {