Browse Source

refactored plugin file + updated readme's

Diana Arreola 4 years ago
parent
commit
3b41349862

+ 1 - 12
README.rst

@@ -200,18 +200,7 @@ Then, install all necessary packages:
 
     npm install
 
-To compile and run the script:
-
-::
-
-    npm run build
-
-To run the testing script:
-
-::
-
-    npm test
-
+Continue to the ``README.md`` within the ``extension/code-editor-integration`` folder for an in depth explanation.
 
 Visual Studio Code Extension
 ~~~~~~~~~~~~~~~~~~~~~~

+ 18 - 1
extension/code-editor-integration/README.md

@@ -48,7 +48,7 @@ To run the testing script:
 
     npm test
 
-## Usage
+## Integration
 
 To utilize this plug-in to create a howdoi extension for a code editor: 
 
@@ -65,3 +65,20 @@ To utilize this plug-in to create a howdoi extension for a code editor:
 3. Call the `runHowdoi` function.
 
 Refer to `vscode-howdoi` for an example.
+
+## Usage
+
+usage: 
+    
+    // howdoi query [-n NUM_ANSWERS]
+
+positional arguments:
+
+      QUERY                 the question to answer
+
+optional arguments:
+
+      -n NUM_ANSWERS        NUM_ANSWERS
+                            number of answers to return
+                            (default: 3)
+

+ 28 - 0
extension/code-editor-integration/src/create_attributes.ts

@@ -0,0 +1,28 @@
+'use strict'
+import {HowdoiObj, JSONObj, CommentChars} from './plugin_interfaces'
+
+export function createComment(command: string, commentChar: CommentChars): string {
+  // adds single line comment to string provided
+  const frontCommentChar: string = commentChar.frontComment
+  const endCommentChar: string = commentChar.endComment
+  if (frontCommentChar && (endCommentChar !== '')) {
+    const commentedCommand: string = frontCommentChar + ' ' + command + ' ' + endCommentChar
+    return commentedCommand
+  }
+  const commentedCommand: string = frontCommentChar + ' ' + command
+  return commentedCommand
+}
+
+export function createHowdoiObj(parsedJson: JSONObj[], userCommand: string, commentChar: CommentChars): HowdoiObj {
+  // creates a HowdoiObj interface 
+  const howdoiObj: HowdoiObj = {question: userCommand, answer: [], link: []}
+
+  for (let i = 0; i < parsedJson.length; i++) {
+    if (parsedJson[i].answer.trim() === 'end=\'\'') { 
+      break
+    }
+    howdoiObj.answer.push(parsedJson[i].answer.trim())
+    howdoiObj.link.push(createComment(parsedJson[i].link.trim(), commentChar))
+  }
+  return howdoiObj
+}

+ 53 - 0
extension/code-editor-integration/src/find_attributes.ts

@@ -0,0 +1,53 @@
+'use strict'
+import {CommentChars} from './plugin_interfaces'
+
+export function findCommentChar(userCommand: string): CommentChars { 
+  /* This function finds the comment regex, removes it from the string and returns a
+    CommentChars interface with the beginning comment regex and ending comment regex or returns
+    null if there is no comment regex/an invalid comment regex */
+  const frontCommentRegex =  /^[!@#<>/;%*(+=._-]+/
+  const endCommentRegex = /[!@#<>/%*+=._-]+$/
+  let frontCommentChar: string
+  let endCommentChar: string
+  let userCommandWithoutComment: CommentChars
+  const initialMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
+  const endMatchRegex: RegExpMatchArray | null = userCommand.match(endCommentRegex)
+        
+  if (initialMatchRegex && endMatchRegex){
+    frontCommentChar = initialMatchRegex.join()
+    endCommentChar = endMatchRegex.join()
+    userCommandWithoutComment = {
+      frontComment: frontCommentChar,
+      endComment: endCommentChar
+    }
+    return userCommandWithoutComment
+  }
+  else if(initialMatchRegex){
+    frontCommentChar = initialMatchRegex.join()
+    userCommandWithoutComment = {
+      frontComment: frontCommentChar,
+      endComment: ''
+    }
+    return userCommandWithoutComment
+  }
+  else {
+    throw Error('Invalid line comment. Please use single line comment for howdoi.')
+  }
+}
+
+export function findNumFlagVal(userCommand: string): number { 
+  /* This function finds the numFlag value within the userCommand and returns the value */
+  const numFlag =  '-n'
+  const defaultNumFlag = 3
+  const index = userCommand.indexOf(numFlag)
+   
+  if (index === -1){
+    return defaultNumFlag
+  }
+
+  const userNumFlag = Number(userCommand.slice(index).replace(numFlag, '').trim())
+  if (isNaN(userNumFlag) || (userNumFlag === 0)) {
+    throw new RangeError('Invalid num flag value')
+  }
+  return userNumFlag
+}

+ 28 - 107
extension/code-editor-integration/src/plugin.ts

@@ -1,76 +1,16 @@
 'use strict'
 import * as cp from 'child_process'
 import {once} from 'events'
-
-const HOWDOI_PREFIX = 'howdoi'
-
-interface HowdoiObj {
-  question: string
-  answer: string[]
-  link: string[]  
-}
-
-interface JSONObj {
-  answer: string
-  link: string
-  position: string
-}
-
-interface CommentChars {
-  frontComment: string
-  endComment: string
-}
-
-export function findCommentChar(userCommand: string): CommentChars { 
-  /* This function finds the comment regex, removes it from the string and returns a
-   CommentChars interface with the beginning comment regex and ending comment regex or returns
-   null if there is no comment regex or an invalid comment regex*/
-  const frontCommentRegex =  /^[!@#<>/;%*(+=._-]+/
-  const endCommentRegex = /[!@#<>/%*+=._-]+$/
-  let frontCommentChar: string
-  let endCommentChar: string
-  let userCommandWithoutComment: CommentChars
-  const initialMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
-  const endMatchRegex: RegExpMatchArray | null = userCommand.match(endCommentRegex)
-        
-  if (initialMatchRegex && endMatchRegex){
-    frontCommentChar = initialMatchRegex.join()
-    endCommentChar = endMatchRegex.join()
-    userCommandWithoutComment = {
-      frontComment: frontCommentChar,
-      endComment: endCommentChar
-    }
-    return userCommandWithoutComment
-  }
-  else if(initialMatchRegex){
-    frontCommentChar = initialMatchRegex.join()
-    userCommandWithoutComment = {
-      frontComment: frontCommentChar,
-      endComment: ''
-    }
-    return userCommandWithoutComment
-  }
-  else {
-    throw Error('Invalid line comment. Please use single line comment for howdoi.')
-  }
-}
-
-export function removeCommentChar(userCommand: string, commentChar: CommentChars): string {
-  // removes single line comment regex from the user command
-  const frontCommentChar: string = commentChar.frontComment
-  const endCommentChar: string = commentChar.endComment
-
-  if (!userCommand.includes(endCommentChar)) {
-    return userCommand.replace(frontCommentChar, '').trim()
-  }
-  userCommand = userCommand.replace(frontCommentChar, '')
-  return userCommand.replace(endCommentChar, '').trim()
-}
-
-export async function retrieveHowdoiOutput(command: string): Promise<JSONObj[]> {
-  // spawns an external application in a new process to run the howdoi query and retreives
-  // the howdoi query answer 
-  const process = cp.spawn(HOWDOI_PREFIX, [command, '-n3', '-j'])
+import {HOWDOI_PREFIX, HowdoiObj, JSONObj, CommentChars} from './plugin_interfaces'
+import * as removeRegex from './remove_regexes'
+import * as findAttr from './find_attributes'
+import * as createAttr from './create_attributes'
+
+export async function retrieveHowdoiOutput(command: string, numFlagVal: number): Promise<JSONObj[]> {
+  /* This function spawns an external application in a new process to run the howdoi query and returns
+  the howdoi query answer formatted as a JSONObj[] */
+  const numFlag: string = '-n' + String(numFlagVal)
+  const process = cp.spawn(HOWDOI_PREFIX, [command, numFlag, '-j'])
   let howdoiJSON: JSONObj[] = [{ answer: '', link: '', position: ''}]
   
   process.stdout.on('data', (data: string) => {
@@ -99,67 +39,48 @@ export async function retrieveHowdoiOutput(command: string): Promise<JSONObj[]>
   return howdoiJSON
 }
 
-export function removeHowdoiPrefix(command: string): string {
-  // removes the prefix `howdoi` from the string
-  if (!command.trim().startsWith(HOWDOI_PREFIX)) {
-    throw Error('Place "howdoi" in front of query')
-  }
-  return command.replace(HOWDOI_PREFIX, '').trim()
-}
-
-export function addComment(command: string, commentChar: CommentChars): string {
-  // adds single line comment to string provided
-  const frontCommentChar: string = commentChar.frontComment
-  const endCommentChar: string = commentChar.endComment
-  if (frontCommentChar && (endCommentChar !== '')) {
-    const commentedCommand: string = frontCommentChar + ' ' + command + ' ' + endCommentChar
-    return commentedCommand
-  }
-  const commentedCommand: string = frontCommentChar + ' ' + command
-  return commentedCommand
-}
-
-export function createHowdoiObj(parsedJson: JSONObj[], userCommand: string, commentChar: CommentChars): HowdoiObj {
-  // creates a HowdoiObj interface 
-  const howdoiObj: HowdoiObj = {question: userCommand, answer: [], link: []}
-
-  for (let i = 0; i < parsedJson.length; i++) {
-    howdoiObj.answer.push(parsedJson[i].answer.trim())
-    howdoiObj.link.push(addComment(parsedJson[i].link.trim(), commentChar))
-  }
-  return howdoiObj
-}
-
-
 export async function runHowdoi(userCommand: string): Promise<HowdoiObj> {
+  /* This functions modifies the users command while checking for errors
+  and formats the howdoi query answer into a HowdoiObj*/
   
   let commentChar: CommentChars
   // check if query is enclosed by a single line comment and return commentChar
   try {
     // retrieve single line comment and store in CommentChars obj
-    commentChar = findCommentChar(userCommand)
+    commentChar = findAttr.findCommentChar(userCommand)
   }catch (e) {
     throw new ReferenceError('Invalid line comment. Please use single line comment for howdoi.')
   }
   
-  const commandWithoutComment: string = removeCommentChar(userCommand, commentChar)
+  const commandWithoutComment: string = removeRegex.removeCommentChar(userCommand, commentChar)
   let commandWithoutPrefix: string
 
   // check if howdoi prefix is present and remove it
   try {
-    commandWithoutPrefix = removeHowdoiPrefix(commandWithoutComment)
+    commandWithoutPrefix = removeRegex.removeHowdoiPrefix(commandWithoutComment)
   }catch (e) {
     throw new SyntaxError('Place "howdoi" in front of query')
   }
 
+  let numFlagVal: number
+  // check if -n flag is present and remove it
+  try {
+    numFlagVal = findAttr.findNumFlagVal(commandWithoutPrefix)
+  }catch (e) {
+    throw new RangeError('Invalid num flag value')
+  }
+
+  const commandWithoutFlag = removeRegex.removeNumFlag(commandWithoutPrefix)
+
   let parsedJson: JSONObj[] 
   // check if howdoi output is valid and save the JSON Obj
   try {
-    parsedJson = await retrieveHowdoiOutput(commandWithoutPrefix)
+    parsedJson = await retrieveHowdoiOutput(commandWithoutFlag, numFlagVal)
   }catch (e) {
     throw new Error('Invalid json object or no json object returned')
   }
   
-  const howdoiResultObj = createHowdoiObj(parsedJson, userCommand, commentChar)
+  let howdoiResultObj = createAttr.createHowdoiObj(parsedJson, userCommand, commentChar)
+  howdoiResultObj = removeRegex.removeInlineRegex(howdoiResultObj)
   return howdoiResultObj
 }

+ 18 - 0
extension/code-editor-integration/src/plugin_interfaces.ts

@@ -0,0 +1,18 @@
+export const HOWDOI_PREFIX = 'howdoi'
+
+export interface HowdoiObj {
+  question: string
+  answer: string[]
+  link: string[]  
+}
+
+export interface JSONObj {
+  answer: string
+  link: string
+  position: string
+}
+
+export interface CommentChars {
+  frontComment: string
+  endComment: string
+}

+ 52 - 0
extension/code-editor-integration/src/remove_regexes.ts

@@ -0,0 +1,52 @@
+'use strict'
+import {HOWDOI_PREFIX, HowdoiObj, CommentChars} from './plugin_interfaces'
+
+export function removeCommentChar(userCommand: string, commentChar: CommentChars): string {
+  /* This function removes the single line comment regex from the userCommand and returns it*/
+  const frontCommentChar: string = commentChar.frontComment
+  const endCommentChar: string = commentChar.endComment
+
+  if (!userCommand.includes(endCommentChar)) {
+    return userCommand.replace(frontCommentChar, '').trim()
+  }
+  userCommand = userCommand.replace(frontCommentChar, '')
+  return userCommand.replace(endCommentChar, '').trim()
+}
+
+export function removeHowdoiPrefix(command: string): string {
+  // removes the prefix `howdoi` from the string
+  if (!command.trim().startsWith(HOWDOI_PREFIX)) {
+    throw Error('Place "howdoi" in front of query')
+  }
+  return command.replace(HOWDOI_PREFIX, '').trim()
+}
+
+export function removeNumFlag(userCommand: string): string { 
+  /* This function removes the numFlag value within the userCommand and returns userCommand */
+  const numFlag =  '-n'
+  const index = userCommand.indexOf(numFlag)
+   
+  if (index === -1){
+    return userCommand
+  }
+  const commandWithoutNumFlag = userCommand.slice(0, index).trim()
+  return commandWithoutNumFlag
+}
+
+export function removeInlineRegex(howdoiResultObj: HowdoiObj): HowdoiObj {
+  /* This function returns a HowdoiObj that has the arrow and dot regexes removed
+  from the answer array to display inline code more cleanly */
+
+  const arrowRegex = /[>->->]{3}/g
+  const dotRegex = /[.-.-.]{3}/g
+
+  for (let i = 0; i < howdoiResultObj.answer.length; i++) {
+    if (howdoiResultObj.answer[i].match(arrowRegex)) {
+      howdoiResultObj.answer[i] = howdoiResultObj.answer[i].replace(arrowRegex, '').trim()
+    }
+    if (howdoiResultObj.answer[i].match(dotRegex)) {
+      howdoiResultObj.answer[i] = howdoiResultObj.answer[i].replace(dotRegex, '').trim()
+    }
+  }
+  return howdoiResultObj
+}

+ 81 - 23
extension/code-editor-integration/src/test/plugin.test.ts

@@ -1,60 +1,101 @@
 import { assert, expect} from 'chai'
 import {suite, test} from 'mocha'
-import * as plugin from '../plugin'
-
+import {CommentChars} from '../plugin_interfaces'
+import * as removeRegex from '../remove_regexes'
+import * as findAttr from '../find_attributes'
+import * as createAttr from '../create_attributes'
 
 suite('Plugin Tests', function () {
   //  //: JS, TS, C/ C++/ C#, Java, GO, Rust, Scala, Swift, J#, Dlang single line comment
-  const commentChar1 = {frontComment: '//', endComment: ''}
+  const commentChar1: CommentChars = {frontComment: '//', endComment: ''}
   // #: Python, Ruby, powershell, Julia, R, prolog, Crystal, Dockerfile, Diff single line comment
-  const commentChar2 = { frontComment: '#', endComment: '' }
+  const commentChar2: CommentChars = { frontComment: '#', endComment: '' }
   // /* */: C++, CSS single line comment 
-  const commentChar3 = { frontComment: '--', endComment: '' }
+  const commentChar3: CommentChars = { frontComment: '--', endComment: '' }
   // <!-- -->: HTML, PHP, Markdown, Vue single line comment
-  const commentChar4 = { frontComment: '%', endComment: '' }
+  const commentChar4: CommentChars = { frontComment: '%', endComment: '' }
   // --: SQL, Haskell single line comment
-  const commentChar5 = { frontComment: ';', endComment: '' }
+  const commentChar5: CommentChars = { frontComment: ';', endComment: '' }
   // %: LaTex single line comment
-  const commentChar6 = { frontComment: '/*', endComment: '*/' }
+  const commentChar6: CommentChars = { frontComment: '/*', endComment: '*/' }
   // ;: clojure single line comment
-  const commentChar7 = { frontComment: '<!--', endComment: '-->' }
+  const commentChar7: CommentChars = { frontComment: '<!--', endComment: '-->' }
   /* eslint-disable prefer-const*/
-  const commentCharArr = [commentChar1, commentChar2, commentChar3, commentChar4, commentChar5, commentChar6, 
-    commentChar7]
+  const commentCharArr: CommentChars[] = [commentChar1, commentChar2, commentChar3, commentChar4, commentChar5, 
+    commentChar6, commentChar7]
+
+  // Global function used for #findNumFlagVal and #removeNumFlag
+  function getRandomInt(max: number): number {
+    return Math.floor(Math.random() * Math.floor(max))
+  }
 
   suite('Find comment regex in string -> #findCommentChar', function () {
     test('String w/o comment regex', function () {
       // error example
       const err = 'Invalid line comment. Please use single line comment for howdoi.' 
       expect(function(){
-        plugin.findCommentChar('howdoi query')
+        findAttr.findCommentChar('howdoi query')
       }).to.throw(err)
     })
     test('Comment regex test (w/ space): //, #, --, %, ;, /* */, <!-- -->', function () {
       for (let commentChar of commentCharArr) {
         let commentedQuery = commentChar.frontComment + ' howdoi query ' + commentChar.endComment
-        assert.deepEqual(plugin.findCommentChar(commentedQuery), commentChar)
+        assert.deepEqual(findAttr.findCommentChar(commentedQuery), commentChar)
       }   
     })
     test('Comment regex test (w/o space): //, #, --, %, ;, /* */, <!-- -->', function () {
       for (let commentChar of commentCharArr) {
         let commentedQuery = commentChar.frontComment + 'howdoi query' + commentChar.endComment
-        assert.deepEqual(plugin.findCommentChar(commentedQuery), commentChar)
+        assert.deepEqual(findAttr.findCommentChar(commentedQuery), commentChar)
       }   
     })
   })
 
+  suite('Find the Num Flag value from the user command -> #findNumFlagVal', function () {
+    test('error examples', function () {
+      const err = 'Invalid num flag value' 
+      expect(function(){
+        findAttr.findNumFlagVal('query -n')
+      }).to.throw(err)
+      expect(function(){
+        findAttr.findNumFlagVal('query -nzl')
+      }).to.throw(err)
+    })
+    test('testing default num 3', function () {
+      assert.equal(findAttr.findNumFlagVal('query -n3'), 3)
+      assert.equal(findAttr.findNumFlagVal('query -n 3'), 3)
+    })
+    test('testing non-default numbers', function () {
+      const maxNum = 25
+      for (let i = 0; i < maxNum; i++) {
+        const randomNum = getRandomInt(maxNum)
+        const query1 = 'query -n' + String(randomNum)
+        const query2 = 'query -n ' + String(randomNum)
+        if (randomNum === 0) {
+          const err = 'Invalid num flag value'
+          expect(function(){
+            findAttr.findNumFlagVal(query1)
+          }).to.throw(err)
+        }
+        else {
+          assert.equal(findAttr.findNumFlagVal(query1), randomNum)
+          assert.equal(findAttr.findNumFlagVal(query2), randomNum)
+        }
+      }
+    })
+  })
+
   suite('Removal of comment character from user command -> #removeCommentChar', function () {
     test('Removal of front and front/back comment char (w/ space): //, #, --, %, ;, /* */, <!-- -->', function () {
       for (let commentChar of commentCharArr) {
         let commentedQuery = commentChar.frontComment + ' howdoi query ' + commentChar.endComment
-        assert.equal(plugin.removeCommentChar(commentedQuery, commentChar), 'howdoi query')
+        assert.equal(removeRegex.removeCommentChar(commentedQuery, commentChar), 'howdoi query')
       } 
     })
     test('Removal of front and front/back comment char (w/o space): //, #, --, %, ;, /* */, <!-- -->', function () {
       for (let commentChar of commentCharArr) {
         let commentedQuery = commentChar.frontComment + 'howdoi query' + commentChar.endComment
-        assert.equal(plugin.removeCommentChar(commentedQuery, commentChar), 'howdoi query')
+        assert.equal(removeRegex.removeCommentChar(commentedQuery, commentChar), 'howdoi query')
       } 
     })
   })
@@ -62,30 +103,47 @@ suite('Plugin Tests', function () {
   suite('Removal of howdoi prefix test -> #removeHowdoiPrefix', function () {
     test('Normal Query', function () {
       // Normal Query
-      assert.equal(plugin.removeHowdoiPrefix('howdoi query'), 'query')
+      assert.equal(removeRegex.removeHowdoiPrefix('howdoi query'), 'query')
     })
     test('Query with whitespace', function () {
       // Query with whitespace
-      assert.equal(plugin.removeHowdoiPrefix(' howdoi query '), 'query')
+      assert.equal(removeRegex.removeHowdoiPrefix(' howdoi query '), 'query')
     })
     test('Query without howdoi prefix', function () {
       // Query without howdoi prefix
       const err = 'Place "howdoi" in front of query' 
       expect(function(){
-        plugin.removeHowdoiPrefix('query')
+        removeRegex.removeHowdoiPrefix('query')
       }).to.throw(err)
     })
     test('Query without howdoi prefix and whitespace', function () {
       // Query without howdoi prefix and whitespace
       const err = 'Place "howdoi" in front of query'
       expect(function(){
-        plugin.removeHowdoiPrefix(' query ')
+        removeRegex.removeHowdoiPrefix(' query ')
       }).to.throw(err)
     })
   })
 
-  suite('Add comment character to a string -> #addComment', function () {
-    test('Add comment with front & front/back char to string: //, #, --, %, ;, /* */, <!-- -->', function () {
+  suite('Remove the Num Flag and value from the user command -> #removeNumFlag', function () {
+    test('testing default num 3', function () {
+      assert.equal(removeRegex.removeNumFlag('query -n3'), 'query')
+      assert.equal(removeRegex.removeNumFlag('query -n 3'), 'query')
+    })
+    test('testing non-default numbers', function () {
+      const maxNum = 25
+      for (let i = 0; i < maxNum; i++) {
+        const randomNum = getRandomInt(maxNum)
+        const query1 = 'query -n' + String(randomNum)
+        const query2 = 'query -n ' + String(randomNum)
+        assert.equal(removeRegex.removeNumFlag(query1), 'query')
+        assert.equal(removeRegex.removeNumFlag(query2), 'query')
+      }
+    })
+  })
+
+  suite('Create comment character to a string -> #createComment', function () {
+    test('Creare comment with front & front/back char to string: //, #, --, %, ;, /* */, <!-- -->', function () {
       let testString = ''
       for (let commentChar of commentCharArr) {
         if (commentChar.frontComment && (commentChar.endComment !== '')) {
@@ -94,7 +152,7 @@ suite('Plugin Tests', function () {
         else {
           testString = commentChar.frontComment + ' howdoi query'
         }
-        assert.equal(plugin.addComment('howdoi query', commentChar), testString)
+        assert.equal(createAttr.createComment('howdoi query', commentChar), testString)
       }   
     })
   })

+ 24 - 10
extension/vscode-howdoi/README.md

@@ -9,7 +9,7 @@ Suppose you want to know how to format a date in bash. Why open your browser and
 
 howdoi will answer all sorts of queries:
 <!-- howdoi print stack trace python gif-->
-![howdoi format bash date](https://i.imgur.com/8D5wiM4.gif)
+![howdoi print stack trace python](https://i.imgur.com/8D5wiM4.gif)
 
 ## Installation
 
@@ -22,16 +22,13 @@ The howdoi extension allows users to ask howdoi within their own code editor.
 For usage within the code editor:
 
 1. Write down your question in the code editor commented out with a single line comment. 
-    - Toggling a line comment can be done by: 
 
-          cmd + /
-
-        or 
-
-          Edit > Toggle Line Comment
+    ![up close howdoi print stack trace python](https://i.imgur.com/NLYeTNs.gif)
 
 2. Highlight the text from the first step.
 
+    ![highlighted howdoi print stack trace python](https://i.imgur.com/58x3QbQ.gif)
+
 3. Open the command palette using:
 
         cmd/ctrl + shift + P
@@ -39,12 +36,29 @@ For usage within the code editor:
     
         View > Command Palette
 
-4. Run howdoi in command palette.
+4. Run howdoi in command palette and choose among three answers from the drop down.
+
+    ![highlighted howdoi print stack trace python](https://i.imgur.com/92c0xVM.gif)
+
+## Usage
+
+usage: 
+    
+    // howdoi query [-n NUM_ANSWERS]
+
+positional arguments:
+
+      QUERY                 the question to answer
+
+optional arguments:
 
-5. Choose among three answers from the drop down.
+      -n NUM_ANSWERS        NUM_ANSWERS
+                            number of answers to return
+                            (default: 3)
 
-6. The answer will be displayed in the code editor along with the question and link.
+example:
 
+  ![highlighted howdoi print stack trace python](https://i.imgur.com/9WGSL2y.gif)    
 
 
 ## Release Notes

+ 4 - 4
extension/vscode-howdoi/src/extension.ts

@@ -1,7 +1,6 @@
 import * as vscode from 'vscode'
 import * as plugin from './code-editor-integration/src/plugin'
 
-
 export function activate(context: vscode.ExtensionContext) {
 
   let disposable = vscode.commands.registerCommand('howdoi.extension', async () => {
@@ -24,7 +23,10 @@ export function activate(context: vscode.ExtensionContext) {
       } else if (e instanceof SyntaxError) {
         vscode.window.showInformationMessage('Place "howdoi" in front of query')
         return e
-      }else if (e instanceof Error) {
+      } else if (e instanceof RangeError) {
+        vscode.window.showInformationMessage('Invalid num flag value')
+        return e
+      } else if (e instanceof Error) {
         vscode.window.showInformationMessage('Could not find response for query')
         return e
       } else {
@@ -34,8 +36,6 @@ export function activate(context: vscode.ExtensionContext) {
     } 
 
     quickPicker(editor, howdoiResultObj, userCommand)
-  
- 
   })
   context.subscriptions.push(disposable)
 }