mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 01:38:04 +00:00
fold: variable width tabs, guard treating tab as whitespace
Treat tab chars as advancing to the next tab stop rather than having a fixed 8-column width. Also treat tab as a whitespace split target only when splitting on word boundaries.
This commit is contained in:
parent
bd8b129d9a
commit
e5c61a28be
5 changed files with 114 additions and 4 deletions
|
@ -14,6 +14,8 @@ use std::fs::File;
|
|||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::path::Path;
|
||||
|
||||
const TAB_WIDTH: usize = 8;
|
||||
|
||||
static SYNTAX: &str = "[OPTION]... [FILE]...";
|
||||
static SUMMARY: &str = "Writes each file (or standard input if no files are given)
|
||||
to standard output whilst breaking long lines";
|
||||
|
@ -220,11 +222,14 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) {
|
|||
|
||||
match ch {
|
||||
'\t' => {
|
||||
if col_count + 8 > width && !output.is_empty() {
|
||||
let next_tab_stop = col_count + TAB_WIDTH - col_count % TAB_WIDTH;
|
||||
|
||||
if next_tab_stop > width && !output.is_empty() {
|
||||
emit_output!();
|
||||
}
|
||||
col_count += 8;
|
||||
last_space = Some(char_count);
|
||||
|
||||
col_count = next_tab_stop;
|
||||
last_space = if spaces { Some(char_count) } else { None };
|
||||
}
|
||||
'\x08' => {
|
||||
// FIXME: does not match GNU's handling of backspace
|
||||
|
|
|
@ -132,7 +132,7 @@ fn test_single_tab_should_not_add_extra_newline() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_tab_counts_as_8_columns() {
|
||||
fn test_initial_tab_counts_as_8_columns() {
|
||||
new_ucmd!()
|
||||
.arg("-w8")
|
||||
.pipe_in("\t1")
|
||||
|
@ -140,6 +140,33 @@ fn test_tab_counts_as_8_columns() {
|
|||
.stdout_is("\t\n1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tab_should_advance_to_next_tab_stop() {
|
||||
// tab advances the column count to the next tab stop, i.e. the width
|
||||
// of the tab varies based on the leading text
|
||||
new_ucmd!()
|
||||
.args(&["-w8", "tab_stops.input"])
|
||||
.succeeds()
|
||||
.stdout_is_fixture("tab_stops_w8.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_tabs_should_advance_to_next_tab_stops() {
|
||||
new_ucmd!()
|
||||
.args(&["-w16", "tab_stops.input"])
|
||||
.succeeds()
|
||||
.stdout_is_fixture("tab_stops_w16.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_before_tab_with_narrow_width() {
|
||||
new_ucmd!()
|
||||
.arg("-w7")
|
||||
.pipe_in("a\t1")
|
||||
.succeeds()
|
||||
.stdout_is("a\n\t\n1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_at_word_boundary() {
|
||||
new_ucmd!()
|
||||
|
@ -167,8 +194,35 @@ fn test_fold_at_word_boundary_preserve_final_newline() {
|
|||
.stdout_is("one \ntwo\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_at_tab() {
|
||||
new_ucmd!()
|
||||
.arg("-w8")
|
||||
.pipe_in("a\tbbb\n")
|
||||
.succeeds()
|
||||
.stdout_is("a\t\nbbb\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_after_tab() {
|
||||
new_ucmd!()
|
||||
.arg("-w10")
|
||||
.pipe_in("a\tbbb\n")
|
||||
.succeeds()
|
||||
.stdout_is("a\tbb\nb\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_at_tab_as_word_boundary() {
|
||||
new_ucmd!()
|
||||
.args(&["-w8", "-s"])
|
||||
.pipe_in("a\tbbb\n")
|
||||
.succeeds()
|
||||
.stdout_is("a\t\nbbb\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_after_tab_as_word_boundary() {
|
||||
new_ucmd!()
|
||||
.args(&["-w10", "-s"])
|
||||
.pipe_in("a\tbbb\n")
|
||||
|
@ -317,6 +371,15 @@ fn test_tab_counts_as_one_byte() {
|
|||
.stdout_is("1\t\n2\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytewise_fold_before_tab_with_narrow_width() {
|
||||
new_ucmd!()
|
||||
.args(&["-w7", "-b"])
|
||||
.pipe_in("a\t1")
|
||||
.succeeds()
|
||||
.stdout_is("a\t1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytewise_fold_at_word_boundary_only_whitespace() {
|
||||
new_ucmd!()
|
||||
|
|
11
tests/fixtures/fold/tab_stops.input
vendored
Normal file
11
tests/fixtures/fold/tab_stops.input
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
1
|
||||
12
|
||||
123
|
||||
1234
|
||||
12345
|
||||
123456
|
||||
1234567
|
||||
12345678
|
||||
123456781
|
||||
12345678 2
|
||||
12345678 2 4
|
13
tests/fixtures/fold/tab_stops_w16.expected
vendored
Normal file
13
tests/fixtures/fold/tab_stops_w16.expected
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
1
|
||||
12
|
||||
123
|
||||
1234
|
||||
12345
|
||||
123456
|
||||
1234567
|
||||
12345678
|
||||
123456781
|
||||
12345678
|
||||
2
|
||||
12345678
|
||||
2 4
|
18
tests/fixtures/fold/tab_stops_w8.expected
vendored
Normal file
18
tests/fixtures/fold/tab_stops_w8.expected
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
1
|
||||
12
|
||||
123
|
||||
1234
|
||||
12345
|
||||
123456
|
||||
1234567
|
||||
12345678
|
||||
|
||||
12345678
|
||||
1
|
||||
12345678
|
||||
|
||||
2
|
||||
12345678
|
||||
|
||||
2
|
||||
4
|
Loading…
Reference in a new issue