forked from extern/nushell
Add line ending autodetect to 'lines' (#589)
This commit is contained in:
parent
39f03bf5e4
commit
e1c92e90ca
@ -7,8 +7,6 @@ use nu_protocol::{
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Lines;
|
pub struct Lines;
|
||||||
|
|
||||||
const SPLIT_CHAR: char = '\n';
|
|
||||||
|
|
||||||
impl Command for Lines {
|
impl Command for Lines {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"lines"
|
"lines"
|
||||||
@ -39,8 +37,10 @@ impl Command for Lines {
|
|||||||
// the Rc structure to continue using it. If split could take ownership
|
// the Rc structure to continue using it. If split could take ownership
|
||||||
// of the split values, then this wouldn't be needed
|
// of the split values, then this wouldn't be needed
|
||||||
PipelineData::Value(Value::String { val, span }, ..) => {
|
PipelineData::Value(Value::String { val, span }, ..) => {
|
||||||
|
let split_char = if val.contains("\r\n") { "\r\n" } else { "\n" };
|
||||||
|
|
||||||
let lines = val
|
let lines = val
|
||||||
.split(SPLIT_CHAR)
|
.split(split_char)
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
@ -55,12 +55,18 @@ impl Command for Lines {
|
|||||||
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, ..) => {
|
PipelineData::ListStream(stream, ..) => {
|
||||||
|
let mut split_char = "\n";
|
||||||
|
|
||||||
let iter = stream
|
let iter = stream
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |value| {
|
.filter_map(move |value| {
|
||||||
if let Value::String { val, span } = value {
|
if let Value::String { val, span } = value {
|
||||||
|
if split_char != "\r\n" && val.contains("\r\n") {
|
||||||
|
split_char = "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
let inner = val
|
let inner = val
|
||||||
.split(SPLIT_CHAR)
|
.split(split_char)
|
||||||
.filter_map(|s| {
|
.filter_map(|s| {
|
||||||
if skip_empty && s.is_empty() {
|
if skip_empty && s.is_empty() {
|
||||||
None
|
None
|
||||||
@ -83,22 +89,29 @@ impl Command for Lines {
|
|||||||
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::StringStream(stream, span, ..) => {
|
PipelineData::StringStream(stream, span, ..) => {
|
||||||
|
let mut split_char = "\n";
|
||||||
|
|
||||||
let iter = stream
|
let iter = stream
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |value| match value {
|
.map(move |value| match value {
|
||||||
Ok(value) => value
|
Ok(value) => {
|
||||||
.split(SPLIT_CHAR)
|
if split_char != "\r\n" && value.contains("\r\n") {
|
||||||
.filter_map(|s| {
|
split_char = "\r\n";
|
||||||
if !s.is_empty() {
|
}
|
||||||
Some(Value::String {
|
value
|
||||||
val: s.into(),
|
.split(split_char)
|
||||||
span,
|
.filter_map(|s| {
|
||||||
})
|
if !s.is_empty() {
|
||||||
} else {
|
Some(Value::String {
|
||||||
None
|
val: s.into(),
|
||||||
}
|
span,
|
||||||
})
|
})
|
||||||
.collect::<Vec<Value>>(),
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<Value>>()
|
||||||
|
}
|
||||||
Err(err) => vec![Value::Error { error: err }],
|
Err(err) => vec![Value::Error { error: err }],
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
@ -116,8 +129,10 @@ impl Command for Lines {
|
|||||||
//know to use a different encoding
|
//know to use a different encoding
|
||||||
let s = input.collect_string("", &config)?;
|
let s = input.collect_string("", &config)?;
|
||||||
|
|
||||||
|
let split_char = if s.contains("\r\n") { "\r\n" } else { "\n" };
|
||||||
|
|
||||||
let lines = s
|
let lines = s
|
||||||
.split(SPLIT_CHAR)
|
.split(split_char)
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
@ -84,3 +84,8 @@ fn string_in_valuestream() -> TestResult {
|
|||||||
fn single_tick_interpolation() -> TestResult {
|
fn single_tick_interpolation() -> TestResult {
|
||||||
run_test(r#"$'(3 + 4)'"#, "7")
|
run_test(r#"$'(3 + 4)'"#, "7")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn detect_newlines() -> TestResult {
|
||||||
|
run_test("'hello\r\nworld' | lines | get 0 | str length", "5")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user