zsh-workers
 help / color / mirror / code / Atom feed
* _os_arguments
@ 2016-12-12  5:28 Matthew Martin
  2016-12-12  8:52 ` _os_arguments Daniel Shahaf
  2016-12-13  0:54 ` _os_arguments Oliver Kiddle
  0 siblings, 2 replies; 3+ messages in thread
From: Matthew Martin @ 2016-12-12  5:28 UTC (permalink / raw)
  To: zsh-workers

Also for when 5.3 is settled.

When updating completions for the BSDs, it can be a bit of a pain to
check each case or if block especially since the alphabetization of the
options is disrupted. This is an attempt to ease that pain. First an
example usage converting _rm to _os_arguments then the patch itself.
Hopefully the yodl looks decent.

- Matthew Martin


diff --git a/Completion/Unix/Command/_rm b/Completion/Unix/Command/_rm
index 6d728b157..0c5b526f1 100644
--- a/Completion/Unix/Command/_rm
+++ b/Completion/Unix/Command/_rm
@@ -23,32 +23,20 @@ if _pick_variant gnu=gnu unix --help; then
   )
 else
   args=(${args:#*)--*\[*})
-  case $OSTYPE in
-    dragonfly*|freebsd*|netbsd*|openbsd*)
-      args+=(
-        '-d[remove directories as well]'
-        '-P[overwrite files before deleting them]'
-      )
-    ;|
-    dragonfly*|freebsd*|netbsd*)
-      args+=(
-        '-v[explain what is being done]'
-        '-W[attempt to undelete named files]'
-        "-x[don't cross file systems when removing a hierarchy]"
-      )
-    ;|
-    dragonfly*|freebsd*)
-      args+=(
-        '(-i)-I[prompt when removing many files]'
-      )
-    ;;
-  esac
+  args+=(
+    DFNO '-d[remove directories as well]'
+    DF   '(-i)-I[prompt when removing many files]'
+    DFNO '-P[overwrite files before deleting them]'
+    DFN  '-v[explain what is being done]'
+    DFN  '-W[attempt to undelete named files]'
+    DFN  "-x[don't cross file systems when removing a hierarchy]"
+  )
 fi
 
 local curcontext=$curcontext state line ret=1
 declare -A opt_args
 
-_arguments -C -s $opts \
+_os_arguments -C -s $opts : \
   $args && ret=0
 
 case $state in





diff --git a/Completion/Base/Utility/_os_arguments b/Completion/Base/Utility/_os_arguments
new file mode 100755
index 000000000..44ba19c05
--- /dev/null
+++ b/Completion/Base/Utility/_os_arguments
@@ -0,0 +1,36 @@
+#autoload
+
+local i os s=2
+local -a args
+
+i=${@[(i):]}
+(( i > $# )) && i=0
+args=(${@[1,i]})
+shift $i
+
+case $OSTYPE in
+  aix*) os=A;;
+  cygwin*) os=C;;
+  dragonfly*) os=D;;
+  freebsd*) os=F;;
+  hpux*) os=H;;
+  irix*) os=I;;
+  linux*) os=L;;
+  darwin*) os=M;;
+  netbsd*) os=N;;
+  openbsd*) os=O;;
+  solaris*) os=S;;
+esac
+
+for 1; do
+  if [[ $1 == [[:upper:]]## ]]; then
+    (( s == 2 )) && s=0
+    [[ $1 == *$os* ]] && s=1
+  else
+    (( s )) || continue
+    args+=($1)
+    s=2
+  fi
+done
+
+_arguments "$args[@]"
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index 953d51c4c..e75aa7062 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -4624,6 +4624,60 @@ are used to store the option settings in effect before the completion
 widget locally sets the options it needs.  Hence these functions are not
 generally used by the completion system.
 )
+findex(_os_arguments)
+xitem(tt(_os_arguments )[ var(_arguments flags) tt(:) ] {var(OS selector)|var(spec)} )
+This function wraps tt(_arguments) to ease completing multiple OSes with
+differing flags. The arguments up to the first colon are passed verbatim
+to tt(_arguments). Following arguments are either OS selectors,
+consisting of all uppercase letters, or tt(_arguments) specs. Each OS is
+assigned a letter (see below). If that letter appears in an OS selector
+since the last spec (or if there is no proceeding OS selector), the
+following specs are passed to tt(_arguments) until the next OS selector.
+
+startitem()
+item(tt(A))(
+AIX
+)
+item(tt(C))(
+Cygwin
+)
+item(tt(D))(
+DragonFlyBSD
+)
+item(tt(F))(
+FreeBSD
+)
+item(tt(H))(
+HP-UX
+)
+item(tt(I))(
+IRIX
+)
+item(tt(L))(
+Linux
+)
+item(tt(M))(
+macOS
+)
+item(tt(N))(
+NetBSD
+)
+item(tt(O))(
+OpenBSD
+)
+item(tt(S))(
+Solaris
+)
+enditem()
+
+example(_os_arguments -s : \\ \
+    '-n[number all output lines]' \\ \
+    '-u[do not buffer output]' \\ \
+    '(-)*:files:_files' \\ \
+       N  '-B[use specified buffer size]:buffer size:' \\ \
+     F N  '-l[set a lock on the stdout file descriptor]' \\ \
+    DFMNO '-v[display non-printing chars as ^X or M-a]'
+)
 findex(_parameters)
 item(tt(_parameters))(
 This is used to complete the names of shell parameters.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: _os_arguments
  2016-12-12  5:28 _os_arguments Matthew Martin
@ 2016-12-12  8:52 ` Daniel Shahaf
  2016-12-13  0:54 ` _os_arguments Oliver Kiddle
  1 sibling, 0 replies; 3+ messages in thread
From: Daniel Shahaf @ 2016-12-12  8:52 UTC (permalink / raw)
  To: zsh-workers

Matthew Martin wrote on Sun, Dec 11, 2016 at 23:28:03 -0600:
> +++ b/Doc/Zsh/compsys.yo
> @@ -4624,6 +4624,60 @@ are used to store the option settings in effect before the completion
>  widget locally sets the options it needs.  Hence these functions are not
>  generally used by the completion system.
>  )
> +findex(_os_arguments)
> +xitem(tt(_os_arguments )[ var(_arguments flags) tt(:) ] {var(OS selector)|var(spec)} )

Should be item(), not xitem().  The former is for all-but-the-last when
there's more than one item() heading before a paragraph.

Add a `...' at the end to indicate the {..} group is repeatable?

Eliminate the space inside the tt()?

> +This function wraps tt(_arguments) to ease completing multiple OSes with
> +differing flags. The arguments up to the first colon are passed verbatim
> +to tt(_arguments). Following arguments are either OS selectors,
> +consisting of all uppercase letters, or tt(_arguments) specs. Each OS is
> +assigned a letter (see below). If that letter appears in an OS selector
> +since the last spec (or if there is no proceeding OS selector), the
> +following specs are passed to tt(_arguments) until the next OS selector.
> +
> +startitem()

Use startsitem()?  I think the 's' stands for 'short', which would be
more appropriate in this instance.

Add some linking sentence?  "The following OS selectors are available:".

The text implies unknown OS selectors are silently ignored, which is
good for forwards compatibility (completion functions running on an
older zsh than they target).

> +item(tt(S))(
> +Solaris
> +)
> +enditem()
> +
> +example(_os_arguments -s : \\ \
> +    '-n[number all output lines]' \\ \
> +    '-u[do not buffer output]' \\ \
> +    '(-)*:files:_files' \\ \
> +       N  '-B[use specified buffer size]:buffer size:' \\ \
> +     F N  '-l[set a lock on the stdout file descriptor]' \\ \
> +    DFMNO '-v[display non-printing chars as ^X or M-a]'
> +)

Missing ')'.  Also, consider adding a prose description of what the
example code does.

The yodl looks good; haven't reviewed the functions.

Cheers,

Daniel

>  findex(_parameters)
>  item(tt(_parameters))(
>  This is used to complete the names of shell parameters.
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: _os_arguments
  2016-12-12  5:28 _os_arguments Matthew Martin
  2016-12-12  8:52 ` _os_arguments Daniel Shahaf
@ 2016-12-13  0:54 ` Oliver Kiddle
  1 sibling, 0 replies; 3+ messages in thread
From: Oliver Kiddle @ 2016-12-13  0:54 UTC (permalink / raw)
  To: zsh-workers

Matthew Martin wrote:
> When updating completions for the BSDs, it can be a bit of a pain to
> check each case or if block especially since the alphabetization of the
> options is disrupted. This is an attempt to ease that pain. First an
> example usage converting _rm to _os_arguments then the patch itself.

Have you seen the approach taken in _chown, _cp, _du and _last which
also does not disrupt the order of options? There could be ways to
compress the patterns down.

Having only a single letter and wrapping _arguments directly means that
this wouldn't work for a number of functions. We have quite a few cases
where we do:
  _pick_variant -r variant gnu=GNU $OSTYPE --version
and then use $variant with the case statement.

Also, there are quite a few cases where we include the version number,
particularly with Solaris because Solaris 10 still gets a fair amount of
use (is still the primary platform where I work). I was planning to do
this somewhat more in future for BSDs (at least at major version level)
now that we've got more of the functions in a good state: it's easier
when adding them incrementally.

Rather than wrap _arguments directly, it might be more flexible to have
some sort of filter_args helper. That could also be applied around
_values too for, e.g. dd or ifconfig. It could allow for custom
letter mappings and have the option of making other transformations on
the args list before going on to _arguments. It might also be easier to
mix with _arguments' sets feature.

Long options can pose a bigger challenge when trying to handle different
systems. There are a few GNU utilities such as grep where FreeBSD and
Darwin have forked at the final GPL2 release. So I can see there being
more cases where we need to handle these with associated issues such as
sharing the latter part of the _arguments spec (description etc) between
the long and short option. I'd regard alphabetization of options to be
a lesser concern. For single implementation commands, I try to follow
the ordering from -h / --help output which is usually a mix of logical,
alphabetical and some randomness. And sometimes it'd be more helpful to
have them ordered with options that have similar mutual exclusions.

> +case $OSTYPE in
> +  aix*) os=A;;
> +  cygwin*) os=C;;

Note that this case statement could be done as an associative array. I
mention this mainly because an associative array is easier to extend if
we were to support that:
  typeset -A osabbrev
  osabbrev=( 'linux*' L 'openbsd*' O ..... )
  os=${a[(k)$OSTYPE]}

Oliver


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-12-13  1:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-12  5:28 _os_arguments Matthew Martin
2016-12-12  8:52 ` _os_arguments Daniel Shahaf
2016-12-13  0:54 ` _os_arguments Oliver Kiddle

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).