mirror of
https://github.com/nushell/nushell
synced 2024-12-28 05:53:09 +00:00
nu-cli/completions: apply correctly nesting for env vars (#5382)
This commit is contained in:
parent
ae9c0fc138
commit
7c6f976d65
1 changed files with 72 additions and 69 deletions
|
@ -6,6 +6,7 @@ use nu_protocol::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -49,26 +50,46 @@ impl Completer for VariableCompletion {
|
||||||
start: span.start - offset,
|
start: span.start - offset,
|
||||||
end: span.end - offset,
|
end: span.end - offset,
|
||||||
};
|
};
|
||||||
|
let sublevels_count = self.var_context.1.len();
|
||||||
|
|
||||||
// Completions for the given variable
|
// Completions for the given variable
|
||||||
if !var_str.is_empty() {
|
if !var_str.is_empty() {
|
||||||
// Completion for $env.<tab>
|
// Completion for $env.<tab>
|
||||||
if var_str.as_str() == "$env" {
|
if var_str.as_str() == "$env" {
|
||||||
for env_var in self.stack.get_env_vars(&self.engine_state) {
|
let env_vars = self.stack.get_env_vars(&self.engine_state);
|
||||||
if options
|
|
||||||
.match_algorithm
|
|
||||||
.matches_u8(env_var.0.as_bytes(), &prefix)
|
|
||||||
{
|
|
||||||
output.push(Suggestion {
|
|
||||||
value: env_var.0,
|
|
||||||
description: None,
|
|
||||||
extra: None,
|
|
||||||
span: current_span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
// Return nested values
|
||||||
|
if sublevels_count > 0 {
|
||||||
|
// Extract the target var ($env.<target-var>)
|
||||||
|
let target_var = self.var_context.1[0].clone();
|
||||||
|
let target_var_str =
|
||||||
|
str::from_utf8(&target_var).unwrap_or_default().to_string();
|
||||||
|
|
||||||
|
// Everything after the target var is the nested level ($env.<target-var>.<nested_levels>...)
|
||||||
|
let nested_levels: Vec<Vec<u8>> =
|
||||||
|
self.var_context.1.clone().into_iter().skip(1).collect();
|
||||||
|
|
||||||
|
if let Some(val) = env_vars.get(&target_var_str) {
|
||||||
|
return nested_suggestions(val.clone(), nested_levels, current_span);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No nesting provided, return all env vars
|
||||||
|
for env_var in env_vars {
|
||||||
|
if options
|
||||||
|
.match_algorithm
|
||||||
|
.matches_u8(env_var.0.as_bytes(), &prefix)
|
||||||
|
{
|
||||||
|
output.push(Suggestion {
|
||||||
|
value: env_var.0,
|
||||||
|
description: None,
|
||||||
|
extra: None,
|
||||||
|
span: current_span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Completions for $nu.<tab>
|
// Completions for $nu.<tab>
|
||||||
|
@ -83,33 +104,7 @@ impl Completer for VariableCompletion {
|
||||||
end: current_span.end,
|
end: current_span.end,
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
// Find recursively the values for sublevels
|
return nested_suggestions(nuval, self.var_context.1.clone(), current_span);
|
||||||
// if no sublevels are set it returns the current value
|
|
||||||
let value = recursive_value(nuval, self.var_context.1.clone());
|
|
||||||
|
|
||||||
match value {
|
|
||||||
Value::Record {
|
|
||||||
cols,
|
|
||||||
vals: _,
|
|
||||||
span: _,
|
|
||||||
} => {
|
|
||||||
// Add all the columns as completion
|
|
||||||
for item in cols {
|
|
||||||
output.push(Suggestion {
|
|
||||||
value: item,
|
|
||||||
description: None,
|
|
||||||
extra: None,
|
|
||||||
span: current_span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,34 +120,8 @@ impl Completer for VariableCompletion {
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the value exists and it's of type Record
|
// If the value exists and it's of type Record
|
||||||
if let Ok(mut value) = var {
|
if let Ok(value) = var {
|
||||||
// Find recursively the values for sublevels
|
return nested_suggestions(value, self.var_context.1.clone(), current_span);
|
||||||
// if no sublevels are set it returns the current value
|
|
||||||
value = recursive_value(value, self.var_context.1.clone());
|
|
||||||
|
|
||||||
match value {
|
|
||||||
Value::Record {
|
|
||||||
cols,
|
|
||||||
vals: _,
|
|
||||||
span: _,
|
|
||||||
} => {
|
|
||||||
// Add all the columns as completion
|
|
||||||
for item in cols {
|
|
||||||
output.push(Suggestion {
|
|
||||||
value: item,
|
|
||||||
description: None,
|
|
||||||
extra: None,
|
|
||||||
span: current_span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +175,40 @@ impl Completer for VariableCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find recursively the values for sublevels
|
||||||
|
// if no sublevels are set it returns the current value
|
||||||
|
fn nested_suggestions(
|
||||||
|
val: Value,
|
||||||
|
sublevels: Vec<Vec<u8>>,
|
||||||
|
current_span: reedline::Span,
|
||||||
|
) -> Vec<Suggestion> {
|
||||||
|
let mut output: Vec<Suggestion> = vec![];
|
||||||
|
let value = recursive_value(val, sublevels);
|
||||||
|
|
||||||
|
match value {
|
||||||
|
Value::Record {
|
||||||
|
cols,
|
||||||
|
vals: _,
|
||||||
|
span: _,
|
||||||
|
} => {
|
||||||
|
// Add all the columns as completion
|
||||||
|
for item in cols {
|
||||||
|
output.push(Suggestion {
|
||||||
|
value: item,
|
||||||
|
description: None,
|
||||||
|
extra: None,
|
||||||
|
span: current_span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => output,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extracts the recursive value (e.g: $var.a.b.c)
|
||||||
fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
|
fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
|
||||||
// Go to next sublevel
|
// Go to next sublevel
|
||||||
if let Some(next_sublevel) = sublevels.clone().into_iter().next() {
|
if let Some(next_sublevel) = sublevels.clone().into_iter().next() {
|
||||||
|
|
Loading…
Reference in a new issue