diff --git a/go-core.bash b/go-core.bash index 475e0d5..49312ec 100755 --- a/go-core.bash +++ b/go-core.bash @@ -124,26 +124,36 @@ declare _GO_PLUGINS_PATHS=() # initialized, _GO_PLUGINS_PATHS and _GO_SCRIPTS_DIR will be added. declare _GO_SEARCH_PATHS=("$_GO_CORE_DIR/libexec") -# Invokes printf builtin, then folds output to $COLUMNS width if 'fold' exists. -# -# Should be used as the last step to print to standard output or error, as that -# is more efficient than calling this multiple times due to the pipe to 'fold'. +# Invokes printf builtin, then folds output to $COLUMNS width # # Arguments: # everything accepted by the printf builtin except the '-v varname' option @go.printf() { local format="$1" shift + local result + local line + local prefix if [[ "$#" -eq 0 ]]; then format="${format//\%/%%}" fi - - if command -v fold >/dev/null; then - printf "$format" "$@" | fold -s -w "$COLUMNS" - else - printf "$format" "$@" - fi + # If `format` ends with a newline, chomp it, since the loop will add one. + printf -v result "${format%\\n}" "$@" + + while IFS= read -r line; do + line="${line%$'\r'}" + + while [[ "${#line}" -gt "$COLUMNS" ]]; do + prefix="${line:0:$COLUMNS}" + prefix="${prefix% *}" + printf '%s\n' "$prefix" + line="${line#$prefix}" + line="${line#* }" + done + + printf '%s\n' "$line" + done <<<"$result" } # Prints the stack trace at the point of the call. diff --git a/tests/core.bats b/tests/core.bats index 259a868..4dbe174 100644 --- a/tests/core.bats +++ b/tests/core.bats @@ -32,7 +32,7 @@ load environment @test "$SUITE: produce error on cd" { local expected - expected+='cd is only available after using "./go env" to set up your '$'\n' + expected+=$'cd is only available after using "./go env" to set up your\n' expected+='shell environment.' COLUMNS=60 @@ -42,7 +42,7 @@ load environment @test "$SUITE: produce error on pushd" { local expected - expected+='pushd is only available after using "./go env" to set up '$'\n' + expected+=$'pushd is only available after using "./go env" to set up\n' expected+='your shell environment.' COLUMNS=60 @@ -52,7 +52,7 @@ load environment @test "$SUITE: produce error on unenv" { local expected - expected+='unenv is only available after using "./go env" to set up '$'\n' + expected+=$'unenv is only available after using "./go env" to set up\n' expected+='your shell environment.' COLUMNS=60 diff --git a/tests/core/printf.bats b/tests/core/printf.bats index f3f473c..e3f4720 100644 --- a/tests/core/printf.bats +++ b/tests/core/printf.bats @@ -2,29 +2,14 @@ load ../environment -TEST_TEXT='1234567890 1234567890 1234567890' - -setup() { - create_test_go_script '@go.printf "%s" "$@"' -} - teardown() { remove_test_go_rootdir } -@test "$SUITE: wrap text according to COLUMNS if fold command is available" { - run env COLUMNS=11 "$TEST_GO_SCRIPT" "$TEST_TEXT" - assert_success - assert_equal '3' "${#lines[@]}" 'number of output lines' - assert_line_equals 0 '1234567890 ' - assert_line_equals 1 '1234567890 ' - assert_line_equals 2 '1234567890' -} - -@test "$SUITE: don't wrap text if fold command isn't available" { - run env PATH= COLUMNS=11 "$BASH" "$TEST_GO_SCRIPT" "$TEST_TEXT" - assert_success "$TEST_TEXT" - assert_equal '1' "${#lines[@]}" 'number of output lines' +@test "$SUITE: wrap text according to COLUMNS" { + create_test_go_script '@go.printf "%s" "1234567890 1234567890 1234567890"' + COLUMNS=25 run "$TEST_GO_SCRIPT" + assert_success $'1234567890 1234567890\n1234567890' } @test "$SUITE: escape percent signs if only one argument" { @@ -33,3 +18,18 @@ teardown() { run "$TEST_GO_SCRIPT" "$test_text" assert_success "$test_text" } + +@test "$SUITE: preserve blank lines" { + local test_string=$'1234567890\n\n1234567890\n\n1234567890' + create_test_go_script "@go.printf '%s' '$test_string'" + COLUMNS=15 run "$TEST_GO_SCRIPT" + assert_success "$test_string" +} + +@test "$SUITE: don't add extra newline if format ends with one" { + local test_string='1234567890' + create_test_go_script "@go.printf '%s\n' '$test_string'" \ + "@go.printf '%s\n' '$test_string'" + COLUMNS=15 run "$TEST_GO_SCRIPT" + assert_success "$test_string"$'\n'"$test_string" +}