mirror of
https://github.com/nushell/nushell.git
synced 2025-01-11 16:58:41 +01:00
nu-cli/completions: add completion for $env. (#5199)
* nu-cli/completions: add completion for $env. * use stack to avoid showing hidden env vars
This commit is contained in:
parent
583b7b1821
commit
2a3991cfdb
@ -8,6 +8,7 @@ use nu_protocol::{
|
||||
Span, Value,
|
||||
};
|
||||
use reedline::{Completer as ReedlineCompleter, Suggestion};
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -69,6 +70,10 @@ impl NuCompleter {
|
||||
|
||||
for (flat_idx, flat) in flattened.iter().enumerate() {
|
||||
if pos >= flat.0.start && pos < flat.0.end {
|
||||
// Context variables
|
||||
let mut is_variable_completion = false;
|
||||
let mut previous_expr: Vec<u8> = vec![];
|
||||
|
||||
// Create a new span
|
||||
let new_span = Span {
|
||||
start: flat.0.start,
|
||||
@ -79,9 +84,32 @@ impl NuCompleter {
|
||||
let mut prefix = working_set.get_span_contents(flat.0).to_vec();
|
||||
prefix.remove(pos - flat.0.start);
|
||||
|
||||
// Try to get the previous expression
|
||||
if flat_idx > 0 {
|
||||
match flattened.get(flat_idx - 1) {
|
||||
Some(value) => {
|
||||
let previous_prefix =
|
||||
working_set.get_span_contents(value.0).to_vec();
|
||||
|
||||
// Update the previous expression
|
||||
previous_expr = previous_prefix;
|
||||
|
||||
// Check if should match variable completion
|
||||
if matches!(value.1, FlatShape::Variable) {
|
||||
is_variable_completion = true;
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Variables completion
|
||||
if prefix.starts_with(b"$") {
|
||||
let mut completer = VariableCompletion::new(self.engine_state.clone());
|
||||
if prefix.starts_with(b"$") || is_variable_completion {
|
||||
let mut completer = VariableCompletion::new(
|
||||
self.engine_state.clone(),
|
||||
self.stack.clone(),
|
||||
previous_expr,
|
||||
);
|
||||
|
||||
return self.process_completion(
|
||||
&mut completer,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::completions::{Completer, CompletionOptions};
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, StateWorkingSet},
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
Span,
|
||||
};
|
||||
use reedline::Suggestion;
|
||||
@ -9,11 +9,17 @@ use std::sync::Arc;
|
||||
#[derive(Clone)]
|
||||
pub struct VariableCompletion {
|
||||
engine_state: Arc<EngineState>,
|
||||
stack: Stack,
|
||||
previous_expr: Vec<u8>,
|
||||
}
|
||||
|
||||
impl VariableCompletion {
|
||||
pub fn new(engine_state: Arc<EngineState>) -> Self {
|
||||
Self { engine_state }
|
||||
pub fn new(engine_state: Arc<EngineState>, stack: Stack, previous_expr: Vec<u8>) -> Self {
|
||||
Self {
|
||||
engine_state,
|
||||
stack,
|
||||
previous_expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,10 +33,30 @@ impl Completer for VariableCompletion {
|
||||
_: usize,
|
||||
) -> (Vec<Suggestion>, CompletionOptions) {
|
||||
let mut output = vec![];
|
||||
|
||||
let builtins = ["$nu", "$in", "$config", "$env", "$nothing"];
|
||||
let previous_expr_str = std::str::from_utf8(&self.previous_expr)
|
||||
.unwrap_or("")
|
||||
.to_lowercase();
|
||||
|
||||
// Completions for the given variable (e.g: $env.<tab> for completing $env.SOMETHING)
|
||||
if !self.previous_expr.is_empty() && previous_expr_str.as_str() == "$env" {
|
||||
for env_var in self.stack.get_env_vars(&self.engine_state) {
|
||||
output.push(Suggestion {
|
||||
value: env_var.0,
|
||||
description: None,
|
||||
extra: None,
|
||||
span: reedline::Span {
|
||||
start: span.start - offset,
|
||||
end: span.end - offset,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return (output, CompletionOptions::default());
|
||||
}
|
||||
|
||||
for builtin in builtins {
|
||||
// Variable completion (e.g: $en<tab> to complete $env)
|
||||
if builtin.as_bytes().starts_with(&prefix) {
|
||||
output.push(Suggestion {
|
||||
value: builtin.to_string(),
|
||||
@ -44,6 +70,7 @@ impl Completer for VariableCompletion {
|
||||
}
|
||||
}
|
||||
|
||||
// Working set scope vars
|
||||
for scope in &working_set.delta.scope {
|
||||
for v in &scope.vars {
|
||||
if v.0.starts_with(&prefix) {
|
||||
@ -59,6 +86,8 @@ impl Completer for VariableCompletion {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Permanent state vars
|
||||
for scope in &self.engine_state.scope {
|
||||
for v in &scope.vars {
|
||||
if v.0.starts_with(&prefix) {
|
||||
|
@ -1233,6 +1233,16 @@ impl<'a> StateWorkingSet<'a> {
|
||||
self.permanent_state.env_vars.get(name)
|
||||
}
|
||||
|
||||
pub fn list_env(&self) -> Vec<String> {
|
||||
let mut env_vars = vec![];
|
||||
|
||||
for env_var in self.permanent_state.env_vars.clone().into_iter() {
|
||||
env_vars.push(env_var.0)
|
||||
}
|
||||
|
||||
env_vars
|
||||
}
|
||||
|
||||
pub fn set_variable_type(&mut self, var_id: VarId, ty: Type) {
|
||||
let num_permanent_vars = self.permanent_state.num_vars();
|
||||
if var_id < num_permanent_vars {
|
||||
|
Loading…
Reference in New Issue
Block a user