2021-07-01 18:09:50 +00:00
|
|
|
use crate::{
|
|
|
|
evaluate::{lang, scope::Scope},
|
|
|
|
EvaluationContext,
|
|
|
|
};
|
2021-03-29 08:27:51 +00:00
|
|
|
use indexmap::IndexMap;
|
2021-04-09 06:03:12 +00:00
|
|
|
use nu_data::config::path::{default_history_path, history_path};
|
2020-02-11 23:25:56 +00:00
|
|
|
use nu_errors::ShellError;
|
2021-04-15 19:02:08 +00:00
|
|
|
use nu_protocol::{Dictionary, ShellTypeName, Signature, TaggedDictBuilder, UntaggedValue, Value};
|
2021-03-29 08:27:51 +00:00
|
|
|
use nu_source::{Spanned, Tag};
|
2020-02-11 23:25:56 +00:00
|
|
|
|
2021-06-23 07:21:39 +00:00
|
|
|
pub fn nu(scope: &Scope, ctx: &EvaluationContext) -> Result<Value, ShellError> {
|
2021-03-27 05:08:03 +00:00
|
|
|
let env = &scope.get_env_vars();
|
2021-06-23 07:21:39 +00:00
|
|
|
let tag = Tag::unknown();
|
2021-03-27 05:08:03 +00:00
|
|
|
|
2020-02-11 23:25:56 +00:00
|
|
|
let mut nu_dict = TaggedDictBuilder::new(&tag);
|
|
|
|
|
|
|
|
let mut dict = TaggedDictBuilder::new(&tag);
|
2021-05-13 03:03:49 +00:00
|
|
|
|
2020-05-27 04:50:26 +00:00
|
|
|
for v in env.iter() {
|
2020-02-11 23:25:56 +00:00
|
|
|
if v.0 != "PATH" && v.0 != "Path" {
|
|
|
|
dict.insert_untagged(v.0, UntaggedValue::string(v.1));
|
|
|
|
}
|
|
|
|
}
|
2021-04-09 06:03:12 +00:00
|
|
|
|
2020-02-11 23:25:56 +00:00
|
|
|
nu_dict.insert_value("env", dict.into_value());
|
|
|
|
|
2021-04-09 06:03:12 +00:00
|
|
|
nu_dict.insert_value(
|
|
|
|
"history-path",
|
|
|
|
UntaggedValue::filepath(default_history_path()).into_value(&tag),
|
|
|
|
);
|
|
|
|
|
2021-06-14 03:19:12 +00:00
|
|
|
if let Some(global_cfg) = &ctx.configs().lock().global_config {
|
2021-04-09 06:03:12 +00:00
|
|
|
nu_dict.insert_value(
|
|
|
|
"config",
|
|
|
|
UntaggedValue::row(global_cfg.vars.clone()).into_value(&tag),
|
|
|
|
);
|
|
|
|
|
|
|
|
nu_dict.insert_value(
|
|
|
|
"config-path",
|
|
|
|
UntaggedValue::filepath(global_cfg.file_path.clone()).into_value(&tag),
|
|
|
|
);
|
2021-03-31 05:52:34 +00:00
|
|
|
|
2021-04-09 06:03:12 +00:00
|
|
|
// overwrite hist-path if present
|
|
|
|
if let Some(hist_path) = history_path(global_cfg) {
|
|
|
|
nu_dict.insert_value(
|
|
|
|
"history-path",
|
|
|
|
UntaggedValue::filepath(hist_path).into_value(&tag),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2020-02-11 23:25:56 +00:00
|
|
|
|
2021-05-13 03:03:49 +00:00
|
|
|
// A note about environment variables:
|
|
|
|
//
|
|
|
|
// Environment variables in Unix platforms are case-sensitive. On Windows, case-sensitivity is context-dependent.
|
2021-05-13 19:21:16 +00:00
|
|
|
// In cmd.exe, running `SET` will show you the list of environment variables and their names will be mixed case.
|
2021-05-13 03:03:49 +00:00
|
|
|
// In PowerShell, running `Get-ChildItem Env:` will show you a list of environment variables, and they will match
|
|
|
|
// the case in the environment variable section of the user configuration
|
|
|
|
//
|
|
|
|
// Rust currently returns the DOS-style, all-uppercase environment variables on Windows (as of 1.52) when running
|
|
|
|
// std::env::vars(), rather than the case-sensitive Environment.GetEnvironmentVariables() of .NET that PowerShell
|
|
|
|
// uses.
|
|
|
|
//
|
|
|
|
// For now, we work around the discrepency as best we can by merging the two into what is shown to the user as the
|
|
|
|
// 'path' column of `$nu`
|
2020-02-11 23:25:56 +00:00
|
|
|
let mut table = vec![];
|
2021-02-18 02:56:14 +00:00
|
|
|
for v in env.iter() {
|
|
|
|
if v.0 == "PATH" || v.0 == "Path" {
|
|
|
|
for path in std::env::split_paths(&v.1) {
|
|
|
|
table.push(UntaggedValue::filepath(path).into_value(&tag));
|
|
|
|
}
|
2020-02-11 23:25:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
nu_dict.insert_value("path", UntaggedValue::table(&table).into_value(&tag));
|
|
|
|
|
2020-03-08 05:33:30 +00:00
|
|
|
let path = std::env::current_dir()?;
|
2021-01-08 07:30:41 +00:00
|
|
|
nu_dict.insert_value("cwd", UntaggedValue::filepath(path).into_value(&tag));
|
2020-03-08 05:33:30 +00:00
|
|
|
|
2021-01-10 02:50:49 +00:00
|
|
|
if let Some(home) = crate::filesystem::filesystem_shell::homedir_if_possible() {
|
2021-01-08 07:30:41 +00:00
|
|
|
nu_dict.insert_value("home-dir", UntaggedValue::filepath(home).into_value(&tag));
|
2020-03-08 05:33:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let temp = std::env::temp_dir();
|
2021-01-08 07:30:41 +00:00
|
|
|
nu_dict.insert_value("temp-dir", UntaggedValue::filepath(temp).into_value(&tag));
|
2020-03-08 05:33:30 +00:00
|
|
|
|
2020-09-17 06:02:30 +00:00
|
|
|
#[cfg(feature = "rustyline-support")]
|
|
|
|
{
|
2021-01-13 17:31:47 +00:00
|
|
|
let keybinding_path = nu_data::keybinding::keybinding_path()?;
|
2020-09-17 06:02:30 +00:00
|
|
|
nu_dict.insert_value(
|
|
|
|
"keybinding-path",
|
2021-01-08 07:30:41 +00:00
|
|
|
UntaggedValue::filepath(keybinding_path).into_value(&tag),
|
2020-09-17 06:02:30 +00:00
|
|
|
);
|
|
|
|
}
|
2020-07-15 07:51:59 +00:00
|
|
|
|
2021-07-01 18:09:50 +00:00
|
|
|
let cmd_info = lang::Lang::query_commands(scope);
|
|
|
|
match cmd_info {
|
|
|
|
Ok(cmds) => nu_dict.insert_value("lang", UntaggedValue::table(&cmds).into_value(&tag)),
|
|
|
|
Err(_) => nu_dict.insert_value("lang", UntaggedValue::string("no commands found")),
|
|
|
|
}
|
|
|
|
|
2020-02-11 23:25:56 +00:00
|
|
|
Ok(nu_dict.into_value())
|
|
|
|
}
|
2021-03-29 08:27:51 +00:00
|
|
|
|
|
|
|
pub fn scope(
|
|
|
|
aliases: &IndexMap<String, Vec<Spanned<String>>>,
|
2021-04-12 02:38:47 +00:00
|
|
|
commands: &IndexMap<String, Signature>,
|
2021-04-14 14:48:14 +00:00
|
|
|
variables: &IndexMap<String, Value>,
|
2021-03-29 08:27:51 +00:00
|
|
|
) -> Result<Value, ShellError> {
|
2021-06-23 07:21:39 +00:00
|
|
|
let tag = Tag::unknown();
|
2021-03-29 08:27:51 +00:00
|
|
|
|
|
|
|
let mut scope_dict = TaggedDictBuilder::new(&tag);
|
|
|
|
|
2021-04-12 02:38:47 +00:00
|
|
|
let mut aliases_dict = TaggedDictBuilder::new(&tag);
|
2021-03-29 08:27:51 +00:00
|
|
|
for v in aliases.iter() {
|
|
|
|
let values = v.1.clone();
|
|
|
|
let mut vec = Vec::new();
|
|
|
|
|
|
|
|
for k in values.iter() {
|
|
|
|
vec.push(k.to_string());
|
|
|
|
}
|
|
|
|
|
|
|
|
let alias = vec.join(" ");
|
2021-04-12 02:38:47 +00:00
|
|
|
|
|
|
|
aliases_dict.insert_untagged(v.0, UntaggedValue::string(alias));
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut commands_dict = TaggedDictBuilder::new(&tag);
|
|
|
|
for (name, signature) in commands.iter() {
|
|
|
|
commands_dict.insert_untagged(name, UntaggedValue::string(&signature.allowed().join(" ")))
|
2021-03-29 08:27:51 +00:00
|
|
|
}
|
|
|
|
|
2021-04-15 19:02:08 +00:00
|
|
|
let var_list: Vec<Value> = variables
|
|
|
|
.iter()
|
|
|
|
.map(|var| {
|
|
|
|
let mut entries: IndexMap<String, Value> = IndexMap::new();
|
|
|
|
let name = var.0.trim_start_matches('$');
|
|
|
|
entries.insert(
|
|
|
|
"name".to_string(),
|
|
|
|
UntaggedValue::string(name).into_value(&tag),
|
|
|
|
);
|
|
|
|
entries.insert(
|
|
|
|
"value".to_string(),
|
|
|
|
UntaggedValue::string(var.1.convert_to_string()).into_value(&tag),
|
|
|
|
);
|
|
|
|
entries.insert(
|
|
|
|
"type".to_string(),
|
|
|
|
UntaggedValue::string(ShellTypeName::type_name(&var.1)).into_value(&tag),
|
|
|
|
);
|
|
|
|
UntaggedValue::Row(Dictionary { entries }).into_value(&tag)
|
|
|
|
})
|
|
|
|
.collect();
|
2021-04-14 14:48:14 +00:00
|
|
|
|
2021-04-12 02:38:47 +00:00
|
|
|
scope_dict.insert_value("aliases", aliases_dict.into_value());
|
|
|
|
|
|
|
|
scope_dict.insert_value("commands", commands_dict.into_value());
|
|
|
|
|
2021-04-15 19:02:08 +00:00
|
|
|
scope_dict.insert_value("variables", UntaggedValue::Table(var_list).into_value(&tag));
|
2021-04-14 14:48:14 +00:00
|
|
|
|
2021-03-29 08:27:51 +00:00
|
|
|
Ok(scope_dict.into_value())
|
|
|
|
}
|