mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Update rustyline to latest (#2565)
* Update rustyline to latest * Go ahead and use rustyline for testing
This commit is contained in:
parent
1dc8f3300e
commit
8453261211
13 changed files with 372 additions and 313 deletions
|
@ -71,7 +71,7 @@ steps:
|
|||
- bash: RUSTFLAGS="-D warnings" cargo clippy --all -- -D clippy::unwrap_used
|
||||
condition: eq(variables['style'], 'canary')
|
||||
displayName: Check clippy lints
|
||||
- bash: RUSTFLAGS="-D warnings" cargo test --all --no-default-features
|
||||
- bash: RUSTFLAGS="-D warnings" cargo test --all --no-default-features --features=rustyline-support
|
||||
condition: eq(variables['style'], 'minimal')
|
||||
displayName: Run tests
|
||||
- bash: RUSTFLAGS="-D warnings" cargo test --all --features=extra
|
||||
|
|
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -987,7 +987,7 @@ version = "3.1.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0b676fa23f995faf587496dcd1c80fead847ed58d2da52ac1caca9a72790dd2"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"nix 0.17.0",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
|
@ -1834,7 +1834,7 @@ dependencies = [
|
|||
"lazy_static 1.4.0",
|
||||
"libc",
|
||||
"mach",
|
||||
"nix",
|
||||
"nix 0.17.0",
|
||||
"pin-utils",
|
||||
"uom 0.28.0",
|
||||
"winapi 0.3.9",
|
||||
|
@ -1921,7 +1921,7 @@ dependencies = [
|
|||
"heim-runtime",
|
||||
"libc",
|
||||
"macaddr",
|
||||
"nix",
|
||||
"nix 0.17.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2796,6 +2796,18 @@ dependencies = [
|
|||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.14"
|
||||
|
@ -4503,16 +4515,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustyline"
|
||||
version = "6.2.0"
|
||||
version = "6.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3358c21cbbc1a751892528db4e1de4b7a2b6a73f001e215aaba97d712cfa9777"
|
||||
checksum = "6f0d5e7b0219a3eadd5439498525d4765c59b7c993ef0c12244865cd2d988413"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-next",
|
||||
"libc",
|
||||
"log 0.4.11",
|
||||
"memchr",
|
||||
"nix",
|
||||
"nix 0.18.0",
|
||||
"scopeguard",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
|
|
|
@ -75,6 +75,7 @@ default = [
|
|||
"ptree-support",
|
||||
"term-support",
|
||||
"uuid-support",
|
||||
"rustyline-support",
|
||||
"match",
|
||||
"post",
|
||||
"fetch",
|
||||
|
@ -105,6 +106,7 @@ ctrlc-support = ["nu-cli/ctrlc"]
|
|||
directories-support = ["nu-cli/directories", "nu-cli/dirs", "nu-data/directories", "nu-data/dirs"]
|
||||
git-support = ["nu-cli/git2"]
|
||||
ptree-support = ["nu-cli/ptree"]
|
||||
rustyline-support = ["nu-cli/rustyline-support"]
|
||||
term-support = ["nu-cli/term"]
|
||||
trash-support = ["nu-cli/trash-support"]
|
||||
uuid-support = ["nu-cli/uuid_crate"]
|
||||
|
|
|
@ -67,7 +67,7 @@ rand = "0.7.3"
|
|||
regex = "1.3.9"
|
||||
roxmltree = "0.13.0"
|
||||
rust-embed = "5.6.0"
|
||||
rustyline = "6.2.0"
|
||||
rustyline = {version = "6.3.0", optional = true}
|
||||
serde = {version = "1.0.115", features = ["derive"]}
|
||||
serde-hjson = "0.9.1"
|
||||
serde_bytes = "0.11.5"
|
||||
|
@ -88,17 +88,17 @@ uuid_crate = { package = "uuid", version = "0.8.1", features = ["v4"], optional
|
|||
which = {version = "4.0.2", optional = true}
|
||||
zip = {version = "0.5.7", optional = true}
|
||||
|
||||
Inflector = "0.11"
|
||||
clipboard = {version = "0.5.0", optional = true}
|
||||
encoding_rs = "0.8.24"
|
||||
quick-xml = "0.18.1"
|
||||
rayon = "1.4.0"
|
||||
trash = {version = "1.1.1", optional = true}
|
||||
url = "2.1.1"
|
||||
Inflector = "0.11"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
users = "0.10.0"
|
||||
umask = "1.0.0"
|
||||
users = "0.10.0"
|
||||
|
||||
# TODO this will be possible with new dependency resolver
|
||||
# (currently on nightly behind -Zfeatures=itarget):
|
||||
|
@ -114,12 +114,12 @@ version = "0.23.1"
|
|||
[build-dependencies]
|
||||
git2 = {version = "0.13.11", optional = true}
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "0.9.2"
|
||||
quickcheck_macros = "0.9.1"
|
||||
|
||||
[features]
|
||||
clipboard-cli = ["clipboard"]
|
||||
rustyline-support = ["rustyline"]
|
||||
stable = []
|
||||
trash-support = ["trash"]
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::commands::classified::block::run_block;
|
||||
use crate::commands::classified::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
|
||||
use crate::context::Context;
|
||||
use crate::git::current_branch;
|
||||
use crate::path::canonicalize;
|
||||
use crate::prelude::*;
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
use crate::shell::Helper;
|
||||
use crate::EnvironmentSyncer;
|
||||
use futures_codec::FramedRead;
|
||||
|
@ -12,9 +12,14 @@ use nu_protocol::hir::{ClassifiedCommand, Expression, InternalCommand, Literal,
|
|||
use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue, Value};
|
||||
|
||||
use log::{debug, trace};
|
||||
use rustyline::config::{ColorMode, CompletionType, Config};
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::{self, config::Configurer, At, Cmd, Editor, KeyPress, Movement, Word};
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
use rustyline::{
|
||||
self,
|
||||
config::Configurer,
|
||||
config::{ColorMode, CompletionType, Config},
|
||||
error::ReadlineError,
|
||||
At, Cmd, Editor, KeyPress, Movement, Word,
|
||||
};
|
||||
use std::error::Error;
|
||||
use std::iter::Iterator;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -305,7 +310,21 @@ pub async fn run_vec_of_pipelines(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
fn convert_rustyline_result_to_string(input: Result<String, ReadlineError>) -> LineResult {
|
||||
match input {
|
||||
Ok(s) => LineResult::Success(s),
|
||||
Err(ReadlineError::Interrupted) => LineResult::CtrlC,
|
||||
Err(ReadlineError::Eof) => LineResult::Break,
|
||||
Err(err) => {
|
||||
outln!("Error: {:?}", err);
|
||||
LineResult::Break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The entry point for the CLI. Will register all known internal commands, load experimental commands, load plugins, then prepare the prompt and line reader for input.
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
pub async fn cli(mut context: Context) -> Result<(), Box<dyn Error>> {
|
||||
let mut syncer = EnvironmentSyncer::new();
|
||||
let configuration = syncer.get_config();
|
||||
|
@ -417,6 +436,7 @@ pub async fn cli(mut context: Context) -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
use crate::git::current_branch;
|
||||
format!(
|
||||
"\x1b[32m{}{}\x1b[m> ",
|
||||
cwd,
|
||||
|
@ -444,7 +464,10 @@ pub async fn cli(mut context: Context) -> Result<(), Box<dyn Error>> {
|
|||
initial_command = None;
|
||||
}
|
||||
|
||||
let line = process_line(readline, &mut context, false, true).await;
|
||||
let line = match convert_rustyline_result_to_string(readline) {
|
||||
LineResult::Success(s) => process_line(&s, &mut context, false, true).await,
|
||||
x => x,
|
||||
};
|
||||
|
||||
// Check the config to see if we need to update the path
|
||||
// TODO: make sure config is cached so we don't path this load every call
|
||||
|
@ -579,7 +602,7 @@ pub async fn run_pipeline_standalone(
|
|||
context: &mut Context,
|
||||
exit_on_error: bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let line = process_line(Ok(pipeline), context, redirect_stdin, false).await;
|
||||
let line = process_line(&pipeline, context, redirect_stdin, false).await;
|
||||
|
||||
match line {
|
||||
LineResult::Success(line) => {
|
||||
|
@ -617,6 +640,7 @@ pub async fn run_pipeline_standalone(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
fn default_rustyline_editor_configuration() -> Editor<Helper> {
|
||||
#[cfg(windows)]
|
||||
const DEFAULT_COMPLETION_MODE: CompletionType = CompletionType::Circular;
|
||||
|
@ -657,6 +681,7 @@ fn default_rustyline_editor_configuration() -> Editor<Helper> {
|
|||
rl
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
fn configure_rustyline_editor(
|
||||
rl: &mut Editor<Helper>,
|
||||
config: &dyn nu_data::config::Conf,
|
||||
|
@ -771,6 +796,7 @@ fn configure_rustyline_editor(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
fn nu_line_editor_helper(
|
||||
context: &mut Context,
|
||||
config: &dyn nu_data::config::Conf,
|
||||
|
@ -779,6 +805,7 @@ fn nu_line_editor_helper(
|
|||
crate::shell::Helper::new(context.clone(), hinter)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
fn rustyline_hinter(config: &dyn nu_data::config::Conf) -> Option<rustyline::hint::HistoryHinter> {
|
||||
if let Some(line_editor_vars) = config.var("line_editor") {
|
||||
for (idx, value) in line_editor_vars.row_entries() {
|
||||
|
@ -839,15 +866,14 @@ pub async fn parse_and_eval(line: &str, ctx: &mut Context) -> Result<String, She
|
|||
|
||||
/// Process the line by parsing the text to turn it into commands, classify those commands so that we understand what is being called in the pipeline, and then run this pipeline
|
||||
pub async fn process_line(
|
||||
readline: Result<String, ReadlineError>,
|
||||
line: &str,
|
||||
ctx: &mut Context,
|
||||
redirect_stdin: bool,
|
||||
cli_mode: bool,
|
||||
) -> LineResult {
|
||||
match &readline {
|
||||
Ok(line) if line.trim() == "" => LineResult::Success(line.clone()),
|
||||
|
||||
Ok(line) => {
|
||||
if line.trim() == "" {
|
||||
LineResult::Success(line.to_string())
|
||||
} else {
|
||||
let line = chomp_newline(line);
|
||||
ctx.raw_input = line.to_string();
|
||||
|
||||
|
@ -1035,13 +1061,6 @@ pub async fn process_line(
|
|||
Err(err) => LineResult::Error(line.to_string(), err),
|
||||
}
|
||||
}
|
||||
Err(ReadlineError::Interrupted) => LineResult::CtrlC,
|
||||
Err(ReadlineError::Eof) => LineResult::Break,
|
||||
Err(err) => {
|
||||
outln!("Error: {:?}", err);
|
||||
LineResult::Break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_err(err: ShellError, source: &Text) {
|
||||
|
|
|
@ -213,7 +213,7 @@ pub fn get_documentation(
|
|||
long_desc.push_str(&format!("\n > {}\n", example.example));
|
||||
} else {
|
||||
let colored_example =
|
||||
crate::shell::helper::Painter::paint_string(example.example, registry, &palette);
|
||||
crate::shell::painter::Painter::paint_string(example.example, registry, &palette);
|
||||
long_desc.push_str(&format!("\n > {}\n", colored_example));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,11 +41,14 @@ pub fn nu(env: &IndexMap<String, String>, tag: impl Into<Tag>) -> Result<Value,
|
|||
let config = nu_data::config::default_path()?;
|
||||
nu_dict.insert_value("config-path", UntaggedValue::path(config).into_value(&tag));
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
{
|
||||
let keybinding_path = crate::keybinding::keybinding_path()?;
|
||||
nu_dict.insert_value(
|
||||
"keybinding-path",
|
||||
UntaggedValue::path(keybinding_path).into_value(&tag),
|
||||
);
|
||||
}
|
||||
|
||||
let config: Box<dyn nu_data::config::Conf> = Box::new(nu_data::config::NuConfig::new());
|
||||
let history = crate::commands::history::history_path(&config);
|
||||
|
|
|
@ -15,6 +15,7 @@ extern crate quickcheck_macros;
|
|||
|
||||
mod cli;
|
||||
mod commands;
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
mod completion;
|
||||
mod context;
|
||||
mod deserializer;
|
||||
|
@ -23,7 +24,9 @@ mod env;
|
|||
mod evaluate;
|
||||
mod format;
|
||||
mod futures;
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
mod git;
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
mod keybinding;
|
||||
mod path;
|
||||
mod plugin;
|
||||
|
@ -34,8 +37,11 @@ pub mod utils;
|
|||
#[cfg(test)]
|
||||
mod examples;
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
pub use crate::cli::cli;
|
||||
|
||||
pub use crate::cli::{
|
||||
cli, create_default_context, parse_and_eval, process_line, register_plugins,
|
||||
create_default_context, parse_and_eval, process_line, register_plugins,
|
||||
run_pipeline_standalone, run_vec_of_pipelines, LineResult,
|
||||
};
|
||||
pub use crate::commands::command::{
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
pub(crate) mod completer;
|
||||
pub(crate) mod filesystem_shell;
|
||||
pub(crate) mod help_shell;
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
pub(crate) mod helper;
|
||||
pub(crate) mod painter;
|
||||
pub(crate) mod palette;
|
||||
pub(crate) mod shell;
|
||||
pub(crate) mod shell_manager;
|
||||
pub(crate) mod value_shell;
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
pub(crate) use helper::Helper;
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::completion::flag::FlagCompleter;
|
|||
use crate::completion::path::{PathCompleter, PathSuggestion};
|
||||
use crate::completion::{self, Completer, Suggestion};
|
||||
use crate::context;
|
||||
|
||||
use std::borrow::Cow;
|
||||
pub(crate) struct NuCompleter {}
|
||||
|
||||
impl NuCompleter {}
|
||||
|
@ -109,8 +109,8 @@ fn select_directory_suggestions(completed_paths: Vec<PathSuggestion>) -> Vec<Pat
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn requote(value: String) -> String {
|
||||
let value = rustyline::completion::unescape(&value, Some('\\'));
|
||||
fn requote(orig_value: String) -> String {
|
||||
let value: Cow<str> = rustyline::completion::unescape(&orig_value, Some('\\'));
|
||||
|
||||
let mut quotes = vec!['"', '\'', '`'];
|
||||
let mut should_quote = false;
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use std::borrow::Cow::{self, Owned};
|
||||
|
||||
use ansi_term::{Color, Style};
|
||||
use nu_parser::SignatureRegistry;
|
||||
use nu_protocol::hir::FlatShape;
|
||||
use nu_source::{Spanned, Tag, Tagged};
|
||||
use nu_source::{Tag, Tagged};
|
||||
|
||||
use crate::completion;
|
||||
use crate::context::Context;
|
||||
use crate::shell::completer::NuCompleter;
|
||||
use crate::shell::palette::{DefaultPalette, Palette};
|
||||
use crate::shell::painter::Painter;
|
||||
use crate::shell::palette::DefaultPalette;
|
||||
|
||||
pub struct Helper {
|
||||
completer: NuCompleter,
|
||||
|
@ -143,90 +142,4 @@ fn vec_tag<T>(input: Vec<Tagged<T>>) -> Option<Tag> {
|
|||
})
|
||||
}
|
||||
|
||||
pub struct Painter {
|
||||
original: Vec<u8>,
|
||||
styles: Vec<Style>,
|
||||
}
|
||||
|
||||
impl Painter {
|
||||
fn new(original: &str) -> Painter {
|
||||
let bytes: Vec<u8> = original.bytes().collect();
|
||||
let bytes_count = bytes.len();
|
||||
Painter {
|
||||
original: bytes,
|
||||
styles: vec![Color::White.normal(); bytes_count],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn paint_string<'l, P: Palette>(
|
||||
line: &'l str,
|
||||
registry: &dyn SignatureRegistry,
|
||||
palette: &P,
|
||||
) -> Cow<'l, str> {
|
||||
let lite_block = nu_parser::lite_parse(line, 0);
|
||||
|
||||
match lite_block {
|
||||
Err(_) => Cow::Borrowed(line),
|
||||
Ok(lb) => {
|
||||
let classified = nu_parser::classify_block(&lb, registry);
|
||||
|
||||
let shapes = nu_parser::shapes(&classified.block);
|
||||
let mut painter = Painter::new(line);
|
||||
|
||||
for shape in shapes {
|
||||
painter.paint_shape(&shape, palette);
|
||||
}
|
||||
|
||||
Cow::Owned(painter.into_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_shape<P: Palette>(&mut self, shape: &Spanned<FlatShape>, palette: &P) {
|
||||
palette
|
||||
.styles_for_shape(shape)
|
||||
.iter()
|
||||
.for_each(|x| self.paint(x));
|
||||
}
|
||||
|
||||
fn paint(&mut self, styled_span: &Spanned<Style>) {
|
||||
for pos in styled_span.span.start()..styled_span.span.end() {
|
||||
self.styles[pos] = styled_span.item;
|
||||
}
|
||||
}
|
||||
|
||||
fn into_string(self) -> String {
|
||||
let mut idx_start = 0;
|
||||
let mut idx_end = 1;
|
||||
|
||||
if self.original.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
let mut builder = String::new();
|
||||
|
||||
let mut current_style = self.styles[0];
|
||||
|
||||
while idx_end < self.styles.len() {
|
||||
if self.styles[idx_end] != current_style {
|
||||
// Emit, as we changed styles
|
||||
let intermediate = String::from_utf8_lossy(&self.original[idx_start..idx_end]);
|
||||
|
||||
builder.push_str(&format!("{}", current_style.paint(intermediate)));
|
||||
|
||||
current_style = self.styles[idx_end];
|
||||
idx_start = idx_end;
|
||||
idx_end += 1;
|
||||
} else {
|
||||
idx_end += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let intermediate = String::from_utf8_lossy(&self.original[idx_start..idx_end]);
|
||||
builder.push_str(&format!("{}", current_style.paint(intermediate)));
|
||||
|
||||
builder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rustyline::Helper for Helper {}
|
||||
|
|
92
crates/nu-cli/src/shell/painter.rs
Normal file
92
crates/nu-cli/src/shell/painter.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use crate::shell::palette::Palette;
|
||||
use ansi_term::{Color, Style};
|
||||
use nu_parser::SignatureRegistry;
|
||||
use nu_protocol::hir::FlatShape;
|
||||
use nu_source::Spanned;
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct Painter {
|
||||
original: Vec<u8>,
|
||||
styles: Vec<Style>,
|
||||
}
|
||||
|
||||
impl Painter {
|
||||
fn new(original: &str) -> Painter {
|
||||
let bytes: Vec<u8> = original.bytes().collect();
|
||||
let bytes_count = bytes.len();
|
||||
Painter {
|
||||
original: bytes,
|
||||
styles: vec![Color::White.normal(); bytes_count],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn paint_string<'l, P: Palette>(
|
||||
line: &'l str,
|
||||
registry: &dyn SignatureRegistry,
|
||||
palette: &P,
|
||||
) -> Cow<'l, str> {
|
||||
let lite_block = nu_parser::lite_parse(line, 0);
|
||||
|
||||
match lite_block {
|
||||
Err(_) => Cow::Borrowed(line),
|
||||
Ok(lb) => {
|
||||
let classified = nu_parser::classify_block(&lb, registry);
|
||||
|
||||
let shapes = nu_parser::shapes(&classified.block);
|
||||
let mut painter = Painter::new(line);
|
||||
|
||||
for shape in shapes {
|
||||
painter.paint_shape(&shape, palette);
|
||||
}
|
||||
|
||||
Cow::Owned(painter.into_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_shape<P: Palette>(&mut self, shape: &Spanned<FlatShape>, palette: &P) {
|
||||
palette
|
||||
.styles_for_shape(shape)
|
||||
.iter()
|
||||
.for_each(|x| self.paint(x));
|
||||
}
|
||||
|
||||
fn paint(&mut self, styled_span: &Spanned<Style>) {
|
||||
for pos in styled_span.span.start()..styled_span.span.end() {
|
||||
self.styles[pos] = styled_span.item;
|
||||
}
|
||||
}
|
||||
|
||||
fn into_string(self) -> String {
|
||||
let mut idx_start = 0;
|
||||
let mut idx_end = 1;
|
||||
|
||||
if self.original.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
let mut builder = String::new();
|
||||
|
||||
let mut current_style = self.styles[0];
|
||||
|
||||
while idx_end < self.styles.len() {
|
||||
if self.styles[idx_end] != current_style {
|
||||
// Emit, as we changed styles
|
||||
let intermediate = String::from_utf8_lossy(&self.original[idx_start..idx_end]);
|
||||
|
||||
builder.push_str(&format!("{}", current_style.paint(intermediate)));
|
||||
|
||||
current_style = self.styles[idx_end];
|
||||
idx_start = idx_end;
|
||||
idx_end += 1;
|
||||
} else {
|
||||
idx_end += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let intermediate = String::from_utf8_lossy(&self.original[idx_start..idx_end]);
|
||||
builder.push_str(&format!("{}", current_style.paint(intermediate)));
|
||||
|
||||
builder
|
||||
}
|
||||
}
|
||||
}
|
|
@ -166,8 +166,16 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let _ = nu_cli::register_plugins(&mut context);
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustyline-support")]
|
||||
{
|
||||
futures::executor::block_on(nu_cli::cli(context))?;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "rustyline-support"))]
|
||||
{
|
||||
println!("Nushell needs the 'rustyline-support' feature for CLI support");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue