# ---------------------------------------------------------------------
# Function: kv
# A minimalist's key-value manager for dict-like lists
# This function operates on lists where key-value pairs are stored in
# an even number of elements. The list is modified in-place via reference,
# so no new list is returned.
#
# Arguments:
# @arg lstVar The list variable name to operate on.
# @arg key The key to get/set/add/delete.
# @arg value The value to set for the given key (if provided).
#
# It allows the following operations on the list:
# - GET (fetch the value for a given key),
# - SET (set a value for a key, or update an existing one),
# - ADD (add a new key-value pair if the key doesn't exist),
# - DEL (delete a key-value pair by removing both the key and value).
#
# Special behavior:
# - If the value is "-" it deletes the key and its value
# - If the key is "-" (minus sign), the entire list is pretty printed.
# - The list must have an even number of elements to work correctly.
#
# Example usage:
# set lst {name Jack age 30}
# kv lst name ;# -> Jack
# kv lst name John ;# Sets new name
# kv lst age ;# -> 30
# kv lst city NYC ;# Adds 'city' -> 'NYC'
# kv lst fullname {John Doe} ;# Adds 'fullname' -> 'John Doe'
# kv lst - ;# Pretty prints the current list
# kv lst city - ;# Deletes the city key and its value
#
# Returns the value associated with the key if GET operation, or an empty
# string if the key is not found. If a modification is made (SET/ADD),
# the list is updated in-place via reference, and the set value is returned.
# In the case of DELETE, the removed keyname is returned, or an empty string
# if the key was not found.
# ----------------------------------------------------------------------
proc kv {lstVar key {value {}}} {
upvar 1 $lstVar lst
set idx [lsearch -exact $lst $key]
# Pretty print when key is "-"
if {$key eq "-"} {
puts "Pretty printing $lstVar:"
set maxlen 0
foreach {k v} $lst {
set maxlen [expr {max($maxlen, [string length $k])}]
}
foreach {k v} $lst {
puts [format "%-*s -> %s" $maxlen $k $v]
}
return
}
if {$value eq {}} {
# get
return [expr {$idx == -1 ? "" : [lindex $lst [expr {$idx + 1}]]}]
} elseif {$value eq "-"} {
# del
if {$idx != -1} {
set lst [lreplace $lst $idx [expr {$idx + 1}]]
}
return $key
} elseif {$idx == -1} {
# add
lappend lst $key $value
} else {
# set
lset lst [expr {$idx + 1}] $value
}
return $value
}