Begin directory contrib docs and split commands (#3650)

* Begin directory contrib docs and split commands

* Fix unused import warning
This commit is contained in:
JT
2021-06-19 12:06:44 +12:00
committed by GitHub
parent 4140834e4c
commit a74d05061d
261 changed files with 794 additions and 808 deletions

View File

@ -11,37 +11,37 @@ version = "0.32.1"
doctest = false
[dependencies]
nu-completion = { version = "0.32.1", path = "../nu-completion" }
nu-command = { version = "0.32.1", path = "../nu-command" }
nu-data = { version = "0.32.1", path = "../nu-data" }
nu-engine = { version = "0.32.1", path = "../nu-engine" }
nu-errors = { version = "0.32.1", path = "../nu-errors" }
nu-json = { version = "0.32.1", path = "../nu-json" }
nu-parser = { version = "0.32.1", path = "../nu-parser" }
nu-plugin = { version = "0.32.1", path = "../nu-plugin" }
nu-protocol = { version = "0.32.1", path = "../nu-protocol" }
nu-source = { version = "0.32.1", path = "../nu-source" }
nu-stream = { version = "0.32.1", path = "../nu-stream" }
nu-table = { version = "0.32.1", path = "../nu-table" }
nu-test-support = { version = "0.32.1", path = "../nu-test-support" }
nu-value-ext = { version = "0.32.1", path = "../nu-value-ext" }
nu-ansi-term = { version = "0.32.1", path = "../nu-ansi-term" }
nu-pretty-hex = { version = "0.32.1", path = "../nu-pretty-hex" }
nu-completion = { version="0.32.1", path="../nu-completion" }
nu-command = { version="0.32.1", path="../nu-command" }
nu-data = { version="0.32.1", path="../nu-data" }
nu-engine = { version="0.32.1", path="../nu-engine" }
nu-errors = { version="0.32.1", path="../nu-errors" }
nu-json = { version="0.32.1", path="../nu-json" }
nu-parser = { version="0.32.1", path="../nu-parser" }
nu-plugin = { version="0.32.1", path="../nu-plugin" }
nu-protocol = { version="0.32.1", path="../nu-protocol" }
nu-source = { version="0.32.1", path="../nu-source" }
nu-stream = { version="0.32.1", path="../nu-stream" }
nu-table = { version="0.32.1", path="../nu-table" }
nu-test-support = { version="0.32.1", path="../nu-test-support" }
nu-value-ext = { version="0.32.1", path="../nu-value-ext" }
nu-ansi-term = { version="0.32.1", path="../nu-ansi-term" }
nu-pretty-hex = { version="0.32.1", path="../nu-pretty-hex" }
Inflector = "0.11"
arboard = { version = "1.1.0", optional = true }
arboard = { version="1.1.0", optional=true }
async-recursion = "0.3.2"
async-trait = "0.1.42"
base64 = "0.13.0"
bigdecimal = { version = "0.2.0", features = ["serde"] }
bigdecimal = { version="0.2.0", features=["serde"] }
byte-unit = "4.0.9"
bytes = "1.0.1"
calamine = "0.17.0"
chrono = { version = "0.4.19", features = ["serde"] }
chrono = { version="0.4.19", features=["serde"] }
chrono-tz = "0.5.3"
codespan-reporting = "0.11.0"
csv = "1.1.5"
ctrlc = { version = "3.1.7", optional = true }
ctrlc = { version="3.1.7", optional=true }
derive-new = "0.5.8"
directories-next = "2.0.0"
dirs-next = "2.0.0"
@ -51,25 +51,23 @@ eml-parser = "0.1.0"
encoding_rs = "0.8.28"
filesize = "0.2.0"
fs_extra = "1.2.0"
futures = { version = "0.3.12", features = ["compat", "io-compat"] }
futures = { version="0.3.12", features=["compat", "io-compat"] }
futures-util = "0.3.12"
futures_codec = "0.4.1"
getset = "0.1.1"
glob = "0.3.0"
htmlescape = "0.3.1"
ical = "0.7.0"
indexmap = { version = "1.6.1", features = ["serde-1"] }
itertools = "0.10.0"
lazy_static = "1.*"
indexmap = { version="1.6.1", features=["serde-1"] }
log = "0.4.14"
pretty_env_logger = "0.4.0"
meval = "0.2.0"
num-bigint = { version = "0.3.1", features = ["serde"] }
num-format = { version = "0.4.0", features = ["with-num-bigint"] }
num-bigint = { version="0.3.1", features=["serde"] }
num-format = { version="0.4.0", features=["with-num-bigint"] }
num-traits = "0.2.14"
parking_lot = "0.11.1"
pin-utils = "0.1.0"
ptree = { version = "0.3.1", optional = true }
ptree = { version="0.3.1", optional=true }
query_interface = "0.3.5"
quick-xml = "0.21.0"
rand = "0.8.3"
@ -77,8 +75,8 @@ rayon = "1.5.0"
regex = "1.4.3"
roxmltree = "0.14.0"
rust-embed = "5.9.0"
rustyline = { version = "8.1.0", optional = true }
serde = { version = "1.0.123", features = ["derive"] }
rustyline = { version="8.1.0", optional=true }
serde = { version="1.0.123", features=["derive"] }
serde_bytes = "0.11.5"
serde_ini = "0.2.0"
serde_json = "1.0.61"
@ -90,18 +88,18 @@ strip-ansi-escapes = "0.1.0"
sxd-document = "0.3.2"
sxd-xpath = "0.4.2"
tempfile = "3.2.0"
term = { version = "0.7.0", optional = true }
term = { version="0.7.0", optional=true }
term_size = "0.3.2"
termcolor = "1.1.2"
titlecase = "1.1.0"
toml = "0.5.8"
trash = { version = "1.3.0", optional = true }
trash = { version="1.3.0", optional=true }
unicode-segmentation = "1.7.1"
url = "2.1.1"
uuid_crate = { package = "uuid", version = "0.8.2", features = ["v4"], optional = true }
which = { version = "4.0.2", optional = true }
zip = { version = "0.5.9", optional = true }
shadow-rs = { version = "0.5", default-features = false, optional = true }
uuid_crate = { package="uuid", version="0.8.2", features=["v4"], optional=true }
which = { version="4.0.2", optional=true }
zip = { version="0.5.9", optional=true }
shadow-rs = { version="0.5", default-features=false, optional=true }
[target.'cfg(unix)'.dependencies]
umask = "1.0.0"

4
crates/nu-cli/README.md Normal file
View File

@ -0,0 +1,4 @@
* nu-cli
This crate provides the fundamental needs when creating the Nushell interactive REPL. In it, you'll find features for interacting with the line editor (the piece which writes the prompt and takes input from the user), keybindings, handlers for the commandline arguments passed to the REPL as it starts up, and more.

View File

@ -5,7 +5,7 @@ mod options_parser;
pub use options::{CliOptions, NuScript, Options};
use options_parser::{NuParser, OptionsParser};
use nu_command::{commands::nu::Nu, utils::test_bins as binaries};
use nu_command::{commands::NuSignature as Nu, utils::test_bins as binaries};
use nu_engine::{get_full_help, EvaluationContext};
use nu_errors::ShellError;
use nu_protocol::hir::{Call, Expression, SpannedExpression, Synthetic};
@ -58,7 +58,7 @@ impl App {
if self.version() {
let context = self.parser.context();
let stream = nu_command::commands::version::version(nu_engine::CommandArgs {
let stream = nu_command::commands::version(nu_engine::CommandArgs {
context: context.clone(),
call_info: nu_engine::UnevaluatedCallInfo {
args: Call::new(

View File

@ -1,6 +1,6 @@
use super::Options;
use nu_command::commands::nu::{self, Nu};
use nu_command::commands::{loglevels, testbins, NuSignature as Nu};
use nu_command::commands::{Autoview, Pivot, Table, Version as NuVersion};
use nu_engine::{whole_stream_command, EvaluationContext};
use nu_errors::ShellError;
@ -72,7 +72,7 @@ impl OptionsParser for NuParser {
.map(|v| match k.as_ref() {
"testbin" => {
if let Ok(name) = v.as_string() {
if nu::testbins().iter().any(|n| name == *n) {
if testbins().iter().any(|n| name == *n) {
Some(v)
} else {
Some(
@ -90,7 +90,7 @@ impl OptionsParser for NuParser {
}
"loglevel" => {
if let Ok(name) = v.as_string() {
if nu::loglevels().iter().any(|n| name == *n) {
if loglevels().iter().any(|n| name == *n) {
Some(v)
} else {
Some(

View File

@ -1,5 +1,3 @@
use super::Nu;
use crate::line_editor::configure_ctrl_c;
use nu_ansi_term::Color;
use nu_engine::{maybe_print_errors, run_block, script::run_script_standalone, EvaluationContext};
@ -150,7 +148,7 @@ pub fn cli(
if !skip_welcome_message {
println!(
"Welcome to Nushell {} (type 'help' for more info)",
Nu::version()
nu_command::commands::core_version()
);
}

View File

@ -1,6 +0,0 @@
use crate::prelude::*;
use nu_errors::ShellError;
pub(crate) trait RenderView {
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError>;
}

View File

@ -1,8 +1,3 @@
#![recursion_limit = "2048"]
#[macro_use]
mod prelude;
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
@ -11,12 +6,11 @@ extern crate quickcheck_macros;
mod app;
mod cli;
mod format;
#[cfg(feature = "rustyline-support")]
mod keybinding;
mod line_editor;
#[cfg(feature = "rustyline-support")]
mod shell;
pub mod types;
#[cfg(feature = "rustyline-support")]
pub use crate::cli::cli;
@ -25,8 +19,7 @@ pub use crate::app::App;
pub use crate::cli::{parse_and_eval, register_plugins, run_script_file};
pub use nu_command::{
commands::default_context::create_default_context, commands::nu as Nu,
commands::Version as NuVersion,
commands::NuSignature as Nu, commands::Version as NuVersion, create_default_context,
};
pub use nu_data::config;
pub use nu_data::dict::TaggedListBuilder;

View File

@ -1,8 +1,9 @@
use nu_engine::EvaluationContext;
use nu_errors::ShellError;
use std::error::Error;
#[allow(unused_imports)]
use crate::prelude::*;
use std::sync::atomic::Ordering;
#[allow(unused_imports)]
use nu_engine::script::LineResult;
@ -31,7 +32,7 @@ pub fn convert_rustyline_result_to_string(input: Result<String, ReadlineError>)
Err(ReadlineError::Interrupted) => LineResult::CtrlC,
Err(ReadlineError::Eof) => LineResult::CtrlD,
Err(err) => {
outln!("Error: {:?}", err);
eprintln!("Error: {:?}", err);
LineResult::Break
}
}

View File

@ -1,42 +0,0 @@
#[macro_export]
macro_rules! return_err {
($expr:expr) => {
match $expr {
Err(_) => return,
Ok(expr) => expr,
};
};
}
#[macro_export]
macro_rules! trace_out_stream {
(target: $target:tt, $desc:tt = $expr:expr) => {{
if log::log_enabled!(target: $target, log::Level::Trace) {
let objects = $expr.inspect(move |o| {
trace!(
target: $target,
"{} = {}",
$desc,
match o {
Err(err) => format!("{:?}", err),
Ok(value) => value.display(),
}
);
});
nu_stream::OutputStream::new(objects)
} else {
$expr
}
}};
}
pub(crate) use nu_engine::Host;
#[allow(unused_imports)]
pub(crate) use nu_errors::ShellError;
#[allow(unused_imports)]
pub(crate) use nu_protocol::outln;
#[allow(unused_imports)]
pub(crate) use nu_value_ext::ValueExt;
#[allow(unused_imports)]
pub(crate) use std::sync::atomic::Ordering;

View File

@ -1,7 +1,212 @@
#![allow(clippy::module_inception)]
use nu_ansi_term::Color;
use nu_completion::NuCompleter;
use nu_engine::{DefaultPalette, EvaluationContext, Painter};
use nu_source::{Tag, Tagged};
use std::borrow::Cow::{self, Owned};
#[cfg(feature = "rustyline-support")]
pub(crate) mod helper;
pub struct Helper {
completer: NuCompleter,
hinter: Option<rustyline::hint::HistoryHinter>,
context: EvaluationContext,
pub colored_prompt: String,
validator: NuValidator,
}
#[cfg(feature = "rustyline-support")]
pub(crate) use helper::Helper;
impl Helper {
pub(crate) fn new(
context: EvaluationContext,
hinter: Option<rustyline::hint::HistoryHinter>,
) -> Helper {
Helper {
completer: NuCompleter {},
hinter,
context,
colored_prompt: String::new(),
validator: NuValidator {},
}
}
}
struct CompletionContext<'a>(&'a EvaluationContext);
impl<'a> nu_completion::CompletionContext for CompletionContext<'a> {
fn signature_registry(&self) -> &dyn nu_parser::ParserScope {
&self.0.scope
}
}
pub struct CompletionSuggestion(nu_completion::Suggestion);
impl rustyline::completion::Candidate for CompletionSuggestion {
fn display(&self) -> &str {
&self.0.display
}
fn replacement(&self) -> &str {
&self.0.replacement
}
}
impl rustyline::completion::Completer for Helper {
type Candidate = CompletionSuggestion;
fn complete(
&self,
line: &str,
pos: usize,
_ctx: &rustyline::Context<'_>,
) -> Result<(usize, Vec<Self::Candidate>), rustyline::error::ReadlineError> {
let ctx = CompletionContext(&self.context);
let (position, suggestions) = self.completer.complete(line, pos, &ctx);
let suggestions = suggestions.into_iter().map(CompletionSuggestion).collect();
Ok((position, suggestions))
}
fn update(&self, line: &mut rustyline::line_buffer::LineBuffer, start: usize, elected: &str) {
let end = line.pos();
line.replace(start..end, elected)
}
}
impl rustyline::hint::Hinter for Helper {
type Hint = String;
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
self.hinter.as_ref().and_then(|h| h.hint(line, pos, ctx))
}
}
impl rustyline::highlight::Highlighter for Helper {
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
default: bool,
) -> Cow<'b, str> {
use std::borrow::Cow::Borrowed;
if default {
Borrowed(&self.colored_prompt)
} else {
Borrowed(prompt)
}
}
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
Owned(Color::DarkGray.prefix().to_string() + hint + nu_ansi_term::ansi::RESET)
}
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
let cfg = &self.context.configs().lock();
if let Some(palette) = &cfg.syntax_config {
Painter::paint_string(line, &self.context.scope, palette)
} else {
Painter::paint_string(line, &self.context.scope, &DefaultPalette {})
}
}
fn highlight_char(&self, _line: &str, _pos: usize) -> bool {
true
}
}
impl rustyline::validate::Validator for Helper {
fn validate(
&self,
ctx: &mut rustyline::validate::ValidationContext,
) -> rustyline::Result<rustyline::validate::ValidationResult> {
self.validator.validate(ctx)
}
fn validate_while_typing(&self) -> bool {
self.validator.validate_while_typing()
}
}
struct NuValidator {}
impl rustyline::validate::Validator for NuValidator {
fn validate(
&self,
ctx: &mut rustyline::validate::ValidationContext,
) -> rustyline::Result<rustyline::validate::ValidationResult> {
let src = ctx.input();
let (tokens, err) = nu_parser::lex(src, 0);
if let Some(err) = err {
if let nu_errors::ParseErrorReason::Eof { .. } = err.reason() {
return Ok(rustyline::validate::ValidationResult::Incomplete);
}
}
let (_, err) = nu_parser::parse_block(tokens);
if let Some(err) = err {
if let nu_errors::ParseErrorReason::Eof { .. } = err.reason() {
return Ok(rustyline::validate::ValidationResult::Incomplete);
}
}
Ok(rustyline::validate::ValidationResult::Valid(None))
}
}
#[allow(unused)]
fn vec_tag<T>(input: Vec<Tagged<T>>) -> Option<Tag> {
let mut iter = input.iter();
let first = iter.next()?.tag.clone();
let last = iter.last();
Some(match last {
None => first,
Some(last) => first.until(&last.tag),
})
}
impl rustyline::Helper for Helper {}
#[cfg(test)]
mod tests {
use super::*;
use nu_engine::EvaluationContext;
use rustyline::completion::Completer;
use rustyline::line_buffer::LineBuffer;
#[ignore]
#[test]
fn closing_quote_should_replaced() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 1);
let helper = Helper::new(EvaluationContext::basic(), None);
helper.update(&mut buffer, "cd ".len(), replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
#[ignore]
#[test]
fn replacement_with_cursor_in_text() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 30);
let helper = Helper::new(EvaluationContext::basic(), None);
helper.update(&mut buffer, "cd ".len(), replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
}

View File

@ -1,212 +0,0 @@
use nu_ansi_term::Color;
use nu_completion::NuCompleter;
use nu_engine::{DefaultPalette, EvaluationContext, Painter};
use nu_source::{Tag, Tagged};
use std::borrow::Cow::{self, Owned};
pub struct Helper {
completer: NuCompleter,
hinter: Option<rustyline::hint::HistoryHinter>,
context: EvaluationContext,
pub colored_prompt: String,
validator: NuValidator,
}
impl Helper {
pub(crate) fn new(
context: EvaluationContext,
hinter: Option<rustyline::hint::HistoryHinter>,
) -> Helper {
Helper {
completer: NuCompleter {},
hinter,
context,
colored_prompt: String::new(),
validator: NuValidator {},
}
}
}
struct CompletionContext<'a>(&'a EvaluationContext);
impl<'a> nu_completion::CompletionContext for CompletionContext<'a> {
fn signature_registry(&self) -> &dyn nu_parser::ParserScope {
&self.0.scope
}
}
pub struct CompletionSuggestion(nu_completion::Suggestion);
impl rustyline::completion::Candidate for CompletionSuggestion {
fn display(&self) -> &str {
&self.0.display
}
fn replacement(&self) -> &str {
&self.0.replacement
}
}
impl rustyline::completion::Completer for Helper {
type Candidate = CompletionSuggestion;
fn complete(
&self,
line: &str,
pos: usize,
_ctx: &rustyline::Context<'_>,
) -> Result<(usize, Vec<Self::Candidate>), rustyline::error::ReadlineError> {
let ctx = CompletionContext(&self.context);
let (position, suggestions) = self.completer.complete(line, pos, &ctx);
let suggestions = suggestions.into_iter().map(CompletionSuggestion).collect();
Ok((position, suggestions))
}
fn update(&self, line: &mut rustyline::line_buffer::LineBuffer, start: usize, elected: &str) {
let end = line.pos();
line.replace(start..end, elected)
}
}
impl rustyline::hint::Hinter for Helper {
type Hint = String;
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
self.hinter.as_ref().and_then(|h| h.hint(line, pos, ctx))
}
}
impl rustyline::highlight::Highlighter for Helper {
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
default: bool,
) -> Cow<'b, str> {
use std::borrow::Cow::Borrowed;
if default {
Borrowed(&self.colored_prompt)
} else {
Borrowed(prompt)
}
}
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
Owned(Color::DarkGray.prefix().to_string() + hint + nu_ansi_term::ansi::RESET)
}
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
let cfg = &self.context.configs().lock();
if let Some(palette) = &cfg.syntax_config {
Painter::paint_string(line, &self.context.scope, palette)
} else {
Painter::paint_string(line, &self.context.scope, &DefaultPalette {})
}
}
fn highlight_char(&self, _line: &str, _pos: usize) -> bool {
true
}
}
impl rustyline::validate::Validator for Helper {
fn validate(
&self,
ctx: &mut rustyline::validate::ValidationContext,
) -> rustyline::Result<rustyline::validate::ValidationResult> {
self.validator.validate(ctx)
}
fn validate_while_typing(&self) -> bool {
self.validator.validate_while_typing()
}
}
struct NuValidator {}
impl rustyline::validate::Validator for NuValidator {
fn validate(
&self,
ctx: &mut rustyline::validate::ValidationContext,
) -> rustyline::Result<rustyline::validate::ValidationResult> {
let src = ctx.input();
let (tokens, err) = nu_parser::lex(src, 0);
if let Some(err) = err {
if let nu_errors::ParseErrorReason::Eof { .. } = err.reason() {
return Ok(rustyline::validate::ValidationResult::Incomplete);
}
}
let (_, err) = nu_parser::parse_block(tokens);
if let Some(err) = err {
if let nu_errors::ParseErrorReason::Eof { .. } = err.reason() {
return Ok(rustyline::validate::ValidationResult::Incomplete);
}
}
Ok(rustyline::validate::ValidationResult::Valid(None))
}
}
#[allow(unused)]
fn vec_tag<T>(input: Vec<Tagged<T>>) -> Option<Tag> {
let mut iter = input.iter();
let first = iter.next()?.tag.clone();
let last = iter.last();
Some(match last {
None => first,
Some(last) => first.until(&last.tag),
})
}
impl rustyline::Helper for Helper {}
#[cfg(test)]
mod tests {
use super::*;
use nu_engine::EvaluationContext;
use rustyline::completion::Completer;
use rustyline::line_buffer::LineBuffer;
#[ignore]
#[test]
fn closing_quote_should_replaced() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 1);
let helper = Helper::new(EvaluationContext::basic(), None);
helper.update(&mut buffer, "cd ".len(), replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
#[ignore]
#[test]
fn replacement_with_cursor_in_text() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 30);
let helper = Helper::new(EvaluationContext::basic(), None);
helper.update(&mut buffer, "cd ".len(), replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
}

View File

@ -1 +0,0 @@
pub(crate) mod deduction;

File diff suppressed because it is too large Load Diff