Repository: yargs/yargs (js)

Issue:
Bash completion:  Long vs short options and number of dashes
When using the bash completion feature, yargs completes short options with two
leading dashes instead of just one:

test.js:

``` javascript
var argv = require('yargs')
  .alias('l', 'long')
  .describe('l', 'an option')
  .help('h')
  .alias('h', 'help')
  .completion('completion')
  .argv;

console.log(argv);
```

```
$ node test.js --get-yargs-completions
--l
--h
```

This isn't a huge issue because using the double-dashed short options still works:

```
$ node test.js --l foo
{ _: [],
  h: false,
  help: false,
  l: 'foo',
  long: 'foo',
  '$0': 'test.js' }
```

But I think it would be much better to always use the long options for completions, as they are generally more descriptive. If a long option is not available it should fall back to the single-dashed short version.


Pull request description:
feat: complete short options with a single dash
When the user did not already enter two dashes, and when the option is not a single digit one.

Closes #265 

Patch:
diff --git a/lib/completion.js b/lib/completion.js
index 8c2363e..b48bba5 100644
--- a/lib/completion.js
+++ b/lib/completion.js
@@ -81,11 +81,14 @@ module.exports = function completion (yargs, usage, command) {
         const keyAndAliases = [key].concat(aliases[key] || [])
         const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1)
         if (notInArgs) {
+          const startsByTwoDashes = s => /^--/.test(s)
+          const isShortOption = s => /^[^0-9]$/.test(s)
+          const dashes = !startsByTwoDashes(current) && isShortOption(key) ? '-' : '--'
           if (!zshShell) {
-            completions.push(`--${key}`)
+            completions.push(dashes + key)
           } else {
             const desc = descs[key] || ''
-            completions.push(`--${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`)
+            completions.push(dashes + `${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`)
           }
         }
       })


Test patch:
diff --git a/test/completion.js b/test/completion.js
index a2036af..f553804 100644
--- a/test/completion.js
+++ b/test/completion.js
@@ -58,6 +58,42 @@ describe('Completion', () => {
       r.logs.should.not.include('--foo')
     })
 
+    it('completes short options with a single dash when the user did not already enter two dashes', () => {
+      const r = checkUsage(() => yargs(['./completion', '--get-yargs-completions', './completion', ''])
+        .options({
+          f: { describe: 'f option', alias: 'foo' }
+        })
+        .argv
+      )
+
+      r.logs.should.include('-f')
+      r.logs.should.not.include('--f')
+    })
+
+    it('completes short options with two dashes when the user already entered two dashes', () => {
+      const r = checkUsage(() => yargs(['./completion', '--get-yargs-completions', './completion', '--'])
+        .options({
+          f: { describe: 'f option', alias: 'foo' }
+        })
+        .argv
+      )
+
+      r.logs.should.include('--f')
+      r.logs.should.not.include('-f')
+    })
+
+    it('completes single digit options with two dashes', () => {
+      const r = checkUsage(() => yargs(['./completion', '--get-yargs-completions', './completion', ''])
+        .options({
+          1: { describe: '1 option', alias: 'one' }
+        })
+        .argv
+      )
+
+      r.logs.should.include('--1')
+      r.logs.should.not.include('-1')
+    })
+
     it('completes options for the correct command', () => {
       process.env.SHELL = '/bin/bash'
       const r = checkUsage(() => yargs(['./completion', '--get-yargs-completions', 'cmd2', '--o'])
@@ -98,7 +134,7 @@ describe('Completion', () => {
       r.logs.should.include('cmd1')
     })
 
-    it('does not include possitional arguments', function () {
+    it('does not include positional arguments', function () {
       process.env.SHELL = '/bin/bash'
       var r = checkUsage(function () {
         return yargs(['./completion', '--get-yargs-completions', 'cmd'])