mirror of
https://github.com/RGBCube/nu_scripts
synced 2025-08-01 06:37:46 +00:00
making progress but not quite done
This commit is contained in:
parent
6c94250231
commit
7521ffaaf2
9 changed files with 118 additions and 124 deletions
|
@ -6,7 +6,7 @@ def ls-less [
|
|||
if $is_empty {
|
||||
nu -c 'ls' | less -r
|
||||
} {
|
||||
let command = (build-string 'ls ' $dir)
|
||||
let command = $"ls ($dir)"
|
||||
nu -c $command | less -r
|
||||
}
|
||||
}
|
|
@ -24,26 +24,28 @@ alias fg_light_white = ansi -e '97m'
|
|||
|
||||
# A ls command that approximates the ls -sh command in bash
|
||||
def ls-wide2 [
|
||||
--dir(-d):any # The directory you want to list
|
||||
--columns(-c):int # The number of columns in your output
|
||||
] {
|
||||
let is_empty = ($columns | empty?)
|
||||
let ls_data = (ls)
|
||||
let is_dir_empty = ($dir | empty?)
|
||||
let is_columns_empty = ($columns | empty?)
|
||||
let ls_data = (if $is_dir_empty { ls } { ls $dir })
|
||||
let ansi_size = 9 # \x1b[36m + string + \x1b[0m, ~9 characters are added to each string for coloring
|
||||
let max_fname_size = ((echo $ls_data | get name | str from | str length | math max) + $ansi_size)
|
||||
let max_fsize_size = (echo $ls_data | get size | str from | str length | math max)
|
||||
let max_fname_size = ((echo $ls_data | get name | into string | str length | math max) + $ansi_size)
|
||||
let max_fsize_size = (echo $ls_data | get size | into string | str length | math max)
|
||||
# log (build-string 'max_fname_size=' $max_fname_size ' max_fsize_size=' $max_fsize_size)
|
||||
ls | each -n {
|
||||
let clr_file = (colorize $it.item.name)
|
||||
($ls_data) | each -n { |file|
|
||||
let clr_file = (colorize $file.item.name)
|
||||
# log (build-string $clr_file ' ' $max_fname_size)
|
||||
let clr_size = (echo $it.item.size | str from)
|
||||
let clr_size = (echo $file.item.size | into string)
|
||||
# log (build-string $clr_size ' ' $max_fsize_size)
|
||||
build-string (echo $clr_file | str rpad -c ' ' -l $max_fname_size) ' ' (echo $clr_size | str lpad -c ' ' -l $max_fsize_size) ' ' | autoview
|
||||
if $is_empty {
|
||||
if ($it.index + 1) mod 3 == 0 {
|
||||
$"($clr_file | str rpad -c ' ' -l $max_fname_size) ($clr_size | str lpad -c ' ' -l $max_fsize_size) " | autoview
|
||||
if $is_columns_empty {
|
||||
if ($file.index + 1) mod 3 == 0 {
|
||||
echo (char newline) | autoview
|
||||
} {}
|
||||
} {
|
||||
if ($it.index + 1) mod $columns == 0 {
|
||||
if ($file.index + 1) mod $columns == 0 {
|
||||
echo (char newline) | autoview
|
||||
} {}
|
||||
}
|
||||
|
@ -51,22 +53,22 @@ def ls-wide2 [
|
|||
}
|
||||
|
||||
def colorize [thing:any] {
|
||||
let thing_as_string = (echo $thing | str from)
|
||||
let thing_as_string = (echo $thing | into string)
|
||||
let ext = (echo $thing_as_string | path parse | get extension)
|
||||
let is_empty = ($ext | empty?)
|
||||
|
||||
if $is_empty {
|
||||
# build-string (ansi -e '36m') $thing (ansi -e '0m')
|
||||
build-string (fg_cyan) $thing (relet)
|
||||
$"(fg_cyan)($thing)(relet)"
|
||||
# build-string 'e[36m' $thing 'e[0m'
|
||||
} {
|
||||
if $ext == "nu" {
|
||||
# build-string (ansi -e '95m') $thing (ansi -e '0m')
|
||||
build-string (fg_light_magenta) $thing (relet)
|
||||
$"(fg_light_magenta)($thing)(relet)"
|
||||
# build-string 'e[95m' $thing 'e[0m'
|
||||
} {
|
||||
# build-string (ansi -e '92m') $thing (ansi -e '0m')
|
||||
build-string (fg_light_green) $thing (relet)
|
||||
$"(fg_light_green)($thing)(relet)"
|
||||
# build-string 'e[92m' $thing 'e[0m'
|
||||
}
|
||||
}
|
||||
|
@ -81,17 +83,13 @@ def colorit [] {
|
|||
colorize " file.nu"
|
||||
|
||||
# These all work
|
||||
build-string (fg_light_green) "abc" (relet)
|
||||
echo (fg_cyan) "def" (relet) | str collect
|
||||
#echo '|' (fg_light_green) ' 0;92m ' (relet) '| ' Green ' |' (char newline) | str collect
|
||||
$"(fg_light_green)abc(relet)"
|
||||
$"(fg_cyan)def(relet)"
|
||||
}
|
||||
|
||||
# This is a first attempt and some type of logging
|
||||
def log [
|
||||
message:any # Some log message
|
||||
] {
|
||||
def log [message:any] {
|
||||
let now = (date now | date format '%Y%m%d_%H%M%S.%f')
|
||||
let mess = (build-string $now '|DBG|' $message (char newline))
|
||||
let mess = $"($now)|DBG|($message)(char nl)"
|
||||
echo $mess | autoview
|
||||
}
|
||||
|
||||
}
|
|
@ -26,17 +26,20 @@ def run_ls [
|
|||
path:string
|
||||
columns:int
|
||||
] {
|
||||
let max_fname_size = (ls $path | get name | str from | str length | math max)
|
||||
let max_fsize_size = (ls $path | get size | str from | str length | math max)
|
||||
let max_fname_size = (ls $path | get name | into string | str length | math max)
|
||||
let max_fsize_size = (ls $path | get size | into string | str length | math max)
|
||||
|
||||
ls $path | each -n { |file|
|
||||
let the_file = ($file.item.name | into string | str rpad -c ' ' -l $max_fname_size)
|
||||
let the_size = ($file.item.size | into string | str lpad -c ' ' -l $max_fsize_size)
|
||||
$"($the_file) ($the_size) " | autoview
|
||||
|
||||
ls $path | each -n {
|
||||
build-string (echo $it.item.name | str rpad -c ' ' -l $max_fname_size) ' ' (echo (build-string $it.item.size) | str lpad -c ' ' -l $max_fsize_size) ' '
|
||||
if $is_columns_empty {
|
||||
if ($it.index + 1) mod 3 == 0 {
|
||||
if ($file.index + 1) mod 3 == 0 {
|
||||
echo (char newline) | autoview
|
||||
} {}
|
||||
} {
|
||||
if ($it.index + 1) mod $columns == 0 {
|
||||
if ($file.index + 1) mod $columns == 0 {
|
||||
echo (char newline) | autoview
|
||||
} {}
|
||||
}
|
||||
|
@ -44,11 +47,8 @@ def run_ls [
|
|||
}
|
||||
|
||||
# This is a first attempt and some type of logging
|
||||
def log [
|
||||
message:any # Some log message
|
||||
] {
|
||||
def log [message:any] {
|
||||
let now = (date now | date format '%Y%m%d_%H%M%S.%f')
|
||||
let mess = (build-string $now '|DBG|' $message (char newline))
|
||||
let mess = $"($now)|DBG|($message)(char nl)"
|
||||
echo $mess | autoview
|
||||
}
|
||||
|
||||
}
|
|
@ -2,10 +2,10 @@
|
|||
# $it in and inner loop and an outer loop at
|
||||
# the same time, each having different values
|
||||
|
||||
seq 30 39 | each {
|
||||
let row = (build-string $it ' ')
|
||||
let data = (seq 40 49 | each {
|
||||
build-string $it ' '
|
||||
seq 30 39 | each { |outer|
|
||||
let row = $"($outer) "
|
||||
let data = (seq 40 49 | each { |inner|
|
||||
$"($inner) "
|
||||
} | str collect)
|
||||
echo [$row $data (char newline)] | str collect
|
||||
$"($row)($data)(char newline)"
|
||||
} | str collect
|
|
@ -1,21 +1,20 @@
|
|||
def loading [] {
|
||||
echo Loading (char newline) | str collect | autoview
|
||||
echo 0..100 | each {
|
||||
$"Loading (char newline)" | autoview
|
||||
echo 0..100 | each { |tick|
|
||||
sleep 50ms
|
||||
#hide_cursor
|
||||
# I believe '1000D' means move the cursor to the left 1000 columns
|
||||
echo (ansi -e '1000D') | autoview
|
||||
echo (build-string $it '%') | autoview
|
||||
$"(ansi -e '1000D')" | autoview
|
||||
$"($tick)%" | autoview
|
||||
}
|
||||
#show_cursor
|
||||
}
|
||||
|
||||
def show_cursor [] {
|
||||
echo (ansi -e '?25h') | autoview
|
||||
$"(ansi -e '?25h')" | autoview
|
||||
}
|
||||
|
||||
def hide_cursor [] {
|
||||
echo (ansi -e '?25l') | autoview
|
||||
$"(ansi -e '?25l')" | autoview
|
||||
}
|
||||
|
||||
hide_cursor
|
||||
|
|
|
@ -20,32 +20,31 @@ let blocks = ["▏" "▎" "▍" "▌" "▋" "▊" "▉" "█"]
|
|||
# "▏" #1/8
|
||||
|
||||
# Turn off the cursor
|
||||
echo (ansi cursor_off)
|
||||
ansi cursor_off
|
||||
# Move cursor all the way to the left
|
||||
echo (ansi -e '1000D') | autoview
|
||||
$"(ansi -e '1000D')" | autoview
|
||||
# Draw the background for the progress bar
|
||||
echo $bg_fill | str lpad -c $bg_fill -l $pb_len
|
||||
$bg_fill | str lpad -c $bg_fill -l $pb_len
|
||||
|
||||
echo 1..<$pb_len | each {
|
||||
echo 1..<$pb_len | each { |cur_progress|
|
||||
# This is kind of a hack because it's not incrementally drawing a new box
|
||||
# It's drawing the entire row every time with a different padding amount
|
||||
# echo $blocks.7 | str lpad -c $blocks.7 -l $it | autoview
|
||||
|
||||
let cur_progress = $it
|
||||
echo 0..7 | each {
|
||||
let cur_idx = ($it mod 8)
|
||||
echo 0..7 | each { |tick|
|
||||
let cur_idx = ($tick mod 8)
|
||||
let cur_block = (echo $blocks | nth $cur_idx)
|
||||
echo $cur_block | str lpad -c $blocks.7 -l $cur_progress | autoview
|
||||
echo (ansi -e '1000D') | autoview
|
||||
sleep 50ms
|
||||
$"($cur_block | str lpad -c $blocks.7 -l $cur_progress)" | autoview
|
||||
$"(ansi -e '1000D')" | autoview
|
||||
sleep 5ms
|
||||
}
|
||||
echo (ansi -e '1000D') | autoview
|
||||
$"(ansi -e '1000D')" | autoview
|
||||
}
|
||||
# Fill in the last background block
|
||||
echo $blocks.7 | str lpad -c $blocks.7 -l $pb_len | autoview
|
||||
echo (char newline)
|
||||
echo "Done"
|
||||
echo (ansi cursor_on)
|
||||
$"($blocks.7 | str lpad -c $blocks.7 -l $pb_len)" | autoview
|
||||
char newline
|
||||
"Done"
|
||||
ansi cursor_on
|
||||
|
||||
|
||||
# Try to do this in the next version
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
let blocks = ["▏" "▎" "▍" "▌" "▋" "▊" "▉" "█"]
|
||||
let pb_size = 25
|
||||
echo (ansi cursor_off)
|
||||
echo 1..<$pb_size | each {
|
||||
let cur_size = $it
|
||||
echo 0..7 | each {
|
||||
let idx = ($it mod 8)
|
||||
ansi cursor_off
|
||||
echo 1..<$pb_size | each { |cur_size|
|
||||
echo 0..7 | each { |tick|
|
||||
let idx = ($tick mod 8)
|
||||
let cur_block = (echo $blocks | nth $idx)
|
||||
echo $cur_block | str lpad -c $blocks.7 -l $cur_size | autoview
|
||||
echo (ansi -e '1000D') | autoview
|
||||
sleep 50ms
|
||||
$"($cur_block | str lpad -c $blocks.7 -l $cur_size)" | autoview
|
||||
$"(ansi -e '1000D')" | autoview
|
||||
sleep 5ms
|
||||
}
|
||||
}
|
||||
echo (char newline)
|
||||
echo 'Done'
|
||||
echo (ansi cursor_on)
|
||||
char newline
|
||||
'Done'
|
||||
ansi cursor_on
|
||||
|
||||
|
|
|
@ -1,41 +1,40 @@
|
|||
# Displays a prompt
|
||||
def git-status-prompt [] {
|
||||
# build-string (ansi reset) (ansi green) (whoami | str trim) (ansi reset) '@' ((sys).host | get hostname) ':' (ansi green_dimmed) (prompt-pwd) (ansi reset) (git-branch-icon) (ansi reset) (char newline) '➤ '
|
||||
let not_windows = (echo $nu.path | first | into string | str contains '/')
|
||||
build-string (ansi reset) (ansi green) (if $not_windows {$nu.env.USER} {$nu.env.USERNAME}) (ansi reset) '@' (hostname | str trim) ':' (ansi green_dimmed) (prompt-pwd) (ansi reset) (git-branch-icon) (ansi reset) (char newline) '➤ '
|
||||
let not_windows = ($nu.path | first | into string | str contains '/')
|
||||
$"(ansi reset)(ansi green)(if $not_windows {$nu.env.USER} {$nu.env.USERNAME})(ansi reset)@(hostname | str trim):(ansi green_dimmed)(prompt-pwd)(ansi reset)(git-branch-icon)(ansi reset)(char newline)(char prompt) "
|
||||
}
|
||||
|
||||
# Returns a shortened pwd for use in prompt
|
||||
def prompt-pwd [] {
|
||||
let not_windows = (echo $nu.path | first | into string | str contains '/')
|
||||
let not_windows = ($nu.path | first | into string | str contains '/')
|
||||
let path = (pwd | if $not_windows { split row "/" } { split row "\" })
|
||||
let home = (if $not_windows { ($nu.env.HOME | split row "/") } { (echo [$nu.env.HOMEDRIVE $nu.env.HOMEPATH] | path join | split row "\") })
|
||||
|
||||
if (echo $path | length) > 1 {
|
||||
if (echo $home | reduce { $it in $path }) {
|
||||
let path-without-home = (echo $path | skip (echo $home | length))
|
||||
if ($path | length) > 1 {
|
||||
if ($home | reduce { $it in $path }) {
|
||||
let path-without-home = ($path | skip ($home | length))
|
||||
|
||||
if (echo $path-without-home | wrap | compact | length) > 0 {
|
||||
let parent = (echo $path | skip (echo $home | length) | drop)
|
||||
if ($path-without-home | wrap | compact | length) > 0 {
|
||||
let parent = ($path | skip ($home | length) | drop)
|
||||
|
||||
if (echo $parent | wrap | compact | length) > 0 {
|
||||
let short-part = (echo $parent | each {
|
||||
if (echo $it | str starts-with ".") {
|
||||
echo (echo $it | str substring [0 2]) "/"
|
||||
if ($parent | wrap | compact | length) > 0 {
|
||||
let short-part = ($parent | each { |part|
|
||||
if ($part | str starts-with ".") {
|
||||
$"($part | str substring [0 2])/"
|
||||
} {
|
||||
echo (echo $it | str substring [0 1]) "/"
|
||||
$"($part | str substring [0 1])/"
|
||||
}
|
||||
})
|
||||
echo "~/" $short-part (echo $path | last) | str collect
|
||||
$"~/($short-part | str collect)($path | last)"
|
||||
} {
|
||||
echo "~/" (echo $path | last) | str collect
|
||||
$"~/($path | last)"
|
||||
}
|
||||
} {
|
||||
echo "~"
|
||||
"~"
|
||||
}
|
||||
} {
|
||||
let parent = (echo $path | drop | str substring [0 1] | each { echo $it "/" })
|
||||
echo "/" $parent (echo $path | last) | str collect
|
||||
$"/($parent)($path | last)"
|
||||
}
|
||||
} {
|
||||
pwd
|
||||
|
@ -45,10 +44,10 @@ def prompt-pwd [] {
|
|||
# Map of git status codes to ANSI colour codes
|
||||
def git-prompt-map [] {
|
||||
echo a m r c d "??" u |
|
||||
rotate lengther-clockwise |
|
||||
rotate counter-clockwise |
|
||||
reject Column0 | append (
|
||||
echo (ansi green) (ansi yellow_bold) (ansi cyan) (ansi blue) (ansi red) (ansi red_dimmed) (ansi red) |
|
||||
rotate lengther-clockwise |
|
||||
rotate counter-clockwise |
|
||||
reject Column0
|
||||
) | headers
|
||||
}
|
||||
|
@ -58,11 +57,11 @@ def git-prompt-icons [k] {
|
|||
let icns = ["✚ " "* " "➜ " "⇒ " "✖ " "? " "! "];
|
||||
|
||||
git-prompt-map |
|
||||
pivot status colour | each --numbered {
|
||||
let idx = $it.index;
|
||||
pivot status colour | each --numbered { |icon|
|
||||
let idx = $icon.index;
|
||||
|
||||
if $it.item.status == $k {
|
||||
build-string $it.item.colour (echo $icns | nth $idx)
|
||||
if $icon.item.status == $k {
|
||||
$"($icon.item.colour)($icns | nth $idx)"
|
||||
} {
|
||||
= $nothing
|
||||
}
|
||||
|
@ -74,24 +73,22 @@ def git-branch-icon [] {
|
|||
do -i {
|
||||
let branch = (do -i { git rev-parse --abbrev-ref HEAD } | str trim)
|
||||
|
||||
if (echo $branch | str length) > 0 {
|
||||
if ($branch | str length) > 0 {
|
||||
let modified = (do -i { git status --porcelain } | split row "\n" | str trim | split column " " status file);
|
||||
|
||||
if (echo $modified | get | first | empty?) {
|
||||
build-string "|" (ansi green) $branch (ansi reset) ":" (ansi green) '✓' (ansi reset)
|
||||
if ($modified | get | first | empty?) {
|
||||
$"|(ansi green)($branch)(ansi reset):(ansi green)✓(ansi reset)"
|
||||
} {
|
||||
let modified2 = (do -i { git status --porcelain } | split row "\n" | str substring [0 1])
|
||||
let branch-colour = (if (echo $modified2 | each { $it in [A M R C D] } | reduce { $it || $acc }) {
|
||||
echo yellow
|
||||
"yellow"
|
||||
} {
|
||||
echo red
|
||||
"red"
|
||||
})
|
||||
build-string "|" (ansi $branch-colour) $branch (ansi reset) ":" (echo $modified | get status | uniq | str downcase | each {
|
||||
git-prompt-icons $it
|
||||
} | str collect)
|
||||
$"|(ansi $branch-colour)($branch)(ansi reset):($modified | get status | uniq | str downcase | each { git-prompt-icons $it })" | str collect
|
||||
}
|
||||
} {
|
||||
echo ""
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,25 +25,25 @@ def construct_prompt [] {
|
|||
|
||||
# let's construct the left and right prompt
|
||||
# the left side of the prompt with ansi colors
|
||||
let left_colored = (build-string (ansi gb) $current_dir (ansi cb) '(' $git_info ')' (ansi reset))
|
||||
let left_colored = $"(ansi gb)($current_dir)(ansi cb)(char lparen)($git_info)(char rparen)(ansi reset)"
|
||||
|
||||
# the left prompt length without the ansi escapes
|
||||
let left_len = (echo $left_colored | ansi strip | str length)
|
||||
let left_len = ($left_colored | ansi strip | str length)
|
||||
|
||||
# the right side of the prompt with ansi colors
|
||||
let right_colored = (build-string (ansi blue) (echo $nu.env.CMD_DURATION) '|' (ansi dark_gray) $current_time (ansi reset))
|
||||
let right_colored = $"(ansi blue)($nu.env.CMD_DURATION)|(ansi dark_gray)($current_time)(ansi reset)"
|
||||
|
||||
# the right prompt length *with* ansi escapes (need this to determine how many escape chars there are)
|
||||
let right_colored_len = (echo $right_colored | str length)
|
||||
let right_colored_len = ( $right_colored | str length)
|
||||
|
||||
# the right prompt length without the ansi escapes
|
||||
let right_len = (echo $right_colored | ansi strip | str length)
|
||||
let right_len = ($right_colored | ansi strip | str length)
|
||||
|
||||
# let's calcuate the length of the right prompt so we know how much to pad the left prompt
|
||||
let calculated_right_len = ($term_width - $left_len + ($right_colored_len - $right_len))
|
||||
|
||||
# finally, let's make the prompt
|
||||
let the_prompt = (build-string $left_colored (echo $right_colored | str lpad -c ' ' -l $calculated_right_len) (char newline) $decorator ' ')
|
||||
let the_prompt = $"($left_colored)($right_colored | str lpad -c ' ' -l $calculated_right_len)(char newline)($decorator) "
|
||||
|
||||
# let's update the title bar now
|
||||
echo $title_bar
|
||||
|
@ -60,30 +60,32 @@ def construct_prompt [] {
|
|||
|
||||
# Abbreviate home path
|
||||
def home_abbrev [] {
|
||||
let is_home_in_path = (echo (pwd) | str starts-with $nu.home-dir)
|
||||
let is_home_in_path = (pwd | into string | str starts-with $nu.home-dir)
|
||||
if $is_home_in_path {
|
||||
let lin-home = (echo $nu.home-dir | str find-replace -a '\\' '/' | str downcase)
|
||||
let lin-pwd = (echo (pwd) | str find-replace -a '\\' '/' | str downcase)
|
||||
echo $lin-pwd | str find-replace $lin-home '~'
|
||||
let lin-home = ($nu.home-dir | into string | str find-replace -a '\\' '/' | str downcase)
|
||||
let lin-pwd = (pwd | into string | str find-replace -a '\\' '/' | str downcase)
|
||||
$lin-pwd | str find-replace $lin-home '~'
|
||||
} {
|
||||
echo (pwd)
|
||||
pwd
|
||||
}
|
||||
}
|
||||
|
||||
# Get Git Info custom commands
|
||||
|
||||
def git_br [] {
|
||||
echo [ (ansi gb) (pwd) (ansi reset) '(' (ansi cb) (do -i { git rev-parse --abbrev-ref HEAD } | str trim | str collect ) (ansi reset) ')' (char newline) (ansi yb) (date now | date format '%m/%d/%Y %I:%M:%S%.3f %p') (ansi reset) ' ¯\\_(ツ)_/¯ ' (char prompt) ' '] | str collect
|
||||
$"(ansi gb)(pwd)(ansi reset)(char lparen)(ansi cb)(do -i { git rev-parse --abbrev-ref HEAD } | str trim | str collect)(ansi reset)(char rparen)(char newline)(ansi yb)(date now | date format '%m/%d/%Y %I:%M:%S%.3f %p')(ansi reset)¯\\_(ツ)_/¯(char prompt) "
|
||||
}
|
||||
|
||||
# Set Title String custom commands
|
||||
|
||||
def set_title_str [str-arg] {
|
||||
echo [(ansi title) ' ' $str-arg ' ' (char bel)] | str collect
|
||||
}
|
||||
def get_abbrev_pwd_win [] {
|
||||
echo [(pwd | split row '\' | first (pwd | split row '\' | length | each { $it - 1} ) | str substring '0,1' | format '{$it}/' | append (pwd | split row '\' | last ) | str collect)] | str collect
|
||||
$"(ansi title) ($str-arg) (char bel)"
|
||||
}
|
||||
|
||||
# def get_abbrev_pwd_win [] {
|
||||
# echo [(pwd | split row '\' | first (pwd | split row '\' | length | each { $it - 1} ) | str substring '0,1' | format '{$it}/' | append (pwd | split row '\' | last ) | str collect)] | str collect
|
||||
# }
|
||||
|
||||
def get_abbrev_pwd_lin [] {
|
||||
# echo [(pwd | split row '/' | first (pwd | split row '/' | length | each { $it - 1} ) | each { str substring '0,1' | format '{$it}/' } | append (pwd | split row '/' | last ) | str collect)] | str collect
|
||||
echo [(home_abbrev | split row '/' | first (home_abbrev | split row '/' | length | each { $it - 1} ) | each { str substring '0,1' | format '{$it}/' } | append (home_abbrev | split row '/' | last ) | str collect)] | str collect
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue