Node.js optimist module - assign all arguments following flag to flag

I am using optimist for node.js, and want to parse the input like this:

$ command some args -m this is the message

into this

{argv:{_:['some','args'],m:'this is the message'}}

is this possible with optimist? is this possible in general?

In general it's the responsibility of the shell to group space-containing arguments, not the argument parser. This is generally done by the user quoting multi-word arguments (single or double quotes in Unix-type shells, only double quotes are recognized in Windows).

In Optimist you could do something like:

var argv=require('optimist').argv;
if (argv.m) {
  argv.m=argv.m+' '+argv._.join(' ');
}

which would work as you expect if -m is the last argument. However, if you did something like command ... -m hello there -q now here, argv.m would wind up being "hello there here" which is probably not what you'd want.

I ended up doing this, which works for my use case:

#!/usr/bin/env coffee

args = process.argv

o = {_:[],$0:[]}
flags = {s:'state',m:'message',e:'editor',t:'type'}
i = -2
na = false # next argument: false/opt/flag

for arg in args
  if m = arg.match /^--(.+?)(=(.+))?$/
    na = m[1]
    o[m[1]] = m[3] || true
  else if m = arg.match /^-(.+)/
    na = flags[m[1]]
    o[na] = true
    if !na
      console.log 'Unknown flag: '+m[1]
      process.exit 1
  else if ++i > 0 # ignore first two args which are node and app
    if na == 'message'
      o.message = [arg]
    else if na != false
      o[na] = arg
    else
      if o.message
        o.message.push arg
      else
        o._.push arg
    na = false
  else
    o['$0'].push arg

if o.message
  o.message = o.message.join ' '

console.log o

EDIT:

Actually there are still problems with this method. I ended up doing something else, but am still in search of a better solution. I think I am going to end up writing a small peg parser to parse the command line options how I want.