forked from extern/nushell
Lines no longer treats a text buffer as a line (#3153)
This commit is contained in:
parent
ee5bd2b4b3
commit
0d305d7c3e
@ -56,59 +56,70 @@ async fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(args
|
||||
.input
|
||||
.chain(eos)
|
||||
.map(move |item| {
|
||||
.filter_map(move |item| {
|
||||
let leftover_string = leftover_string.clone();
|
||||
async move {
|
||||
match item {
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(st)),
|
||||
..
|
||||
} => {
|
||||
let mut leftover_string = leftover_string.lock();
|
||||
|
||||
match item {
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(st)),
|
||||
..
|
||||
} => {
|
||||
let mut leftover_string = leftover_string.lock();
|
||||
let mut buffer = leftover_string.clone();
|
||||
buffer.push_str(&st);
|
||||
|
||||
let lo_lines = (&*leftover_string).lines().map(|x| x.to_string());
|
||||
let st_lines = st.lines().map(|x| x.to_string());
|
||||
let mut lines: Vec<String> = lo_lines.chain(st_lines).collect();
|
||||
let mut lines: Vec<String> =
|
||||
buffer.lines().map(|x| x.to_string()).collect();
|
||||
|
||||
leftover_string.clear();
|
||||
leftover_string.clear();
|
||||
|
||||
if !ends_with_line_ending(&st) {
|
||||
if let Some(last) = lines.pop() {
|
||||
leftover_string.push_str(&last);
|
||||
if !ends_with_line_ending(&st) {
|
||||
if let Some(last) = lines.pop() {
|
||||
leftover_string.push_str(&last);
|
||||
}
|
||||
}
|
||||
|
||||
if !lines.is_empty() {
|
||||
let success_lines: Vec<_> = lines
|
||||
.iter()
|
||||
.map(|x| {
|
||||
ReturnSuccess::value(
|
||||
UntaggedValue::string(x).into_untagged_value(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Some(futures::stream::iter(success_lines))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let success_lines: Vec<_> = lines
|
||||
.iter()
|
||||
.map(|x| {
|
||||
ReturnSuccess::value(UntaggedValue::string(x).into_untagged_value())
|
||||
})
|
||||
.collect();
|
||||
|
||||
futures::stream::iter(success_lines)
|
||||
}
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::EndOfStream),
|
||||
..
|
||||
} => {
|
||||
let st = (&*leftover_string).lock().clone();
|
||||
if !st.is_empty() {
|
||||
futures::stream::iter(vec![ReturnSuccess::value(
|
||||
UntaggedValue::string(st).into_untagged_value(),
|
||||
)])
|
||||
} else {
|
||||
futures::stream::iter(vec![])
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::EndOfStream),
|
||||
..
|
||||
} => {
|
||||
let st = (&*leftover_string).lock().clone();
|
||||
if !st.is_empty() {
|
||||
Some(futures::stream::iter(vec![ReturnSuccess::value(
|
||||
UntaggedValue::string(st).into_untagged_value(),
|
||||
)]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Value {
|
||||
tag: value_span, ..
|
||||
} => Some(futures::stream::iter(vec![Err(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
name_span,
|
||||
"value originates from here",
|
||||
value_span,
|
||||
),
|
||||
)])),
|
||||
}
|
||||
Value {
|
||||
tag: value_span, ..
|
||||
} => futures::stream::iter(vec![Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
name_span,
|
||||
"value originates from here",
|
||||
value_span,
|
||||
))]),
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
|
@ -17,6 +17,21 @@ pub fn nonu() {
|
||||
args().iter().skip(1).for_each(|arg| print!("{}", arg));
|
||||
}
|
||||
|
||||
pub fn repeater() {
|
||||
let mut stdout = io::stdout();
|
||||
let args = args();
|
||||
let mut args = args.iter().skip(1);
|
||||
let letter = args.next().expect("needs a character to iterate");
|
||||
let count = args.next().expect("need the number of times to iterate");
|
||||
|
||||
let count: u64 = count.parse().expect("can't convert count to number");
|
||||
|
||||
for _ in 0..count {
|
||||
let _ = write!(stdout, "{}", letter);
|
||||
}
|
||||
let _ = stdout.flush();
|
||||
}
|
||||
|
||||
pub fn iecho() {
|
||||
// println! panics if stdout gets closed, whereas writeln gives us an error
|
||||
let mut stdout = io::stdout();
|
||||
|
@ -46,5 +46,5 @@ fn lines_multi_value_split() {
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "6");
|
||||
assert_eq!(actual.out, "5");
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
.hidden(true)
|
||||
.long("testbin")
|
||||
.value_name("TESTBIN")
|
||||
.possible_values(&["cococo", "iecho", "fail", "nonu", "chop"])
|
||||
.possible_values(&["cococo", "iecho", "fail", "nonu", "chop", "repeater"])
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
@ -77,6 +77,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
"fail" => binaries::fail(),
|
||||
"nonu" => binaries::nonu(),
|
||||
"chop" => binaries::chop(),
|
||||
"repeater" => binaries::repeater(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,17 @@ mod it_evaluation {
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_properly_buffer_lines_externally() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
nu --testbin repeater c 8197 | lines | count
|
||||
"#
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "1");
|
||||
}
|
||||
#[test]
|
||||
fn supports_fetching_given_a_column_path_to_it() {
|
||||
Playground::setup("it_argument_test_3", |dirs, sandbox| {
|
||||
|
Loading…
Reference in New Issue
Block a user