[Home] Zsh logo

dual

Zsh Wizard

Download dual Return to Examples
  1. #!/bin/zsh
  2. #
  3. # dual - automatically updates path-array combinations.
  4. # i.e. setting BLAH=a:b:c also sets blah=(a b c) and
  5. # vice versa.
  6. #
  7. # This behaviour is planned for release in version 2.6 of zsh, where
  8. # it will presumably be as transparent as every other variable
  9. # type. In the mean time, this will accomplish the same thing.
  10. #
  11. # [2000-09-29]
  12. # Version 3.1.6 of zsh automates this functionality with
  13. # typeset -T. I'll leave this function here for historical purposes.
  14. #
  15. # Usage:
  16. # dual [var[=val]] . . .
  17. #
  18. # where
  19. # var is a variable to mark as being dual, that is, when dual
  20. # sets foo, it also sets FOO.
  21. # val is the value to assign to var. Because it is interpreted
  22. # by the shell twice, replace every \ by \\\ to receive the
  23. # same behaviour.
  24. #
  25. # Note that because this is not really a part of zsh, but just an
  26. # add-on, doing
  27. # foo=(a b c d)
  28. # will not set FOO to A:B:C:D. You must explicitly say
  29. # dual foo=(a b c d)
  30. # Likewise, FOO=a:b:c:d will not work on its own. Prefix it with dual.
  31. #
  32. # To do:
  33. # This is a little over-large. There's no real need to keep a list of
  34. # variables that are dual, at least not with this small implementation.
  35. # As a result undual isn't necessary either, though one does exist.
  36. # I did it mainly for interest's sake.
  37. # Currently this function assumes unsetopt shwordsplit
  38. # scan each variable given
  39. for var
  40. do
  41. # get name
  42. name=${var%%\=*}
  43. # This next bit needed because for some reason ${foo%%\=*} doesn't strip
  44. # the = if it's all there is. Use ${foo%\=*} and it does. This
  45. # doesn't happen with the equivalent # or ## format. Bizarre.
  46. if [[ $name[-1] = "=" ]]
  47. then
  48. name=$name[1,-2]
  49. fi
  50. # value to assign.
  51. if [[ "$var" = *\=* ]]
  52. then
  53. eval "val=${var#$name\=}"
  54. else
  55. val=
  56. fi
  57. # get lower- and upper-case versions.
  58. lower=${(L)name}
  59. upper=${(U)name}
  60. # check for obvious errors - no letters, mixed case
  61. if [[ $upper = $lower ]]
  62. then
  63. echo "dual: $name has no letters"
  64. elif [[ $name != $upper && $name != $lower ]]
  65. then
  66. echo "dual: $name has both cases"
  67. else
  68. # Update DUAL and dual environment variables
  69. if [[ -z "$dual" || -z "$DUAL" ]]
  70. then
  71. dual=(dual)
  72. DUAL=DUAL
  73. fi
  74. if [[ $DUAL != (*:|)$upper(|:*) ]]
  75. then
  76. dual=($dual "$lower")
  77. DUAL="$DUAL:$upper"
  78. fi
  79. if [[ $name = $upper ]]
  80. then
  81. # upper-case given - split into tokens at :
  82. upperval=$val
  83. lowerval=${(s,:,)=upperval}
  84. else
  85. # lower-case. Join with :
  86. lowerval=$val
  87. upperval=${(j,:,)=lowerval}
  88. fi
  89. # assign.
  90. $upper=$upperval
  91. $lower=$lowerval
  92. fi
  93. done
  94. return 0