mirror of
https://github.com/nushell/nushell.git
synced 2025-04-23 04:38:21 +02:00
In Nu we have variables (E.g. $var-name) and these contain `Value` types. This means we can bind to variables any structured data and column path syntax (E.g. `$variable.path.to`) allows flexibility for "querying" said structures. Here we offer completions for these. For example, in a Nushell session the variable `$nu` contains environment values among other things. If we wanted to see in the screen some environment variable (say the var `SHELL`) we do: ``` > echo $nu.env.SHELL ``` with completions we can now do: `echo $nu.env.S[\TAB]` and we get suggestions that start at the column path `$nu.env` with vars starting with the letter `S` in this case `SHELL` appears in the suggestions.
84 lines
2.0 KiB
Rust
84 lines
2.0 KiB
Rust
use crate::{UntaggedValue, Value};
|
|
use nu_errors::ShellError;
|
|
use std::path::{Component, Path, PathBuf};
|
|
|
|
fn is_value_tagged_dir(value: &Value) -> bool {
|
|
matches!(
|
|
&value.value,
|
|
UntaggedValue::Row(_) | UntaggedValue::Table(_)
|
|
)
|
|
}
|
|
|
|
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
|
pub struct ValueResource {
|
|
pub at: usize,
|
|
pub loc: PathBuf,
|
|
}
|
|
|
|
impl ValueResource {}
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct ValueStructure {
|
|
pub resources: Vec<ValueResource>,
|
|
}
|
|
|
|
impl ValueStructure {
|
|
pub fn new() -> ValueStructure {
|
|
ValueStructure {
|
|
resources: Vec::<ValueResource>::new(),
|
|
}
|
|
}
|
|
|
|
pub fn exists(&self, path: &Path) -> bool {
|
|
if path == Path::new("/") {
|
|
return true;
|
|
}
|
|
|
|
let path = if path.starts_with("/") {
|
|
path.strip_prefix("/").unwrap_or(path)
|
|
} else {
|
|
path
|
|
};
|
|
|
|
let comps: Vec<_> = path.components().map(Component::as_os_str).collect();
|
|
|
|
let mut is_there = true;
|
|
|
|
for (at, fragment) in comps.iter().enumerate() {
|
|
is_there = is_there
|
|
&& self
|
|
.resources
|
|
.iter()
|
|
.any(|resource| at == resource.at && *fragment == resource.loc.as_os_str());
|
|
}
|
|
|
|
is_there
|
|
}
|
|
|
|
pub fn walk_decorate(&mut self, start: &Value) -> Result<(), ShellError> {
|
|
self.resources = Vec::<ValueResource>::new();
|
|
self.build(start, 0)?;
|
|
self.resources.sort();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn build(&mut self, src: &Value, lvl: usize) -> Result<(), ShellError> {
|
|
for entry in src.row_entries() {
|
|
let value = entry.1;
|
|
let path = entry.0;
|
|
|
|
self.resources.push(ValueResource {
|
|
at: lvl,
|
|
loc: PathBuf::from(path),
|
|
});
|
|
|
|
if is_value_tagged_dir(value) {
|
|
self.build(value, lvl + 1)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|