mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 23:19:49 +02:00
feat(std-rfc/str): add str align
(#16062)
This commit is contained in:
@@ -129,3 +129,54 @@ export def unindent [
|
|||||||
$text
|
$text
|
||||||
| str replace -r --all $"\(?m\)^($indent_chars)" ''
|
| str replace -r --all $"\(?m\)^($indent_chars)" ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alias "str align" = align
|
||||||
|
|
||||||
|
# Aligns each line in the input string to have the target in the same column through padding
|
||||||
|
@example "Align variable assignments" { [ "one = 1", "two = 2", "three = 3", "four = 4", "five = 5" ] | str align '=' } --result r#'one = 1
|
||||||
|
two = 2
|
||||||
|
three = 3
|
||||||
|
four = 4
|
||||||
|
five = 5'#
|
||||||
|
@example "Align variable assignments to the center" { [ "one = 1", "two = 2", "three = 3", "four = 4", "five = 5" ] | str align '=' --center } --result r#' one = 1
|
||||||
|
two = 2
|
||||||
|
three = 3
|
||||||
|
four = 4
|
||||||
|
five = 5'#
|
||||||
|
export def align [
|
||||||
|
target:string # Substring to align
|
||||||
|
--char (-c) = " " # Character to use for padding
|
||||||
|
--center (-C) # Add padding at the beginning of the line instead of before the target
|
||||||
|
--range (-r): range # The range of lines to align
|
||||||
|
]: [string -> string, list<string> -> string] {
|
||||||
|
# noop on empty string
|
||||||
|
if ($in | is-empty) { return "" }
|
||||||
|
let $input = $in | to text | lines
|
||||||
|
|
||||||
|
let $indexes = (
|
||||||
|
$input
|
||||||
|
| enumerate
|
||||||
|
| each {|x|
|
||||||
|
if $x.index in ($range | default 0..) {
|
||||||
|
$x.item | str index-of $target
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
let $max = $indexes | math max
|
||||||
|
|
||||||
|
$input
|
||||||
|
| zip $indexes
|
||||||
|
| each {|x|
|
||||||
|
# Fold adding a `$char` at the index until they are in the same column
|
||||||
|
# If the substring is not in the line, the index is -1 and it is left as it is
|
||||||
|
seq 1 (if $x.1 == -1 { 0 } else { $max - $x.1 })
|
||||||
|
| reduce -f ($x.0 | split chars) {|_, acc|
|
||||||
|
let $idx = if $center { 0 } else { $x.1 }
|
||||||
|
$acc | insert $idx $char
|
||||||
|
}
|
||||||
|
| str join
|
||||||
|
}
|
||||||
|
| str join (char nl)
|
||||||
|
}
|
||||||
|
@@ -291,3 +291,139 @@ def str-unindent_whitespace_works_with_tabs [] {
|
|||||||
|
|
||||||
assert equal $actual $expected
|
assert equal $actual $expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_simple [] {
|
||||||
|
let actual = [
|
||||||
|
"let a = 1"
|
||||||
|
"let max = 2"
|
||||||
|
"let very_long_variable_name = 3"
|
||||||
|
] | str align '='
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"let a = 1"
|
||||||
|
"let max = 2"
|
||||||
|
"let very_long_variable_name = 3"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_center [] {
|
||||||
|
let actual = [
|
||||||
|
"a = 1"
|
||||||
|
"max = 2"
|
||||||
|
"very_long_variable_name = 3"
|
||||||
|
] | str align '=' --center
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
" a = 1"
|
||||||
|
" max = 2"
|
||||||
|
"very_long_variable_name = 3"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_with_range [] {
|
||||||
|
let actual = r#'match 5 {
|
||||||
|
1.. => { print "More than zero" }
|
||||||
|
0 => { print "Zero" }
|
||||||
|
-1 => { print "Negative one" }
|
||||||
|
-119283 => { print "Very negative" }
|
||||||
|
}'# | str align '=>' --range 2..
|
||||||
|
|
||||||
|
let expected = r#'match 5 {
|
||||||
|
1.. => { print "More than zero" }
|
||||||
|
0 => { print "Zero" }
|
||||||
|
-1 => { print "Negative one" }
|
||||||
|
-119283 => { print "Very negative" }
|
||||||
|
}'# | lines | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_ignore_lines_with_no_target [] {
|
||||||
|
let actual = [
|
||||||
|
"let a = 1"
|
||||||
|
"let max = 2"
|
||||||
|
"# comment"
|
||||||
|
] | str align '='
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"let a = 1"
|
||||||
|
"let max = 2"
|
||||||
|
"# comment"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_use_different_char [] {
|
||||||
|
let actual = [
|
||||||
|
"=>"
|
||||||
|
"=====>"
|
||||||
|
] | str align '>' -c '='
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"=====>"
|
||||||
|
"=====>"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_multiple_target_in_line [] {
|
||||||
|
let actual = [
|
||||||
|
"print test # Hello # World"
|
||||||
|
"print hello there # test"
|
||||||
|
] | str align '#'
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"print test # Hello # World"
|
||||||
|
"print hello there # test"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_no_target [] {
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"print test # Hello # World"
|
||||||
|
"print hello there # test"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
let actual = $expected | str align '='
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_empty_target_noop [] {
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
"print test # Hello # World"
|
||||||
|
"print hello there # test"
|
||||||
|
] | str join "\n"
|
||||||
|
|
||||||
|
let actual = $expected | str align ''
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
def str-align_empty_input_noop [] {
|
||||||
|
|
||||||
|
let expected = ""
|
||||||
|
|
||||||
|
let actual = [] | str align '='
|
||||||
|
|
||||||
|
assert equal $actual $expected
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user