Skip to content

Commit 4e3f29a

Browse files
committed
refactor: get rid of SyntaxShape::CompleterWrapper
1 parent a90c4fb commit 4e3f29a

File tree

5 files changed

+80
-110
lines changed

5 files changed

+80
-110
lines changed

crates/nu-engine/src/documentation.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,6 @@ impl HelpStyle {
648648
}
649649
}
650650

651-
/// Make syntax shape presentable by stripping custom completer info
652-
fn document_shape(shape: &SyntaxShape) -> &SyntaxShape {
653-
match shape {
654-
SyntaxShape::CompleterWrapper(inner_shape, _) => inner_shape,
655-
_ => shape,
656-
}
657-
}
658-
659651
#[derive(PartialEq)]
660652
enum PositionalKind {
661653
Required,
@@ -686,15 +678,14 @@ fn write_positional(
686678
long_desc,
687679
"{help_subcolor_one}\"{}\" + {RESET}<{help_subcolor_two}{}{RESET}>",
688680
String::from_utf8_lossy(kw),
689-
document_shape(shape),
681+
shape,
690682
);
691683
}
692684
_ => {
693685
let _ = write!(
694686
long_desc,
695687
"{help_subcolor_one}{}{RESET} <{help_subcolor_two}{}{RESET}>",
696-
positional.name,
697-
document_shape(&positional.shape),
688+
positional.name, &positional.shape,
698689
);
699690
}
700691
};
@@ -767,11 +758,7 @@ where
767758
}
768759
// Type/Syntax shape info
769760
if let Some(arg) = &flag.arg {
770-
let _ = write!(
771-
long_desc,
772-
" <{help_subcolor_two}{}{RESET}>",
773-
document_shape(arg)
774-
);
761+
let _ = write!(long_desc, " <{help_subcolor_two}{arg}{RESET}>");
775762
}
776763
if !flag.desc.is_empty() {
777764
let _ = write!(

crates/nu-engine/src/scope.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use nu_protocol::{
2-
DeclId, ModuleId, Signature, Span, SyntaxShape, Type, Value, VarId,
2+
DeclId, ModuleId, Signature, Span, Type, Value, VarId,
33
ast::Expr,
44
engine::{Command, EngineState, Stack, Visibility},
55
record,
@@ -214,7 +214,8 @@ impl<'e, 's> ScopeData<'e, 's> {
214214

215215
// required_positional
216216
for req in &signature.required_positional {
217-
let custom = extract_custom_completion_from_arg(self.engine_state, &req.shape);
217+
let custom =
218+
extract_custom_completion_from_arg(self.engine_state, &req.custom_completion);
218219

219220
sig_records.push(Value::record(
220221
record! {
@@ -233,7 +234,8 @@ impl<'e, 's> ScopeData<'e, 's> {
233234

234235
// optional_positional
235236
for opt in &signature.optional_positional {
236-
let custom = extract_custom_completion_from_arg(self.engine_state, &opt.shape);
237+
let custom =
238+
extract_custom_completion_from_arg(self.engine_state, &opt.custom_completion);
237239
let default = if let Some(val) = &opt.default_value {
238240
val.clone()
239241
} else {
@@ -258,7 +260,8 @@ impl<'e, 's> ScopeData<'e, 's> {
258260
// rest_positional
259261
if let Some(rest) = &signature.rest_positional {
260262
let name = if rest.name == "rest" { "" } else { &rest.name };
261-
let custom = extract_custom_completion_from_arg(self.engine_state, &rest.shape);
263+
let custom =
264+
extract_custom_completion_from_arg(self.engine_state, &rest.custom_completion);
262265

263266
sig_records.push(Value::record(
264267
record! {
@@ -285,11 +288,10 @@ impl<'e, 's> ScopeData<'e, 's> {
285288
continue;
286289
}
287290

288-
let mut custom_completion_command_name: String = "".to_string();
291+
let custom_completion_command_name: String =
292+
extract_custom_completion_from_arg(self.engine_state, &named.custom_completion);
289293
let shape = if let Some(arg) = &named.arg {
290294
flag_type = Value::string("named", span);
291-
custom_completion_command_name =
292-
extract_custom_completion_from_arg(self.engine_state, arg);
293295
Value::string(arg.to_string(), span)
294296
} else {
295297
flag_type = Value::string("switch", span);
@@ -544,14 +546,16 @@ impl<'e, 's> ScopeData<'e, 's> {
544546
}
545547
}
546548

547-
fn extract_custom_completion_from_arg(engine_state: &EngineState, shape: &SyntaxShape) -> String {
548-
match shape {
549-
SyntaxShape::CompleterWrapper(_, custom_completion_decl_id) => {
550-
let custom_completion_command = engine_state.get_decl(*custom_completion_decl_id);
551-
let custom_completion_command_name: &str = custom_completion_command.name();
552-
custom_completion_command_name.to_string()
553-
}
554-
_ => "".to_string(),
549+
fn extract_custom_completion_from_arg(
550+
engine_state: &EngineState,
551+
decl_id: &Option<DeclId>,
552+
) -> String {
553+
if let Some(decl_id) = decl_id {
554+
let custom_completion_command = engine_state.get_decl(*decl_id);
555+
let custom_completion_command_name: &str = custom_completion_command.name();
556+
custom_completion_command_name.to_string()
557+
} else {
558+
"".to_string()
555559
}
556560
}
557561

crates/nu-parser/src/parse_shape_specs.rs

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::{TokenContents, lex::lex_signature, parser::parse_value, trim_quotes};
44
use nu_protocol::{
5-
IntoSpanned, ParseError, Span, Spanned, SyntaxShape, Type, engine::StateWorkingSet,
5+
DeclId, IntoSpanned, ParseError, Span, Spanned, SyntaxShape, Type, engine::StateWorkingSet,
66
};
77

88
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -73,53 +73,29 @@ pub fn parse_shape_name(
7373
parse_generic_shape(working_set, bytes, span, use_loc)
7474
}
7575
_ => {
76-
if bytes.contains(&b'@') {
77-
let mut split = bytes.splitn(2, |b| b == &b'@');
78-
79-
let shape_name = split
80-
.next()
81-
.expect("If `bytes` contains `@` splitn returns 2 slices");
82-
let shape_span = Span::new(span.start, span.start + shape_name.len());
83-
let shape = parse_shape_name(working_set, shape_name, shape_span, use_loc);
84-
if use_loc != ShapeDescriptorUse::Argument {
85-
let illegal_span = Span::new(span.start + shape_name.len(), span.end);
86-
working_set.error(ParseError::LabeledError(
87-
"Unexpected custom completer in type spec".into(),
88-
"Type specifications do not support custom completers".into(),
89-
illegal_span,
90-
));
91-
return shape;
92-
}
93-
94-
let cmd_span = Span::new(span.start + shape_name.len() + 1, span.end);
95-
let cmd_name = split
96-
.next()
97-
.expect("If `bytes` contains `@` splitn returns 2 slices");
98-
99-
let cmd_name = trim_quotes(cmd_name);
100-
if cmd_name.is_empty() {
101-
working_set.error(ParseError::Expected(
102-
"the command name of a completion function",
103-
cmd_span,
104-
));
105-
return shape;
106-
}
107-
108-
if let Some(decl_id) = working_set.find_decl(cmd_name) {
109-
SyntaxShape::CompleterWrapper(Box::new(shape), decl_id)
110-
} else {
111-
working_set.error(ParseError::UnknownCommand(cmd_span));
112-
shape
113-
}
114-
} else {
115-
//TODO: Handle error case for unknown shapes
116-
working_set.error(ParseError::UnknownType(span));
117-
SyntaxShape::Any
118-
}
76+
//TODO: Handle error case for unknown shapes
77+
working_set.error(ParseError::UnknownType(span));
78+
SyntaxShape::Any
11979
}
12080
}
12181
}
12282

83+
pub fn parse_completer(
84+
working_set: &mut StateWorkingSet,
85+
bytes: &[u8],
86+
span: Span,
87+
) -> Option<DeclId> {
88+
let cmd_name = trim_quotes(bytes);
89+
if cmd_name.is_empty() {
90+
working_set.error(ParseError::Expected(
91+
"the command name of a completion function",
92+
span,
93+
));
94+
return None;
95+
}
96+
working_set.find_decl(cmd_name)
97+
}
98+
12399
fn parse_generic_shape(
124100
working_set: &mut StateWorkingSet<'_>,
125101
bytes: &[u8],

crates/nu-parser/src/parser.rs

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
lite_parser::{LiteCommand, LitePipeline, LiteRedirection, LiteRedirectionTarget, lite_parse},
77
parse_keywords::*,
88
parse_patterns::parse_pattern,
9-
parse_shape_specs::{ShapeDescriptorUse, parse_shape_name, parse_type},
9+
parse_shape_specs::{ShapeDescriptorUse, parse_completer, parse_shape_name, parse_type},
1010
type_check::{self, check_range_types, math_result_type, type_compatible},
1111
};
1212
use itertools::Itertools;
@@ -4180,12 +4180,39 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
41804180
}
41814181
ParseMode::Type => {
41824182
if let Some(last) = args.last_mut() {
4183-
let syntax_shape = parse_shape_name(
4184-
working_set,
4185-
&contents,
4186-
span,
4187-
ShapeDescriptorUse::Argument,
4188-
);
4183+
let (syntax_shape, completer) = if contents.contains(&b'@') {
4184+
let mut split = contents.splitn(2, |b| b == &b'@');
4185+
4186+
let shape_name = split
4187+
.next()
4188+
.expect("If `bytes` contains `@` splitn returns 2 slices");
4189+
let shape_span =
4190+
Span::new(span.start, span.start + shape_name.len());
4191+
let cmd_span =
4192+
Span::new(span.start + shape_name.len() + 1, span.end);
4193+
let cmd_name = split
4194+
.next()
4195+
.expect("If `bytes` contains `@` splitn returns 2 slices");
4196+
(
4197+
parse_shape_name(
4198+
working_set,
4199+
shape_name,
4200+
shape_span,
4201+
ShapeDescriptorUse::Argument,
4202+
),
4203+
parse_completer(working_set, cmd_name, cmd_span),
4204+
)
4205+
} else {
4206+
(
4207+
parse_shape_name(
4208+
working_set,
4209+
&contents,
4210+
span,
4211+
ShapeDescriptorUse::Argument,
4212+
),
4213+
None,
4214+
)
4215+
};
41894216
//TODO check if we're replacing a custom parameter already
41904217
match last {
41914218
Arg::Positional {
@@ -4200,12 +4227,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
42004227
type_annotated,
42014228
} => {
42024229
working_set.set_variable_type(var_id.expect("internal error: all custom parameters must have var_ids"), syntax_shape.to_type());
4203-
// Extract custom_completion from CompleterWrapper if present
4204-
if let SyntaxShape::CompleterWrapper(_, decl_id) =
4205-
&syntax_shape
4206-
{
4207-
*custom_completion = Some(*decl_id);
4208-
}
4230+
*custom_completion = completer;
42094231
*shape = syntax_shape;
42104232
*type_annotated = true;
42114233
}
@@ -4216,12 +4238,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
42164238
..
42174239
}) => {
42184240
working_set.set_variable_type(var_id.expect("internal error: all custom parameters must have var_ids"), Type::List(Box::new(syntax_shape.to_type())));
4219-
// Extract custom_completion from CompleterWrapper if present
4220-
if let SyntaxShape::CompleterWrapper(_, decl_id) =
4221-
&syntax_shape
4222-
{
4223-
*custom_completion = Some(*decl_id);
4224-
}
4241+
*custom_completion = completer;
42254242
*shape = syntax_shape;
42264243
}
42274244
Arg::Flag {
@@ -4242,12 +4259,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
42424259
span,
42434260
));
42444261
}
4245-
// Extract custom_completion from CompleterWrapper if present
4246-
if let SyntaxShape::CompleterWrapper(_, decl_id) =
4247-
&syntax_shape
4248-
{
4249-
*custom_completion = Some(*decl_id);
4250-
}
4262+
*custom_completion = completer;
42514263
*arg = Some(syntax_shape);
42524264
*type_annotated = true;
42534265
}
@@ -5204,10 +5216,6 @@ pub fn parse_value(
52045216
}
52055217

52065218
match shape {
5207-
SyntaxShape::CompleterWrapper(shape, _custom_completion) => {
5208-
// Ignore the custom_completion field since it's now stored in PositionalArg/Flag
5209-
parse_value(working_set, span, shape)
5210-
}
52115219
SyntaxShape::Number => parse_number(working_set, span),
52125220
SyntaxShape::Float => parse_float(working_set, span),
52135221
SyntaxShape::Int => parse_int(working_set, span),

crates/nu-protocol/src/syntax_shape.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{DeclId, Type};
1+
use crate::Type;
22
use serde::{Deserialize, Serialize};
33
use std::fmt::Display;
44

@@ -29,9 +29,6 @@ pub enum SyntaxShape {
2929
/// A closure is allowed, eg `{|| start this thing}`
3030
Closure(Option<Vec<SyntaxShape>>),
3131

32-
/// A [`SyntaxShape`] with custom completion logic
33-
CompleterWrapper(Box<SyntaxShape>, DeclId),
34-
3532
/// A datetime value, eg `2022-02-02` or `2019-10-12T07:20:50.52+00:00`
3633
DateTime,
3734

@@ -147,7 +144,6 @@ impl SyntaxShape {
147144
SyntaxShape::Closure(_) => Type::Closure,
148145
SyntaxShape::Binary => Type::Binary,
149146
SyntaxShape::CellPath => Type::Any,
150-
SyntaxShape::CompleterWrapper(inner, _) => inner.to_type(),
151147
SyntaxShape::DateTime => Type::Date,
152148
SyntaxShape::Duration => Type::Duration,
153149
SyntaxShape::Expression => Type::Any,
@@ -248,7 +244,6 @@ impl Display for SyntaxShape {
248244
SyntaxShape::ExternalArgument => write!(f, "external-argument"),
249245
SyntaxShape::Boolean => write!(f, "bool"),
250246
SyntaxShape::Error => write!(f, "error"),
251-
SyntaxShape::CompleterWrapper(x, _) => write!(f, "completable<{x}>"),
252247
SyntaxShape::OneOf(list) => {
253248
write!(f, "oneof<")?;
254249
if let Some((last, rest)) = list.split_last() {

0 commit comments

Comments
 (0)