Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: WIP _units



On Thu, 30 Jul 2026 12:51:10 +0200
Oliver Kiddle <opk@xxxxxxx> wrote:

> christopher@xxxxxxxxx wrote:
> > i'm trying to update _units to allow completion for e.g. `units area_<TAB>`
> > which currently breaks with the underscore. I couldn't make out what i have
> > to add to compadd to make this work.
> > Any suggestions?  
> 
> The problem is with the two compset commands early in the function which
> try to strip off characters not belonging to the units like numbers. They
> are removing `area_` from the completion matching because of the
> underscore. Try adding the _ into those patterns too:
> 
>   compset -P '*[^[:alnum:]_]'
>   compset -S '[^[:alnum:]_]*'
> 
> >  testfiles=(
> > -  /usr/share/units.dat		# GNU on Fedora  
> 
> Did you make any actual changes here or is this purely realignment?
Other than the "*.units" it was pure alignment.
I reduced it now by only replacing the tabs with spaces or should i rather
use tabs instead (for all those lines)? The completion-style-guide has no
answer to that or i'm blind.
> 
> On my system, more than one file matches including an extra currency
> one. The completion ignores that second file. I can't see why it needs a
> loop instead of something like $^testfiles(N) adding also Y1 to the
> qualifier if only one should be matched.
> 
> > -units=(${${all:#^[[:alnum:]]##([\(\]]*|)}%%\(*})
> > +units=(${${all:#^[0-9A-z_]##([\(\]]*|)}%%\(*})  
> 
> I'd keep the character class rather than use something like A-z which
> may include 6 extra ASCII characters, so e.g:
> 
>   units=( ${${all:#^[[:alnum:]_]##([\(\]]*|)}%%\(*} )


The completion now works for all found files as long as i don't provide the
files manually. No idea how i should "stack" those (marked with #TODO).

The spaces in all= and pfxs= i just put in to align with units=


From 9bb909bb6ddeef0ecbf306c3c08a4facd11f531d Mon Sep 17 00:00:00 2001
From: Christopher Bock <christopher@xxxxxxxxx>
Date: Tue, 28 Jul 2026 22:08:14 +0200
Subject: [PATCH] _units

* rename array testfiles to unitsfiles
* include all files matching /usr/share/units/*.units
* allow completion for units with an underscore in their name, e.g.
  area_europe
* parse all available unitsfiles for completion
---
 Completion/Unix/Command/_units | 39 +++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/Completion/Unix/Command/_units b/Completion/Unix/Command/_units
index 6d86f4dc3..b4149fe81 100644
--- a/Completion/Unix/Command/_units
+++ b/Completion/Unix/Command/_units
@@ -31,43 +31,44 @@ _arguments -C -s -S \
 # need to be a single argument.  Units themselves don't have special
 # characters, so it's safe to take just the characters around the
 # cursor.
-compset -P '*[^[:alnum:]]'
-compset -S '[^[:alnum:]]*'
+compset -P '*[^[:alnum:]_]'
+compset -S '[^[:alnum:]_]*'
 
 # Find the units data.
 local datfile
-local -a testfiles
-testfiles=(
-  /usr/share/units.dat		# GNU on Fedora
+local -a unitsfiles
+unitsfiles=(
+  /usr/share/units.dat          # GNU on Fedora
   /usr/share/units/units.dat    # on gentoo
-  /usr/share/units/definitions.units # on Debian, units 2.00 and newer
+  /usr/share/units/*.units      # on Debian, units 2.00 and newer
   /usr/local/share/units.dat    # GNU DIY install
-  /usr/share/lib/unittab	# Solaris
+  /usr/share/lib/unittab        # Solaris
   /usr/share/misc/units.lib     # OpenBSD [as of 2020]; also FreeBSD 9.1
   /usr/share/misc/definitions.units     # FreeBSD 12.1
   /usr/share/misc/units.dat     # on Debian, units 1.88 and older
 )
 
+# This currently only allows completion on the first occurence if we provide
+# something like -f file1 -f file2 -f file3.
+# TODO: Use all provided files.
 datfile=${opt_args[-f]:-${opt_args[--file]}}
-if [[ -z $datfile ]]; then
-  for datfile in $testfiles; do
-    [[ -f $datfile ]] && break
-  done
-fi
-
-if [[ ! -f $datfile ]]; then
-  _message "Data file for units not found."
-  return
+if [[ ! -z $datfile ]]; then
+  if [[ -f $datfile ]]; then
+    unitsfiles=( $datfile )
+  else
+    _message "Data file for units not found."
+    return
+  fi
 fi
 
 local -a all units pfxs
 # Solaris uses / to start a comment, else #.
 # could cache this, but it's not that big a deal...
-all=($(awk '$1 !~ /^[\/#]/ { print $1 }' $datfile))
+all=( $( awk '$1 !~ /^[\/#]/ { print $1 }' $^unitsfiles(N) ) )
 # prefixes end in a -
-pfxs=(${${all:#^[[:alnum:]]##-}%%-})
+pfxs=( ${${all:#^[[:alnum:]]##-}%%-} )
 # units may include regular or piecewise linear functions
-units=(${${all:#^[[:alnum:]]##([\(\]]*|)}%%\(*})
+units=( ${${all:#^[[:alnum:]_]##([\(\]]*|)}%%\(*} )
 
 if (( ${#units} )); then
   _alternative 'unitprefixes:unit prefix:compadd -S "" -a pfxs' \
-- 
2.53.0





Messages sorted by: Reverse Date, Date, Thread, Author