mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Add a simple scope variable
This commit is contained in:
parent
3c1b3473ae
commit
d856cebebd
8 changed files with 204 additions and 47 deletions
98
Cargo.lock
generated
98
Cargo.lock
generated
|
@ -163,6 +163,28 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono-tz"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64c01c1c607d25c71bbaa67c113d6c6b36c434744b4fd66691d711b5b1bc0c8b"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"chrono-tz-build",
|
||||||
|
"phf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono-tz-build"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db058d493fb2f65f41861bfed7e3fe6335264a9f0f92710cab5bdf01fef09069"
|
||||||
|
dependencies = [
|
||||||
|
"parse-zoneinfo",
|
||||||
|
"phf",
|
||||||
|
"phf_codegen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "console"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
|
@ -622,6 +644,8 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytesize",
|
"bytesize",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"chrono-humanize",
|
||||||
|
"chrono-tz",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"glob",
|
"glob",
|
||||||
"lscolors",
|
"lscolors",
|
||||||
|
@ -636,6 +660,7 @@ dependencies = [
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"titlecase",
|
||||||
"trash",
|
"trash",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
@ -801,6 +826,54 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parse-zoneinfo"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
|
||||||
|
dependencies = [
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_codegen"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
"uncased",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -1096,6 +1169,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sized-chunks"
|
name = "sized-chunks"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
|
@ -1263,6 +1342,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "titlecase"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f565e410cfc24c2f2a89960b023ca192689d7f77d3f8d4f4af50c2d8affe1117"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trash"
|
name = "trash"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -1278,6 +1367,15 @@ version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uncased"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-linebreak"
|
name = "unicode-linebreak"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
|
|
@ -95,16 +95,6 @@ pub fn create_default_context() -> EngineState {
|
||||||
|
|
||||||
let sig = Signature::build("exit");
|
let sig = Signature::build("exit");
|
||||||
working_set.add_decl(sig.predeclare());
|
working_set.add_decl(sig.predeclare());
|
||||||
let sig = Signature::build("vars");
|
|
||||||
working_set.add_decl(sig.predeclare());
|
|
||||||
let sig = Signature::build("decls");
|
|
||||||
working_set.add_decl(sig.predeclare());
|
|
||||||
let sig = Signature::build("blocks");
|
|
||||||
working_set.add_decl(sig.predeclare());
|
|
||||||
let sig = Signature::build("stack");
|
|
||||||
working_set.add_decl(sig.predeclare());
|
|
||||||
let sig = Signature::build("contents");
|
|
||||||
working_set.add_decl(sig.predeclare());
|
|
||||||
|
|
||||||
working_set.render()
|
working_set.render()
|
||||||
};
|
};
|
||||||
|
|
|
@ -371,12 +371,12 @@ pub fn eval_block(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval_variable(
|
pub fn eval_variable(
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
var_id: VarId,
|
var_id: VarId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
if var_id == 0 {
|
if var_id == nu_protocol::NU_VARIABLE_ID {
|
||||||
// $nu
|
// $nu
|
||||||
let mut output_cols = vec![];
|
let mut output_cols = vec![];
|
||||||
let mut output_vals = vec![];
|
let mut output_vals = vec![];
|
||||||
|
@ -425,6 +425,71 @@ pub fn eval_variable(
|
||||||
output_vals.push(Value::String { val: cwd, span })
|
output_vals.push(Value::String { val: cwd, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(Value::Record {
|
||||||
|
cols: output_cols,
|
||||||
|
vals: output_vals,
|
||||||
|
span,
|
||||||
|
})
|
||||||
|
} else if var_id == nu_protocol::SCOPE_VARIABLE_ID {
|
||||||
|
let mut output_cols = vec![];
|
||||||
|
let mut output_vals = vec![];
|
||||||
|
|
||||||
|
let mut vars = vec![];
|
||||||
|
let mut commands = vec![];
|
||||||
|
let mut aliases = vec![];
|
||||||
|
let mut modules = vec![];
|
||||||
|
|
||||||
|
for frame in &engine_state.scope {
|
||||||
|
for var in &frame.vars {
|
||||||
|
vars.push(Value::String {
|
||||||
|
val: String::from_utf8_lossy(var.0).to_string(),
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for command in &frame.decls {
|
||||||
|
commands.push(Value::String {
|
||||||
|
val: String::from_utf8_lossy(command.0).to_string(),
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for alias in &frame.aliases {
|
||||||
|
aliases.push(Value::String {
|
||||||
|
val: String::from_utf8_lossy(alias.0).to_string(),
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for module in &frame.modules {
|
||||||
|
modules.push(Value::String {
|
||||||
|
val: String::from_utf8_lossy(module.0).to_string(),
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output_cols.push("vars".to_string());
|
||||||
|
output_vals.push(Value::List { vals: vars, span });
|
||||||
|
|
||||||
|
output_cols.push("commands".to_string());
|
||||||
|
output_vals.push(Value::List {
|
||||||
|
vals: commands,
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
|
||||||
|
output_cols.push("aliases".to_string());
|
||||||
|
output_vals.push(Value::List {
|
||||||
|
vals: aliases,
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
|
||||||
|
output_cols.push("modules".to_string());
|
||||||
|
output_vals.push(Value::List {
|
||||||
|
vals: modules,
|
||||||
|
span,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(Value::Record {
|
Ok(Value::Record {
|
||||||
cols: output_cols,
|
cols: output_cols,
|
||||||
vals: output_vals,
|
vals: output_vals,
|
||||||
|
|
|
@ -1198,7 +1198,17 @@ pub fn parse_variable_expr(
|
||||||
} else if contents == b"$nu" {
|
} else if contents == b"$nu" {
|
||||||
return (
|
return (
|
||||||
Expression {
|
Expression {
|
||||||
expr: Expr::Var(0),
|
expr: Expr::Var(nu_protocol::NU_VARIABLE_ID),
|
||||||
|
span,
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
} else if contents == b"$scope" {
|
||||||
|
return (
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Var(nu_protocol::SCOPE_VARIABLE_ID),
|
||||||
span,
|
span,
|
||||||
ty: Type::Unknown,
|
ty: Type::Unknown,
|
||||||
custom_completion: None,
|
custom_completion: None,
|
||||||
|
|
|
@ -6,17 +6,6 @@ use std::{
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EngineState {
|
|
||||||
files: im::Vector<(String, usize, usize)>,
|
|
||||||
file_contents: im::Vector<(Vec<u8>, usize, usize)>,
|
|
||||||
vars: im::Vector<Type>,
|
|
||||||
decls: im::Vector<Box<dyn Command + 'static>>,
|
|
||||||
blocks: im::Vector<Block>,
|
|
||||||
pub scope: im::Vector<ScopeFrame>,
|
|
||||||
pub ctrlc: Option<Arc<AtomicBool>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tells whether a decl etc. is visible or not
|
// Tells whether a decl etc. is visible or not
|
||||||
// TODO: When adding new exportables (env vars, aliases, etc.), parametrize the ID type with generics
|
// TODO: When adding new exportables (env vars, aliases, etc.), parametrize the ID type with generics
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -62,9 +51,9 @@ impl Visibility {
|
||||||
pub struct ScopeFrame {
|
pub struct ScopeFrame {
|
||||||
pub vars: HashMap<Vec<u8>, VarId>,
|
pub vars: HashMap<Vec<u8>, VarId>,
|
||||||
predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations
|
predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations
|
||||||
decls: HashMap<Vec<u8>, DeclId>,
|
pub decls: HashMap<Vec<u8>, DeclId>,
|
||||||
aliases: HashMap<Vec<u8>, Vec<Span>>,
|
pub aliases: HashMap<Vec<u8>, Vec<Span>>,
|
||||||
modules: HashMap<Vec<u8>, BlockId>,
|
pub modules: HashMap<Vec<u8>, BlockId>,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,18 +80,26 @@ impl Default for ScopeFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EngineState {
|
#[derive(Clone)]
|
||||||
fn default() -> Self {
|
pub struct EngineState {
|
||||||
Self::new()
|
files: im::Vector<(String, usize, usize)>,
|
||||||
}
|
file_contents: im::Vector<(Vec<u8>, usize, usize)>,
|
||||||
|
vars: im::Vector<Type>,
|
||||||
|
decls: im::Vector<Box<dyn Command + 'static>>,
|
||||||
|
blocks: im::Vector<Block>,
|
||||||
|
pub scope: im::Vector<ScopeFrame>,
|
||||||
|
pub ctrlc: Option<Arc<AtomicBool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const NU_VARIABLE_ID: usize = 0;
|
||||||
|
pub const SCOPE_VARIABLE_ID: usize = 1;
|
||||||
|
|
||||||
impl EngineState {
|
impl EngineState {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
files: im::vector![],
|
files: im::vector![],
|
||||||
file_contents: im::vector![],
|
file_contents: im::vector![],
|
||||||
vars: im::vector![Type::Unknown],
|
vars: im::vector![Type::Unknown, Type::Unknown],
|
||||||
decls: im::vector![],
|
decls: im::vector![],
|
||||||
blocks: im::vector![],
|
blocks: im::vector![],
|
||||||
scope: im::vector![ScopeFrame::new()],
|
scope: im::vector![ScopeFrame::new()],
|
||||||
|
@ -319,6 +316,12 @@ impl EngineState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for EngineState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct StateWorkingSet<'a> {
|
pub struct StateWorkingSet<'a> {
|
||||||
pub permanent_state: &'a EngineState,
|
pub permanent_state: &'a EngineState,
|
||||||
pub delta: StateDelta,
|
pub delta: StateDelta,
|
||||||
|
|
|
@ -11,6 +11,7 @@ mod ty;
|
||||||
mod value;
|
mod value;
|
||||||
pub use value::Value;
|
pub use value::Value;
|
||||||
|
|
||||||
|
pub use engine::{NU_VARIABLE_ID, SCOPE_VARIABLE_ID};
|
||||||
pub use example::*;
|
pub use example::*;
|
||||||
pub use id::*;
|
pub use id::*;
|
||||||
pub use pipeline_data::*;
|
pub use pipeline_data::*;
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -225,21 +225,6 @@ fn main() -> Result<()> {
|
||||||
Ok(Signal::Success(s)) => {
|
Ok(Signal::Success(s)) => {
|
||||||
if s.trim() == "exit" {
|
if s.trim() == "exit" {
|
||||||
break;
|
break;
|
||||||
} else if s.trim() == "vars" {
|
|
||||||
engine_state.print_vars();
|
|
||||||
continue;
|
|
||||||
} else if s.trim() == "decls" {
|
|
||||||
engine_state.print_decls();
|
|
||||||
continue;
|
|
||||||
} else if s.trim() == "blocks" {
|
|
||||||
engine_state.print_blocks();
|
|
||||||
continue;
|
|
||||||
} else if s.trim() == "stack" {
|
|
||||||
stack.print_stack();
|
|
||||||
continue;
|
|
||||||
} else if s.trim() == "contents" {
|
|
||||||
engine_state.print_contents();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_source(
|
eval_source(
|
||||||
|
|
|
@ -801,3 +801,8 @@ fn long_flag() -> TestResult {
|
||||||
fn help_works_with_missing_requirements() -> TestResult {
|
fn help_works_with_missing_requirements() -> TestResult {
|
||||||
run_test(r#"each --help | lines | length"#, "10")
|
run_test(r#"each --help | lines | length"#, "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scope_variable() -> TestResult {
|
||||||
|
run_test(r"let x = 3; $scope.vars.0", "$x")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue