/promptie

A framework written in Vue.js for creating command-line like interfaces in web browsers.

Primary LanguageJavaScriptMIT LicenseMIT


promptie
promptie

A framework for creating command-line like interfaces in web browsers

Promptie gives you useful and convenient API's to simulate a CLI like interface in the browser. You can easily write your own applications in it and you can even pipe the outputs of your applications to each other.

promptie demo
promptie demo

Table of contents

Running and Building

Instructions below are tested with NodeJS v7.7.2 and works with yarn package manager as well.

# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# build for production with minification
npm run build

# build for production and view the bundle analyzer report
npm run build --report

Creating an application

Creating an application is very easy in promptie. Just create a folder inside src/bin with the name of your application and put an index.js file inside it. index.js should export a function that returns a javascript Promise. This exported function has two parameters:

screen provides utilities to print text or html on Screen

args is a js object wrapping the parsed command line arguments. Promptie uses minimist to parse arguments, you can check the github page to learn more.

resolve method of the promise takes two arguments. out is a string argument that represents the final output of your application. This is the output that gets piped while using pipes. The second argument is silent. It is a boolean, optional value, false by default. If it is true or left blank, your final output will be printed on the screen on application exit.

Here is an example application that basically colorize the input string. You can check the bin folder to see some other application examples.

import paint from '../system/paint'

export default function (screen, args) {
  return new Promise((resolve) => {
    const colors = ['red', 'yellow', 'green', 'blue', 'magenta', 'cyan']
    let output = ''
    args._plain.split('').forEach(function (char, index) {
      output += paint(char, {styles: [colors[index % colors.length]]})
    })
    resolve(output)
  })
}

API

Promptie has two main API's, Screen and Prompt.

Screen

  • lines: An array containing all the lines on the Screen.
Screen.lines = []
  • push: Pushes a line to the Screen. If you want to escape html, you can pass true as the second parameter.
Screen.push(line, escapeHtml = false)
  • pushNewLine: Pushes a new empty line.
Screen.pushNewLine()
  • replaceLastLine: Replaces last line on the Screen with the given line.
Screen.replaceLastLine(line)
  • removeLastLine: Removes the last line from Screen.
Screen.removeLastLine()
  • clean: Clears all the lines from Screen.
Screen.removeLastLine()

Prompt

  • prompt: A property used to set the prompt text. Default is >.
Prompt.prompt = '$'
  • disabled: A boolean value if set to false the prompt will be disabled.
Prompt.disabled = false
  • getCaretPosition: Returns the caret position index.
Prompt.getCaretPosition()
  • setCaretPostion: Sets the caret position to given index.
Prompt.setCaretPostion(index)
  • pushCaretToEnd: Pushes caret to the end of the line.
Prompt.pushCaretToEnd()

System

System provides a couple of helpers to be used in your application.

Runner

This is a special type of system helper that is used to run commands in promptie and also can be imported to your applications to run other commands within your application. Runner js has two main methods to parse commands

  • static run (command): Runs the given command string.
Runner.run('movie Eternal Sunshine of the Spotless Mind')
  • static async runPipe (command): Runs the given piped command list string. Uses async/await to wait for applications to finish and pass their outputs to other applications.
import Runner from '../system/runner'
// Passes the string to movie app which queries the OMDB and returns 
// the plot of the movie and colorize it with rainbow command. 
// You can see this in action in the gifs at the top of the page.
Runner.runPipe('echo Star Wars | movie | rainbow')

Paint

Paint helps you add colors, styles and links to your application. It has a special style type called command which creates a clickable command that is executed on click. You can check the paint.css file inside bin/system to see available styles.

import paint from '../system/paint'

screen.push(paint('You will be presented with a dummy determinate loading..', 
{styles: ['magenta', 'underline', 'white-bg']}))

screen.push(paint('movie Star Wars', {styles: ['command']}))
screen.push(paint('google.com', {styles: ['blue', 'bold'], link: 'http://google.ca'}}))

Ask

  • ask(message): Ask provides a prompt that you can use to get user input to . use in your app.
import progress from '../system/progress'
import paint from '../system/paint'
import ask from '../system/ask'

export default function (screen, args) {
  return new Promise((resolve, reject) => {
    ask('Enter the city name for forecast')
    .then(function (city) {
      progress.pushProgressIndeterminate(['/', '-', '|', '-', '\\', '-'], 100)
      return fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}`)
    })
    .then(function (res) {
      return res.json()
    })
    .then(function (res) {
      progress.removeProgress()
      resolve(`Current temperature for ${res.name} is ${paint(parseInt(res.main.temp) + ' degrees.', {styles: ['bold', 'green']})}`)
    })
  })
}

promptie demo

Progress

Progress provides determinate and intereminate progress indicators for your app.

  • static pushProgressIndeterminate(characterSequence, interval): Creates a indeterminate progress indicator with the given character sequence.

  • static pushProgressDeterminate(progress, zero, one): Creates a determinate progress indicator. progress represents the total progress done with a value between 0 and 1. zero is a single character representing the unfinished progress and one represents the done progress.

  • static removeProgress(): Removes the progress from screen.

import progress from '../system/progress'

// This will put 'OOOOOO______________ %30' on the screen.
progress.pushProgressDeterminate(0.3, '_', 'O')

// This will continuously loop through given character sequence until you call progress.removeProgress()
progress.pushProgressIndeterminate(['/', '-', '|', '-', '\\', '-'], 100)
progress.removeProgress()

Road Map

  • Giving applications their own prompt for gettin user input during the execution of the application.
  • Math parsing.
  • A .promptie_profile file for setting environmental options and running apps on launch.
  • A ruby on rails like application generator to generate application templates in the src/bin.
  • SUPER FUTURE TODO: Fulscreen GUI applications and multitasking 🙃.

Credits

This software mainly uses code from these open source packages.

License

MIT


Twitter @alican