Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FMT - Refactor from buffered to streaming output #152

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions src/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,18 @@ mut:
}

fn main() {
output := run_fmt(os.args)

for line in output {
println(line)
}
run_fmt(os.args, fn (s string) {
println(s)
})
}

fn run_fmt(args []string) []string {
mut output := []string{}
fn run_fmt(args []string, out_fn fn (string)) {
app := process_args(args)

for file in app.file_args {
lines := read_all_lines(file)
output << fmt(lines, app)
fmt(lines, app, out_fn)
}
return output
}

fn read_all_lines(file string) []string {
Expand All @@ -57,24 +53,20 @@ fn read_all_lines(file string) []string {
}
}

fn fmt(lines []string, app App) []string {
mut output := []string{}
fn fmt(lines []string, app App, out_fn fn (string)) {
paragraphs := get_paragraphs(lines, app)

for paragraph in paragraphs {
for line in fmt_paragraph(paragraph, app) {
output << line
}
fmt_paragraph(paragraph, app, out_fn)
}
return output
}

fn fmt_paragraph(paragraph Paragraph, app App) []string {
fn fmt_paragraph(paragraph Paragraph, app App, out_fn fn (string)) {
mut ta := ''
mut pa := []string{}

if paragraph.lines.len == 0 {
return ['']
out_fn('')
return
}

mut first_line := true
Expand Down Expand Up @@ -117,7 +109,8 @@ fn fmt_paragraph(paragraph Paragraph, app App) []string {

for rn.len > app.width {
mut break_index := find_break(rn, app.width)
pa << rn[0..break_index].string()
slice := rn[0..break_index].string()
out_fn(slice)
rn = rn[break_index + 1..].clone()
for rn.len > 0 && is_white_space(rn[0]) {
rn.delete(0)
Expand All @@ -131,9 +124,8 @@ fn fmt_paragraph(paragraph Paragraph, app App) []string {
last := rn.string().trim_right(white_space)

if last.len > 0 {
pa << rn.string().trim_right(white_space)
out_fn(rn.string().trim_right(white_space))
}
return pa
}

fn find_break(ln []rune, max int) int {
Expand Down
87 changes: 57 additions & 30 deletions src/fmt/fmt_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ fn to_tmp_file(data []string) string {
return file
}

fn setup() (fn (s string), fn () []string) {
mut result := []string{}
mut result_ref := &result
out_fn := fn [mut result_ref] (s string) {
result_ref << s
}
result_fn := fn [mut result_ref] () []string {
return *result_ref
}
return out_fn, result_fn
}

fn test_basic_wrap() {
println(@METHOD)
input := [
Expand All @@ -31,7 +43,8 @@ fn test_basic_wrap() {
'Now is the time for all good men to come to the aid of their country.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-w', '30', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-w', '30', tmp], out_fn)
os.rm(tmp)!
// print_lines(output)
expected := [
Expand All @@ -43,7 +56,7 @@ fn test_basic_wrap() {
'men to come to the aid of',
'their country.',
]
assert output == expected
assert result_fn() == expected
}

fn test_narrow_to_formatted() {
Expand All @@ -66,7 +79,8 @@ fn test_narrow_to_formatted() {
'Adios amigo.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', tmp], out_fn)
os.rm(tmp)!
// print_lines(output)
expected := [
Expand All @@ -80,7 +94,7 @@ fn test_narrow_to_formatted() {
'',
'Much ado about nothing. He he he. Adios amigo.',
]
assert output == expected
assert result_fn() == expected
}

fn test_line_indents_denote_new_paragraph() {
Expand All @@ -93,7 +107,8 @@ fn test_line_indents_denote_new_paragraph() {
'multline paragraph.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-w', '35', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-w', '35', tmp], out_fn)
os.rm(tmp)!
expected := [
'This is a single line paragraph',
Expand All @@ -104,7 +119,7 @@ fn test_line_indents_denote_new_paragraph() {
'comprise a simple multline',
'paragraph.',
]
assert output == expected
assert result_fn() == expected
}

fn test_numbered_list_no_options() {
Expand All @@ -118,7 +133,8 @@ fn test_numbered_list_no_options() {
' 4. Now is the time for all good men to come to the aid of their country.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', tmp], out_fn)
os.rm(tmp)!
// print_lines(output)
expected := [
Expand All @@ -130,7 +146,7 @@ fn test_numbered_list_no_options() {
' of their country. 4. Now is the time for all good men to come to the',
' aid of their country.',
]
assert output == expected
assert result_fn() == expected
}

fn test_numbered_list_w_40() {
Expand All @@ -144,7 +160,8 @@ fn test_numbered_list_w_40() {
' 4. Now is the time for all good men to come to the aid of their country.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-w', '40', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-w', '40', tmp], out_fn)
os.rm(tmp)!
// print_lines(output)
expected := [
Expand All @@ -159,7 +176,7 @@ fn test_numbered_list_w_40() {
' 4. Now is the time for all good men',
' to come to the aid of their country.',
]
assert output == expected
assert result_fn() == expected
}

fn test_split_only() {
Expand All @@ -180,7 +197,8 @@ fn test_split_only() {
'fringilla ut, venenatis ut, neque.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-s', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-s', tmp], out_fn)
os.rm(tmp)!
expected := [
'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur',
Expand All @@ -202,7 +220,7 @@ fn test_split_only() {
'lacinia. Morbi fringilla lacus quis arcu. Vestibulum sem quam, dapibus in,',
'fringilla ut, venenatis ut, neque.',
]
assert output == expected
assert result_fn() == expected
}

fn test_indents_no_blank_lines() {
Expand All @@ -217,7 +235,8 @@ fn test_indents_no_blank_lines() {
'Love never fails.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', tmp], out_fn)
os.rm(tmp)!
expected := [
'Love is patient, love is kind. It does not envy,',
Expand All @@ -228,7 +247,7 @@ fn test_indents_no_blank_lines() {
' always trusts, always hopes, always perseveres.',
'Love never fails.',
]
assert output == expected
assert result_fn() == expected
}

fn test_prefix_str_option() {
Expand All @@ -243,7 +262,8 @@ fn test_prefix_str_option() {
'> Court front maids forty if aware their at. Chicken use are pressed removed.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-p', '> ', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-p', '> ', tmp], out_fn)
os.rm(tmp)!
expected := [
'Prefix lines test',
Expand All @@ -257,7 +277,7 @@ fn test_prefix_str_option() {
'> opinions it pleasure of debating. Court front maids forty if aware their',
'> at. Chicken use are pressed removed.',
]
assert output == expected
assert result_fn() == expected
}

fn test_uniform_spacing_option() {
Expand All @@ -267,22 +287,24 @@ fn test_uniform_spacing_option() {
]
tmp := to_tmp_file(input)
// non-uniform case
output1 := run_fmt(['fmt', tmp])
out_fn1, result_fn1 := setup()
run_fmt(['fmt', tmp], out_fn1)
expected1 := [
'venenatis pede. Quisque dui dui, ultricies ut, facilisis non,',
'pulvinar non. Duis quis arcu a purus volutpat iaculis. Morbi id dui',
'in diam ornare',
]
assert output1 == expected1
assert result_fn1() == expected1

// uniform spacing case
output2 := run_fmt(['fmt', '-u', tmp])
out_fn2, result_fn2 := setup()
run_fmt(['fmt', '-u', tmp], out_fn2)
os.rm(tmp)!
expected2 := [
'venenatis pede. Quisque dui dui, ultricies ut, facilisis non, pulvinar non.',
'Duis quis arcu a purus volutpat iaculis. Morbi id dui in diam ornare',
]
assert output2 == expected2
assert result_fn2() == expected2
}

fn test_uniform_spacing_with_prefix_and_width() {
Expand All @@ -297,7 +319,8 @@ fn test_uniform_spacing_with_prefix_and_width() {
'> Court front maids forty if aware their at. Chicken use are pressed removed.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-u', '-p', '> ', '-w', '30', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-u', '-p', '> ', '-w', '30', tmp], out_fn)
os.rm(tmp)!
expected := [
'> Prefix lines test',
Expand All @@ -319,7 +342,7 @@ fn test_uniform_spacing_with_prefix_and_width() {
'> aware their at. Chicken use',
'> are pressed removed.',
]
assert output == expected
assert result_fn() == expected
}

fn test_crown_and_uniform_options() {
Expand All @@ -330,15 +353,16 @@ fn test_crown_and_uniform_options() {
'introduced on output.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-c', '-u', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-c', '-u', tmp], out_fn)
os.rm(tmp)!
expected := [
'By default, blank lines, spaces between words, and indentation are',
' preserved in the output; successive input lines with different',
' indentation are not joined; tabs are expanded on input and',
'introduced on output.',
]
assert expected == output
assert result_fn() == expected
}

fn test_tagged_and_width_options() {
Expand All @@ -349,7 +373,8 @@ fn test_tagged_and_width_options() {
'Now is the time for all good men to come to the aid of their country.',
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-t', '-w', '40', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-t', '-w', '40', tmp], out_fn)
os.rm(tmp)!
expected := [
'Now is the time for all good men to come',
Expand All @@ -358,7 +383,7 @@ fn test_tagged_and_width_options() {
'Now is the time for all good men to come',
' to the aid of their country.',
]
assert expected == output
assert result_fn() == expected
}

fn test_unicode_handling() {
Expand All @@ -367,15 +392,16 @@ fn test_unicode_handling() {
"I can do without ⑰ lobsters, you know. Come on!' So they ⼘≺↩⌝⚙⠃ couldn't get them out again. The Mock Turtle went on again:-- 'I didn't mean it!' Ⓡpleaded.",
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-w', '40', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-w', '40', tmp], out_fn)
os.rm(tmp)!
expected := [
'I can do without ⑰ lobsters, you know.',
"Come on!' So they ⼘≺↩⌝⚙⠃ couldn't get",
'them out again. The Mock Turtle went on',
"again:-- 'I didn't mean it!' Ⓡpleaded.",
]
assert output == expected
assert result_fn() == expected
}

fn test_unicode__tab_handling() {
Expand All @@ -384,7 +410,8 @@ fn test_unicode__tab_handling() {
"I can do without ⑰ lobsters, \tyou know. Come on!' So they ⼘≺↩⌝⚙⠃ couldn't get them out again. The Mock Turtle went on again:-- 'I didn't mean it!' Ⓡpleaded.",
]
tmp := to_tmp_file(input)
output := run_fmt(['fmt', '-w', '40', tmp])
out_fn, result_fn := setup()
run_fmt(['fmt', '-w', '40', tmp], out_fn)
os.rm(tmp)!
expected := [
'I can do without ⑰ lobsters, you',
Expand All @@ -393,5 +420,5 @@ fn test_unicode__tab_handling() {
"on again:-- 'I didn't mean it!'",
'Ⓡpleaded.',
]
assert output == expected
assert result_fn() == expected
}
Loading