Re: WIP _units

[email protected]
Newsgroups gmane.comp.shells.zsh.devel,gmane.comp.shells.zsh.user
Message-ID <[email protected]>
On Thu, 30 Jul 2026 12:51:10 +0200
Oliver Kiddle <[email protected]> wrote:

> [email protected] 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 <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.