repll

node repl livly implementation

Usage no npm install needed!

<script type="module">
  import repll from 'https://cdn.skypack.dev/repll';
</script>

README

demo

npm npm

repll: customizable & livly repl

The above is a tool called commitlive, created using repll

Features

  • r: read input key-by-key ( when you paste something, don't worry, we will handle it as a longer key )
  • e: evaluate input ( we do not evaluate javascript, that's boring, the eval function is provided by you )
  • p: print whatever you wanna output ( without even press Enter )
  • ll: we keep doing r e p looply and livly, so you can interact with user in real-time

We also support:

  • input heilghting: heightlight user's input at ease, this is what a repl should feels like
  • tab completion: not bash like, we won't endlessly prompt out the possibilities. Moreover, repll support adding detailed introduction by using a completion object
  • stop detection: when user stops input, we will calculate the pause time, compare it with the time you provide
  • fake line: sometimes, you want to process input just in one line(by hitting enter, you don't wanna create a new prompt). But readline won't let you do that line feed, repll implement that by using onFakeLine, press <shift-DownArrow> to try it!
  • livly prompt: by passing a prompt string sequence to repll, every time you press enter, a brand new prompt prompts up!
  • livly placeholder: can be used to give user tips on what to do, it has livly feature too!
  • arrow key navigation: you can using arrow keys to edit the text you input, we currently don't support fake line + arrow key navigation, this can lead to strange behavior, but the fact that it is still working 💊 (PR is welcome)

Get started!

Installation

npm i repll

The installation process is super fast because repll does not need any dependencies

You must have NodeJS v13.5.0+(v12.16.0+) installed considering compatibility issues

Usage

const { replLive, onInput } = require('repll')

// Create a repll instance
const repll = replLive({ 'prompt › ': 'placeholder' })

// Listen input key-by-key
onInput(input => {
  // Output in real-time
  repll.refresh(`\nINPUT: ${input}
  \nLINE: ${repll.input}`)
})

The arrow function passed to onInput acts as an evaluate function in repl, in this case, it will output what user inputs

Global methods explained

Note: Those methods can be directly required from repll module:

// Require global methods
const { replLive, onTab } = require('repll')
  • replLive(map)

    • map: a Object which contains prompt-placeholder key-value pairs, repll will close it's instance when all prompts are consumed, Make sure to pass all the prompts you need, and try to use repll.waitClosing() to keep the closing flow in control
    • Return: a replLive class's instance

    You must call this function first to init and generate a repll entity, which contains some very useful properties and methods:

    • repll.input: a string, which keeps tracking of user's accumulated input in current line
    • repll.hl(len, string): a Function, it moves the cursor to the len left, cover user's input with a colorized string, it can be used to heightlighting user's input(NOTE: it won't change user's input, it covers a layer of colorized string provided by you)
    • repll.write(string, object): a Function, same as readline's write method, it can type inputs for user. You can use it as an auto-completion
    • repll.waitClosing(): a Function which returns a Promise(will be resolved when prompt is running out), we can use it to create a new repll instance or write some sync code for good UX. After it resolves, a repll's history array will return, you can catch it and do something like inquirer does
    • repll.history an array, when you have multiple lines of input, it records each line for user
    • repll.inpuLine: a string, it indicates which line user is currently on
  • onTab(callback(input))

    • callback Function: take in user accumulated input, generate a sequence for completing

    i.e. :

    onTab(v => {
      const optionMap = {
        'feat: ': 'add a new feature',
        'fix: ': 'patch a bug',
      }
      const selectedList = Object.keys(optionMap).filter(
        e => e.includes(v) && e.length > v.length
      )
      return [selectedList, optionMap]
    })
    

This callback gets called each time user press the tab, view full example at here: ./TEST/completion.js

  • onLine(callback(key))

    • callback Function: take in line number, if callback returns a string, it will be used as the new line's placeholder

    This function makes palceholder modifiable when user starts a new line. i.e. :

    onLine(line => {
      return `LINE: ${line}`
    })
    

    View full example at here: ./TEST/placeholder.js

  • onFakeLine

    • callback Function

    By default, when you press enter, readline creates a new line for you. repll listens to the shfit + DownArrow keypress to trigger the onFakeLine event, which allows you to simulate a (fake new) line feed on the current line

  • onInput(callback(key))

    • callback Function: take in user input key, evaluate it as you wish, repll with excute it for you

    This callback gets called each time user inputs a key

  • onAny(callback(data))

    • callback Function: take in user input key's data object, it can extend onInput because some modifier key can't fire onInput

    This callback gets called each time user inputs a any key

  • onArrow(callback(arrowKey))

    • callback Function: take in array key type (up|down|left|right)

    This callback gets called each time user press a arrow key

  • onStop(callback(), time)

    • callback Function: will be called when the user pause for a period of time
    • time number: if time period of pausing input seconds > time seconds, the callback function is executed

    You'd better use this function instead of onInput when you make a network request. The tldr demo uses this method, it's powerful!

  • onSubmit(callback())

    • callback Function

    This callback gets called when user press , this is where the program should end

Related projects

  • repl: nodejs built-in module, seems to be livly, but things start to get static when you pass completer into it

  • ink: awesome project, requires a dependency on react, also supports read user input livly

  • inquirer: super powerful interactive command line user interfacess collection