Skip to content

Argparse : save list of 'consumed arguments' into additional variable #6466

Closed

Description

@0ion9

Presently, when writing wrapper scripts, it is necessary to first define which arguments need to be passed through:

argparse d/directory f/file 0/print0 c/count p/path= e/explicit s/sort i/ignore-case -- $argv

Then, for options which accept arguments, some additional mangling is required to restore a -flag which the program will recognize:

  if test -n "$_flag_p"
    set _flag_p -p $_flag_p 
  end

You must compile a list of options to pass along, which partially repeats the information stated in the call to argparse:

set -l newargs (set f _flag_{0,c,d,e,f,i,p,s}; printf %s\n $$f)

After the wrapper makes its particular modification to the arguments,
you can finally invoke the program you are wrapping:

tmsu files $newargs

This is overly involved and repetitive.

====

My suggested solution is that argparse should additionally save a list of consumed arguments, to a variable like _argparse_option_args. This allows to use argparse for wrapping in a way that is more precise and obviously-structured: 'sort options from non-options, then pass options in unmodified'

With this proposal, the process would instead look like this:

# parse, same as before:
argparse d/directory f/file 0/print0 c/count p/path= e/explicit s/sort i/ignore-case -- $argv

# wrapper-specific code generating a list of additional arguments goes here...
# [...]

# invoke wrapped program:

tmsu files $_argparse_option_args $generated_args

With no repetition of information or need to read through to determine which options are 'inherited' and which are generated by the wrapper.

Technical specifics:

If consumed arguments can be stored immediately after they are parsed, this would be ideal for two reasons:

  • it preserves the exact ordering of options, which may be important if they are going to be shown to the user.
  • it avoids some potential confusion that could be otherwise produced when 'reconstituting' options which accept multiple arguments or accept only the last instance of an argument (=+ and =? argspecs)

EDIT: Technically, it's possible to do something like this without having argparse's privileged access to variables. It's just kind of awkward and hacky:

function apwrap -w argparse 
  set sep_index (contains -i -- -- $argv)
  set args_index (math $sep_index+1)
  set old_args $argv[$args_index..-1]
  argparse $argv

  # store options in the order they were originally specified.
  # technically, using sort, comm, and grep might be faster for long arg lists.
  set option_args 
  set nonoption_args
  for v in $old_args
    if not contains -- $v $argv
      set -a option_args "$v"
    else
      set -a nonoption_args "$v"
    end
  end

  # 1. items present in old_args, but not modified argv
  # 2. Abuse of control codes to create an identifiable separator
  # 3. everything else

  printf %s\n $option_args
  printf \t\r\t\r\n
  printf %s\n $nonoption_args
     
end

set optspec o/output=

# returns -o boot \t\r\t\r baz www
set a (apwrap $optspec -- -o boot baz www)

set asep (contains -i \t\r\t\r $a); set asep (math $asep-1) (math $asep+1)

# assigns the value '-o' 'boot'
set optargs $a[1..$asep[1]]

# assigns the value 'baz' 'www'
set nonoptargs $a[$asep[2]..-1]

# then if you want to be able to inspect _flag_o in the normal manner, you need to reparse optargs,
argparse $optspec -- $optargs

# overall, it avoids repetition of option information, but introduces tedious boilerplate.

Activity

  1. added this to the fish-future milestone on Jan 5, 2020
  2. modified the milestones: fish-future, fish 4.1 on Aug 18, 2025
  3. added 3 commits that reference this issue on Aug 19, 2025
    e489fb6
    36e2176
    e62abc4
  4. locked as resolved and limited conversation to collaborators on Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions