forked from extern/nushell
Remove unused help shell. Slight cleanup and improvement. (#3258)
This commit is contained in:
parent
28e1a7915d
commit
1c941557c3
@ -89,24 +89,7 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||||||
let location_string = location.display().to_string();
|
let location_string = location.display().to_string();
|
||||||
let location_clone = location_string.clone();
|
let location_clone = location_string.clone();
|
||||||
|
|
||||||
if location_string.starts_with("help") {
|
if location.is_dir() {
|
||||||
let spec = location_string.split(':').collect::<Vec<&str>>();
|
|
||||||
|
|
||||||
if spec.len() == 2 {
|
|
||||||
let (_, command) = (spec[0], spec[1]);
|
|
||||||
|
|
||||||
if scope.has_command(command) {
|
|
||||||
return Ok(OutputStream::one(ReturnSuccess::action(
|
|
||||||
CommandAction::EnterHelpShell(
|
|
||||||
UntaggedValue::string(command).into_value(Tag::unknown()),
|
|
||||||
),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::action(
|
|
||||||
CommandAction::EnterHelpShell(UntaggedValue::nothing().into_value(Tag::unknown())),
|
|
||||||
)))
|
|
||||||
} else if location.is_dir() {
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::action(
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
CommandAction::EnterShell(location_clone),
|
CommandAction::EnterShell(location_clone),
|
||||||
)))
|
)))
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_engine::command_dict;
|
use crate::TaggedListBuilder;
|
||||||
use nu_engine::documentation::generate_docs;
|
use nu_engine::documentation::generate_docs;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::{Command, WholeStreamCommand};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{
|
||||||
|
NamedType, PositionalType, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder,
|
||||||
|
UntaggedValue, Value,
|
||||||
|
};
|
||||||
|
use nu_source::Tag;
|
||||||
use nu_source::{SpannedItem, Tagged};
|
use nu_source::{SpannedItem, Tagged};
|
||||||
use nu_value_ext::ValueExt;
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
@ -208,6 +212,62 @@ You can also learn more at https://www.nushell.sh/book/"#;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Value {
|
||||||
|
let tag = tag.into();
|
||||||
|
|
||||||
|
let mut spec = TaggedDictBuilder::new(tag);
|
||||||
|
|
||||||
|
spec.insert_untagged("name", UntaggedValue::string(name));
|
||||||
|
spec.insert_untagged("type", UntaggedValue::string(ty));
|
||||||
|
spec.insert_untagged(
|
||||||
|
"required",
|
||||||
|
UntaggedValue::string(if required { "yes" } else { "no" }),
|
||||||
|
);
|
||||||
|
|
||||||
|
spec.into_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Value {
|
||||||
|
let tag = tag.into();
|
||||||
|
let mut sig = TaggedListBuilder::new(&tag);
|
||||||
|
|
||||||
|
for arg in signature.positional.iter() {
|
||||||
|
let is_required = matches!(arg.0, PositionalType::Mandatory(_, _));
|
||||||
|
|
||||||
|
sig.push_value(for_spec(arg.0.name(), "argument", is_required, &tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
if signature.rest_positional.is_some() {
|
||||||
|
let is_required = false;
|
||||||
|
sig.push_value(for_spec("rest", "argument", is_required, &tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (name, ty) in signature.named.iter() {
|
||||||
|
match ty.0 {
|
||||||
|
NamedType::Mandatory(_, _) => sig.push_value(for_spec(name, "flag", true, &tag)),
|
||||||
|
NamedType::Optional(_, _) => sig.push_value(for_spec(name, "flag", false, &tag)),
|
||||||
|
NamedType::Switch(_) => sig.push_value(for_spec(name, "switch", false, &tag)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sig.into_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_dict(command: Command, tag: impl Into<Tag>) -> Value {
|
||||||
|
let tag = tag.into();
|
||||||
|
|
||||||
|
let mut cmd_dict = TaggedDictBuilder::new(&tag);
|
||||||
|
|
||||||
|
cmd_dict.insert_untagged("name", UntaggedValue::string(command.name()));
|
||||||
|
|
||||||
|
cmd_dict.insert_untagged("type", UntaggedValue::string("Command"));
|
||||||
|
|
||||||
|
cmd_dict.insert_value("signature", signature_dict(command.signature(), tag));
|
||||||
|
cmd_dict.insert_untagged("usage", UntaggedValue::string(command.usage()));
|
||||||
|
|
||||||
|
cmd_dict.into_value()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Help;
|
use super::Help;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::utils::arguments::arguments;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::ShellTypeName;
|
use nu_protocol::ShellTypeName;
|
||||||
use nu_protocol::{
|
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
use nu_source::{Tag, Tagged};
|
use nu_source::{Tag, Tagged};
|
||||||
use nu_value_ext::ValueExt;
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ use num_traits::Num;
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Arguments {
|
struct Arguments {
|
||||||
rest: Vec<ColumnPath>,
|
rest: Vec<Value>,
|
||||||
radix: Option<Tagged<u32>>,
|
radix: Option<Tagged<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
Signature::build("str to-int")
|
Signature::build("str to-int")
|
||||||
.named("radix", SyntaxShape::Number, "radix of integer", Some('r'))
|
.named("radix", SyntaxShape::Number, "radix of integer", Some('r'))
|
||||||
.rest(
|
.rest(
|
||||||
SyntaxShape::ColumnPath,
|
SyntaxShape::Any,
|
||||||
"optionally convert text into integer by column paths",
|
"optionally convert text into integer by column paths",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -69,12 +68,11 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let (Arguments { rest, radix }, input) = args.process().await?;
|
let (Arguments { mut rest, radix }, input) = args.process().await?;
|
||||||
|
let (column_paths, _) = arguments(&mut rest)?;
|
||||||
|
|
||||||
let radix = radix.map(|r| r.item).unwrap_or(10);
|
let radix = radix.map(|r| r.item).unwrap_or(10);
|
||||||
|
|
||||||
let column_paths: Vec<ColumnPath> = rest;
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |v| {
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
use crate::TaggedListBuilder;
|
|
||||||
use nu_source::Tag;
|
|
||||||
|
|
||||||
use nu_protocol::{NamedType, PositionalType, Signature, TaggedDictBuilder, UntaggedValue, Value};
|
|
||||||
|
|
||||||
fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Value {
|
|
||||||
let tag = tag.into();
|
|
||||||
|
|
||||||
let mut spec = TaggedDictBuilder::new(tag);
|
|
||||||
|
|
||||||
spec.insert_untagged("name", UntaggedValue::string(name));
|
|
||||||
spec.insert_untagged("type", UntaggedValue::string(ty));
|
|
||||||
spec.insert_untagged(
|
|
||||||
"required",
|
|
||||||
UntaggedValue::string(if required { "yes" } else { "no" }),
|
|
||||||
);
|
|
||||||
|
|
||||||
spec.into_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Value {
|
|
||||||
let tag = tag.into();
|
|
||||||
let mut sig = TaggedListBuilder::new(&tag);
|
|
||||||
|
|
||||||
for arg in signature.positional.iter() {
|
|
||||||
let is_required = matches!(arg.0, PositionalType::Mandatory(_, _));
|
|
||||||
|
|
||||||
sig.push_value(for_spec(arg.0.name(), "argument", is_required, &tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
if signature.rest_positional.is_some() {
|
|
||||||
let is_required = false;
|
|
||||||
sig.push_value(for_spec("rest", "argument", is_required, &tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (name, ty) in signature.named.iter() {
|
|
||||||
match ty.0 {
|
|
||||||
NamedType::Mandatory(_, _) => sig.push_value(for_spec(name, "flag", true, &tag)),
|
|
||||||
NamedType::Optional(_, _) => sig.push_value(for_spec(name, "flag", false, &tag)),
|
|
||||||
NamedType::Switch(_) => sig.push_value(for_spec(name, "switch", false, &tag)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sig.into_value()
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
pub mod base;
|
pub mod base;
|
||||||
pub mod command;
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod dict;
|
pub mod dict;
|
||||||
pub mod keybinding;
|
pub mod keybinding;
|
||||||
|
@ -2,13 +2,12 @@ use crate::call_info::UnevaluatedCallInfo;
|
|||||||
use crate::command_args::RawCommandArgs;
|
use crate::command_args::RawCommandArgs;
|
||||||
use crate::evaluation_context::EvaluationContext;
|
use crate::evaluation_context::EvaluationContext;
|
||||||
use crate::filesystem::filesystem_shell::{FilesystemShell, FilesystemShellMode};
|
use crate::filesystem::filesystem_shell::{FilesystemShell, FilesystemShellMode};
|
||||||
use crate::shell::help_shell::HelpShell;
|
|
||||||
use crate::shell::value_shell::ValueShell;
|
use crate::shell::value_shell::ValueShell;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::{log_enabled, trace};
|
use log::{log_enabled, trace};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{ExternalRedirection, InternalCommand};
|
use nu_protocol::hir::{ExternalRedirection, InternalCommand};
|
||||||
use nu_protocol::{CommandAction, Primitive, ReturnSuccess, UntaggedValue, Value};
|
use nu_protocol::{CommandAction, ReturnSuccess, UntaggedValue, Value};
|
||||||
use nu_source::{PrettyDebug, Span, Tag};
|
use nu_source::{PrettyDebug, Span, Tag};
|
||||||
use nu_stream::{trace_stream, InputStream, ToInputStream};
|
use nu_stream::{trace_stream, InputStream, ToInputStream};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -127,38 +126,6 @@ pub(crate) async fn run_internal_command(
|
|||||||
InputStream::one(tagged_contents)
|
InputStream::one(tagged_contents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandAction::EnterHelpShell(value) => match value {
|
|
||||||
Value {
|
|
||||||
value: UntaggedValue::Primitive(Primitive::String(cmd)),
|
|
||||||
tag,
|
|
||||||
} => {
|
|
||||||
context.shell_manager.insert_at_current(Box::new(
|
|
||||||
match HelpShell::for_command(
|
|
||||||
UntaggedValue::string(cmd).into_value(tag),
|
|
||||||
&context.scope,
|
|
||||||
) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(err) => {
|
|
||||||
context.error(err);
|
|
||||||
return InputStream::empty();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
));
|
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
context.shell_manager.insert_at_current(Box::new(
|
|
||||||
match HelpShell::index(&context.scope) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(err) => {
|
|
||||||
context.error(err);
|
|
||||||
return InputStream::empty();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
));
|
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CommandAction::EnterValueShell(value) => {
|
CommandAction::EnterValueShell(value) => {
|
||||||
context
|
context
|
||||||
.shell_manager
|
.shell_manager
|
||||||
|
@ -58,6 +58,10 @@ impl Clone for FilesystemShell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FilesystemShell {
|
impl FilesystemShell {
|
||||||
|
fn is_cli(&self) -> bool {
|
||||||
|
matches!(&self.mode, FilesystemShellMode::Cli)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn basic(mode: FilesystemShellMode) -> Result<FilesystemShell, Error> {
|
pub fn basic(mode: FilesystemShellMode) -> Result<FilesystemShell, Error> {
|
||||||
let path = match std::env::current_dir() {
|
let path = match std::env::current_dir() {
|
||||||
Ok(path) => path,
|
Ok(path) => path,
|
||||||
@ -295,7 +299,7 @@ impl Shell for FilesystemShell {
|
|||||||
|
|
||||||
//Loading local configs in script mode, makes scripts behave different on different
|
//Loading local configs in script mode, makes scripts behave different on different
|
||||||
//filesystems and might therefore surprise users. That's why we only load them in cli mode.
|
//filesystems and might therefore surprise users. That's why we only load them in cli mode.
|
||||||
if self.mode == FilesystemShellMode::Cli {
|
if self.is_cli() {
|
||||||
match dunce::canonicalize(self.path()) {
|
match dunce::canonicalize(self.path()) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
trace!(
|
trace!(
|
||||||
|
@ -39,7 +39,6 @@ pub use crate::filesystem::path;
|
|||||||
pub use crate::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
|
pub use crate::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
|
||||||
pub use crate::print::maybe_print_errors;
|
pub use crate::print::maybe_print_errors;
|
||||||
pub use crate::runnable_context::RunnableContext;
|
pub use crate::runnable_context::RunnableContext;
|
||||||
pub use crate::shell::help_shell::{command_dict, HelpShell};
|
|
||||||
pub use crate::shell::painter::Painter;
|
pub use crate::shell::painter::Painter;
|
||||||
pub use crate::shell::palette::{DefaultPalette, Palette};
|
pub use crate::shell::palette::{DefaultPalette, Palette};
|
||||||
pub use crate::shell::shell_manager::ShellManager;
|
pub use crate::shell::shell_manager::ShellManager;
|
||||||
|
@ -1,252 +0,0 @@
|
|||||||
use crate::command_args::EvaluatedWholeStreamCommandArgs;
|
|
||||||
use crate::evaluate::scope::Scope;
|
|
||||||
use crate::maybe_text_codec::StringOrBinary;
|
|
||||||
use crate::shell::shell_args::{CdArgs, CopyArgs, LsArgs, MkdirArgs, MvArgs, RemoveArgs};
|
|
||||||
use crate::shell::Shell;
|
|
||||||
use crate::whole_stream_command::Command;
|
|
||||||
use encoding_rs::Encoding;
|
|
||||||
use futures::stream::BoxStream;
|
|
||||||
use nu_data::command::signature_dict;
|
|
||||||
use nu_errors::ShellError;
|
|
||||||
use nu_protocol::{
|
|
||||||
Primitive, ReturnSuccess, ShellTypeName, TaggedDictBuilder, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
use nu_source::Tagged;
|
|
||||||
use nu_source::{Span, SpannedItem, Tag};
|
|
||||||
use nu_stream::OutputStream;
|
|
||||||
use nu_value_ext::ValueExt;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub fn command_dict(command: Command, tag: impl Into<Tag>) -> Value {
|
|
||||||
let tag = tag.into();
|
|
||||||
|
|
||||||
let mut cmd_dict = TaggedDictBuilder::new(&tag);
|
|
||||||
|
|
||||||
cmd_dict.insert_untagged("name", UntaggedValue::string(command.name()));
|
|
||||||
|
|
||||||
cmd_dict.insert_untagged("type", UntaggedValue::string("Command"));
|
|
||||||
|
|
||||||
cmd_dict.insert_value("signature", signature_dict(command.signature(), tag));
|
|
||||||
cmd_dict.insert_untagged("usage", UntaggedValue::string(command.usage()));
|
|
||||||
|
|
||||||
cmd_dict.into_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct HelpShell {
|
|
||||||
pub(crate) path: String,
|
|
||||||
pub(crate) value: Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HelpShell {
|
|
||||||
pub fn index(scope: &Scope) -> Result<HelpShell, ShellError> {
|
|
||||||
let mut cmds = TaggedDictBuilder::new(Tag::unknown());
|
|
||||||
let mut specs = Vec::new();
|
|
||||||
|
|
||||||
for cmd in scope.get_command_names() {
|
|
||||||
if let Some(cmd_value) = scope.get_command(&cmd) {
|
|
||||||
let mut spec = TaggedDictBuilder::new(Tag::unknown());
|
|
||||||
let value = command_dict(cmd_value, Tag::unknown());
|
|
||||||
|
|
||||||
spec.insert_untagged("name", cmd);
|
|
||||||
spec.insert_untagged(
|
|
||||||
"description",
|
|
||||||
value
|
|
||||||
.get_data_by_key("usage".spanned_unknown())
|
|
||||||
.ok_or_else(|| {
|
|
||||||
ShellError::untagged_runtime_error(
|
|
||||||
"Internal error: expected to find usage",
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
.as_string()?,
|
|
||||||
);
|
|
||||||
spec.insert_value("details", value);
|
|
||||||
|
|
||||||
specs.push(spec.into_value());
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds.insert_untagged("help", UntaggedValue::Table(specs));
|
|
||||||
|
|
||||||
Ok(HelpShell {
|
|
||||||
path: "/help".to_string(),
|
|
||||||
value: cmds.into_value(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn for_command(cmd: Value, scope: &Scope) -> Result<HelpShell, ShellError> {
|
|
||||||
let mut sh = HelpShell::index(scope)?;
|
|
||||||
|
|
||||||
if let Value {
|
|
||||||
value: UntaggedValue::Primitive(Primitive::String(name)),
|
|
||||||
..
|
|
||||||
} = cmd
|
|
||||||
{
|
|
||||||
sh.set_path(format!("/help/{:}/details", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(sh)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn commands(&self) -> VecDeque<Value> {
|
|
||||||
let mut cmds = VecDeque::new();
|
|
||||||
let full_path = PathBuf::from(&self.path);
|
|
||||||
|
|
||||||
let mut viewed = self.value.clone();
|
|
||||||
let sep_string = std::path::MAIN_SEPARATOR.to_string();
|
|
||||||
let sep = OsStr::new(&sep_string);
|
|
||||||
|
|
||||||
for p in full_path.iter() {
|
|
||||||
match p {
|
|
||||||
x if x == sep => {}
|
|
||||||
step => {
|
|
||||||
let step: &str = &step.to_string_lossy().to_string();
|
|
||||||
let value = viewed.get_data_by_key(step.spanned_unknown());
|
|
||||||
if let Some(v) = value {
|
|
||||||
viewed = v.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match viewed {
|
|
||||||
Value {
|
|
||||||
value: UntaggedValue::Table(l),
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
for item in l {
|
|
||||||
cmds.push_back(item.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x => {
|
|
||||||
cmds.push_back(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Shell for HelpShell {
|
|
||||||
fn name(&self) -> String {
|
|
||||||
let anchor_name = self.value.anchor_name();
|
|
||||||
|
|
||||||
match anchor_name {
|
|
||||||
Some(x) => format!("{{{}}}", x),
|
|
||||||
None => format!("<{}>", self.value.type_name()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn homedir(&self) -> Option<PathBuf> {
|
|
||||||
#[cfg(feature = "dirs")]
|
|
||||||
{
|
|
||||||
dirs_next::home_dir()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "dirs"))]
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path(&self) -> String {
|
|
||||||
self.path.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pwd(&self, _: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(OutputStream::empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_path(&mut self, path: String) {
|
|
||||||
let _ = std::env::set_current_dir(&path);
|
|
||||||
self.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ls(
|
|
||||||
&self,
|
|
||||||
_args: LsArgs,
|
|
||||||
_name: Tag,
|
|
||||||
_ctrl_c: Arc<AtomicBool>,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let output = self
|
|
||||||
.commands()
|
|
||||||
.into_iter()
|
|
||||||
.map(ReturnSuccess::value)
|
|
||||||
.collect::<VecDeque<_>>();
|
|
||||||
Ok(output.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cd(&self, args: CdArgs, _name: Tag) -> Result<OutputStream, ShellError> {
|
|
||||||
let path = match args.path {
|
|
||||||
None => "/".to_string(),
|
|
||||||
Some(v) => {
|
|
||||||
let Tagged { item: target, .. } = v;
|
|
||||||
let mut cwd = PathBuf::from(&self.path);
|
|
||||||
|
|
||||||
if target == PathBuf::from("..") {
|
|
||||||
cwd.pop();
|
|
||||||
} else {
|
|
||||||
match target.to_str() {
|
|
||||||
Some(target) => match target.chars().next() {
|
|
||||||
Some(x) if x == '/' => cwd = PathBuf::from(target),
|
|
||||||
_ => cwd.push(target),
|
|
||||||
},
|
|
||||||
None => cwd.push(target),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cwd.to_string_lossy().to_string()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut stream = VecDeque::new();
|
|
||||||
stream.push_back(ReturnSuccess::change_cwd(path));
|
|
||||||
Ok(stream.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cp(&self, _args: CopyArgs, _name: Tag, _path: &str) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(OutputStream::empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mv(&self, _args: MvArgs, _name: Tag, _path: &str) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(OutputStream::empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mkdir(&self, _args: MkdirArgs, _name: Tag, _path: &str) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(OutputStream::empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rm(&self, _args: RemoveArgs, _name: Tag, _path: &str) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(OutputStream::empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open(
|
|
||||||
&self,
|
|
||||||
_path: &Path,
|
|
||||||
_name: Span,
|
|
||||||
_with_encoding: Option<&'static Encoding>,
|
|
||||||
) -> Result<BoxStream<'static, Result<StringOrBinary, ShellError>>, ShellError> {
|
|
||||||
Err(ShellError::unimplemented(
|
|
||||||
"open on help shell is not supported",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save(
|
|
||||||
&mut self,
|
|
||||||
_path: &Path,
|
|
||||||
_contents: &[u8],
|
|
||||||
_name: Span,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
Err(ShellError::unimplemented(
|
|
||||||
"save on help shell is not supported",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_interactive(&self) -> bool {
|
|
||||||
//Help shell is always interactive
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,6 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub(crate) mod help_shell;
|
|
||||||
pub(crate) mod painter;
|
pub(crate) mod painter;
|
||||||
pub(crate) mod palette;
|
pub(crate) mod palette;
|
||||||
pub(crate) mod shell_args;
|
pub(crate) mod shell_args;
|
||||||
|
@ -18,8 +18,6 @@ pub enum CommandAction {
|
|||||||
AutoConvert(Value, String),
|
AutoConvert(Value, String),
|
||||||
/// Enter a value shell, one that allows exploring inside of a Value
|
/// Enter a value shell, one that allows exploring inside of a Value
|
||||||
EnterValueShell(Value),
|
EnterValueShell(Value),
|
||||||
/// Enter the help shell, which allows exploring the help system
|
|
||||||
EnterHelpShell(Value),
|
|
||||||
/// Add plugins from path given
|
/// Add plugins from path given
|
||||||
AddPlugins(String),
|
AddPlugins(String),
|
||||||
/// Unload the config specified by PathBuf if present
|
/// Unload the config specified by PathBuf if present
|
||||||
@ -50,7 +48,6 @@ impl PrettyDebug for CommandAction {
|
|||||||
DbgDocBldr::typed("enter shell", DbgDocBldr::description(s))
|
DbgDocBldr::typed("enter shell", DbgDocBldr::description(s))
|
||||||
}
|
}
|
||||||
CommandAction::EnterValueShell(v) => DbgDocBldr::typed("enter value shell", v.pretty()),
|
CommandAction::EnterValueShell(v) => DbgDocBldr::typed("enter value shell", v.pretty()),
|
||||||
CommandAction::EnterHelpShell(v) => DbgDocBldr::typed("enter help shell", v.pretty()),
|
|
||||||
CommandAction::AddPlugins(..) => DbgDocBldr::description("add plugins"),
|
CommandAction::AddPlugins(..) => DbgDocBldr::description("add plugins"),
|
||||||
CommandAction::PreviousShell => DbgDocBldr::description("previous shell"),
|
CommandAction::PreviousShell => DbgDocBldr::description("previous shell"),
|
||||||
CommandAction::NextShell => DbgDocBldr::description("next shell"),
|
CommandAction::NextShell => DbgDocBldr::description("next shell"),
|
||||||
|
3
tests/fixtures/playground/config/startup.toml
vendored
Normal file
3
tests/fixtures/playground/config/startup.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
skip_welcome_message = true
|
||||||
|
|
||||||
|
startup = ["def hello-world [] { echo 'Nu World' }"]
|
@ -1,11 +1,28 @@
|
|||||||
|
use nu_test_support::fs::AbsolutePath;
|
||||||
|
use nu_test_support::playground::{says, Playground};
|
||||||
use nu_test_support::{nu, pipeline};
|
use nu_test_support::{nu, pipeline};
|
||||||
|
|
||||||
|
use hamcrest2::assert_that;
|
||||||
|
use hamcrest2::prelude::*;
|
||||||
|
|
||||||
#[cfg(feature = "directories-support")]
|
#[cfg(feature = "directories-support")]
|
||||||
#[cfg(feature = "which-support")]
|
#[cfg(feature = "which-support")]
|
||||||
mod environment;
|
mod environment;
|
||||||
|
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
|
|
||||||
|
#[should_panic]
|
||||||
|
#[test]
|
||||||
|
fn runs_configuration_startup_commands() {
|
||||||
|
Playground::setup("init_config_startup_commands_test", |dirs, nu| {
|
||||||
|
let file = AbsolutePath::new(dirs.test().join("startup.toml"));
|
||||||
|
|
||||||
|
nu.with_config(&file);
|
||||||
|
|
||||||
|
assert_that!(nu.pipeline("hello-world"), says().to_stdout("Nu World"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plugins_are_declared_with_wix() {
|
fn plugins_are_declared_with_wix() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
Loading…
Reference in New Issue
Block a user