Skip to content

Commit c79ee59

Browse files
committed
refactor: CellPathCompletion to separated file
1 parent 129857d commit c79ee59

File tree

4 files changed

+105
-95
lines changed

4 files changed

+105
-95
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use crate::completions::{Completer, CompletionOptions, SemanticSuggestion, SuggestionKind};
2+
use nu_engine::{column::get_columns, eval_variable};
3+
use nu_protocol::{
4+
ast::{Expr, FullCellPath, PathMember},
5+
engine::{Stack, StateWorkingSet},
6+
eval_const::eval_constant,
7+
Span, Value,
8+
};
9+
use reedline::Suggestion;
10+
11+
use super::completion_options::NuMatcher;
12+
13+
pub struct CellPathCompletion<'a> {
14+
pub full_cell_path: &'a FullCellPath,
15+
}
16+
17+
impl Completer for CellPathCompletion<'_> {
18+
fn fetch(
19+
&mut self,
20+
working_set: &StateWorkingSet,
21+
stack: &Stack,
22+
_prefix: &[u8],
23+
_span: Span,
24+
offset: usize,
25+
_pos: usize,
26+
options: &CompletionOptions,
27+
) -> Vec<SemanticSuggestion> {
28+
// empty tail is already handled as variable names completion
29+
let Some((prefix_member, path_members)) = self.full_cell_path.tail.split_last() else {
30+
return vec![];
31+
};
32+
let (mut prefix_str, span) = match prefix_member {
33+
PathMember::String { val, span, .. } => (val.clone(), span),
34+
PathMember::Int { val, span, .. } => (val.to_string(), span),
35+
};
36+
// strip the placeholder
37+
prefix_str.pop();
38+
let true_end = std::cmp::max(span.start, span.end - 1);
39+
let span = Span::new(span.start, true_end);
40+
let current_span = reedline::Span {
41+
start: span.start - offset,
42+
end: true_end - offset,
43+
};
44+
45+
let mut matcher = NuMatcher::new(prefix_str, options.clone());
46+
47+
// evaluate the head expression to get its value
48+
let value = if let Expr::Var(var_id) = self.full_cell_path.head.expr {
49+
working_set
50+
.get_variable(var_id)
51+
.const_val
52+
.to_owned()
53+
.or_else(|| eval_variable(working_set.permanent_state, stack, var_id, span).ok())
54+
} else {
55+
eval_constant(working_set, &self.full_cell_path.head).ok()
56+
}
57+
.unwrap_or_default();
58+
59+
for suggestion in nested_suggestions(&value, path_members, current_span) {
60+
matcher.add_semantic_suggestion(suggestion);
61+
}
62+
matcher.results()
63+
}
64+
}
65+
66+
// Find recursively the values for cell_path
67+
fn nested_suggestions(
68+
val: &Value,
69+
path_members: &[PathMember],
70+
current_span: reedline::Span,
71+
) -> Vec<SemanticSuggestion> {
72+
let value = val
73+
.clone()
74+
.follow_cell_path(path_members, false)
75+
.unwrap_or_default();
76+
77+
let kind = SuggestionKind::Type(value.get_type());
78+
let str_to_suggestion = |s: String| SemanticSuggestion {
79+
suggestion: Suggestion {
80+
value: s,
81+
span: current_span,
82+
..Suggestion::default()
83+
},
84+
kind: Some(kind.to_owned()),
85+
};
86+
match value {
87+
Value::Record { val, .. } => val
88+
.columns()
89+
.map(|s| str_to_suggestion(s.to_string()))
90+
.collect(),
91+
Value::List { vals, .. } => get_columns(vals.as_slice())
92+
.into_iter()
93+
.map(str_to_suggestion)
94+
.collect(),
95+
_ => vec![],
96+
}
97+
}

crates/nu-cli/src/completions/completer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::completions::{
22
CellPathCompletion, CommandCompletion, Completer, CompletionOptions, CustomCompletion,
33
DirectoryCompletion, DotNuCompletion, FileCompletion, FlagCompletion, OperatorCompletion,
4-
VariableNameCompletion,
4+
VariableCompletion,
55
};
66
use log::debug;
77
use nu_color_config::{color_record_to_nustyle, lookup_ansi_color_style};
@@ -104,7 +104,7 @@ impl NuCompleter {
104104
if !prefix.starts_with(b"$") {
105105
return vec![];
106106
}
107-
let mut variable_names_completer = VariableNameCompletion {};
107+
let mut variable_names_completer = VariableCompletion {};
108108
self.process_completion(
109109
&mut variable_names_completer,
110110
working_set,

crates/nu-cli/src/completions/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod base;
2+
mod cell_path_completions;
23
mod command_completions;
34
mod completer;
45
mod completion_common;
@@ -12,6 +13,7 @@ mod operator_completions;
1213
mod variable_completions;
1314

1415
pub use base::{Completer, SemanticSuggestion, SuggestionKind};
16+
pub use cell_path_completions::CellPathCompletion;
1517
pub use command_completions::CommandCompletion;
1618
pub use completer::NuCompleter;
1719
pub use completion_options::{CompletionOptions, MatchAlgorithm};
@@ -21,4 +23,4 @@ pub use dotnu_completions::DotNuCompletion;
2123
pub use file_completions::{file_path_completion, FileCompletion};
2224
pub use flag_completions::FlagCompletion;
2325
pub use operator_completions::OperatorCompletion;
24-
pub use variable_completions::{CellPathCompletion, VariableNameCompletion};
26+
pub use variable_completions::VariableCompletion;
Lines changed: 3 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
use crate::completions::{Completer, CompletionOptions, SemanticSuggestion, SuggestionKind};
2-
use nu_engine::{column::get_columns, eval_variable};
32
use nu_protocol::{
4-
ast::{Expr, FullCellPath, PathMember},
53
engine::{Stack, StateWorkingSet},
6-
eval_const::eval_constant,
7-
Span, Value, VarId,
4+
Span, VarId,
85
};
96
use reedline::Suggestion;
107

118
use super::completion_options::NuMatcher;
129

13-
pub struct VariableNameCompletion {}
10+
pub struct VariableCompletion {}
1411

15-
impl Completer for VariableNameCompletion {
12+
impl Completer for VariableCompletion {
1613
fn fetch(
1714
&mut self,
1815
working_set: &StateWorkingSet,
@@ -83,89 +80,3 @@ impl Completer for VariableNameCompletion {
8380
matcher.results()
8481
}
8582
}
86-
87-
pub struct CellPathCompletion<'a> {
88-
pub full_cell_path: &'a FullCellPath,
89-
}
90-
91-
impl Completer for CellPathCompletion<'_> {
92-
fn fetch(
93-
&mut self,
94-
working_set: &StateWorkingSet,
95-
stack: &Stack,
96-
_prefix: &[u8],
97-
_span: Span,
98-
offset: usize,
99-
_pos: usize,
100-
options: &CompletionOptions,
101-
) -> Vec<SemanticSuggestion> {
102-
// empty tail is already handled as variable names completion
103-
let Some((prefix_member, path_members)) = self.full_cell_path.tail.split_last() else {
104-
return vec![];
105-
};
106-
let (mut prefix_str, span) = match prefix_member {
107-
PathMember::String { val, span, .. } => (val.clone(), span),
108-
PathMember::Int { val, span, .. } => (val.to_string(), span),
109-
};
110-
// strip the placeholder
111-
prefix_str.pop();
112-
let true_end = std::cmp::max(span.start, span.end - 1);
113-
let span = Span::new(span.start, true_end);
114-
let current_span = reedline::Span {
115-
start: span.start - offset,
116-
end: true_end - offset,
117-
};
118-
119-
let mut matcher = NuMatcher::new(prefix_str, options.clone());
120-
121-
// evaluate the head expression to get its value
122-
let value = if let Expr::Var(var_id) = self.full_cell_path.head.expr {
123-
working_set
124-
.get_variable(var_id)
125-
.const_val
126-
.to_owned()
127-
.or_else(|| eval_variable(working_set.permanent_state, stack, var_id, span).ok())
128-
} else {
129-
eval_constant(working_set, &self.full_cell_path.head).ok()
130-
}
131-
.unwrap_or_default();
132-
133-
for suggestion in nested_suggestions(&value, path_members, current_span) {
134-
matcher.add_semantic_suggestion(suggestion);
135-
}
136-
matcher.results()
137-
}
138-
}
139-
140-
// Find recursively the values for cell_path
141-
fn nested_suggestions(
142-
val: &Value,
143-
path_members: &[PathMember],
144-
current_span: reedline::Span,
145-
) -> Vec<SemanticSuggestion> {
146-
let value = val
147-
.clone()
148-
.follow_cell_path(path_members, false)
149-
.unwrap_or_default();
150-
151-
let kind = SuggestionKind::Type(value.get_type());
152-
let str_to_suggestion = |s: String| SemanticSuggestion {
153-
suggestion: Suggestion {
154-
value: s,
155-
span: current_span,
156-
..Suggestion::default()
157-
},
158-
kind: Some(kind.to_owned()),
159-
};
160-
match value {
161-
Value::Record { val, .. } => val
162-
.columns()
163-
.map(|s| str_to_suggestion(s.to_string()))
164-
.collect(),
165-
Value::List { vals, .. } => get_columns(vals.as_slice())
166-
.into_iter()
167-
.map(str_to_suggestion)
168-
.collect(),
169-
_ => vec![],
170-
}
171-
}

0 commit comments

Comments
 (0)