A full-blown terminal lib featuring: 256 colors, styles, keys & mouse handling, input field, interactive 'yes or no', screen buffer, and many more...
Whether you just need colors & styles, build a simple interactive command line tool or a complexe terminal application: this is the absolute terminal lib for Node.js!
It does NOT depend on ncurses.
- License: MIT
- Current status: really close to release!
- Platform: linux and any xterm-compatible terminal, it has been tested successfully with:
- xterm
- gnome-terminal
- Konsole
- Terminator
- xfce4-terminal
- Linux Console
- rxvt/urxvt
- Eterm
- Terminology
- Your terminal? Help tracking terminal compatibilities on github!
Some tutorials are available at blog.soulserv.net/tag/terminal.
- colors, 256 colors or even 24 bits colors, if the terminal supports it
- styles (bold, underline, italic, and many more)
- style mixing
- string formatting
- short style markup
- cursor positioning
- keyboard input
- mouse support (GPM is supported for the Linux Console)
- terminal window title
- input field
- interactive 'yes or no'
- screen & off-screen buffers (a concept similar to SDL's Surface)
- event-driven
// Require the lib, get a working terminal
var term = require( 'terminal-kit' ).terminal ;
// The term() function simply output a string to stdout, using current style
// output "Hello world!" in default terminal's colors
term( 'Hello world!\n' ) ;
// This output 'red' in red
term.red( 'red' ) ;
// This output 'bold' in bold
term.bold( 'bold' ) ;
// output 'mixed' using bold, underlined & red, exposing the style-mixing syntax
term.bold.underline.red( 'mixed' ) ;
// printf() style formatting everywhere:
// this will output 'My name is Jack, I'm 32.' in green
term.green( "My name is %s, I'm %d.\n" , 'Jack' , 32 ) ;
// Since v0.16.x, style markup are supported as a shorthand.
// Those two lines produce the same result.
term( "My name is " ).red( "Jack" )( " and I'm " ).green( "32\n" ) ;
term( "My name is ^rJack^ and I'm ^g32\n" ) ;
// Width and height of the terminal
term( 'The terminal size is %dx%d' , term.width , term.height ) ;
// Move the cursor at the upper-left corner
term.moveTo( 1 , 1 ) ;
// We can always pass additional arguments that will be displayed...
term.moveTo( 1 , 1 , 'Upper-left corner' ) ;
// ... and formated
term.moveTo( 1 , 1 , "My name is %s, I'm %d.\n" , 'Jack' , 32 ) ;
// ... or even combined with other styles
term.moveTo.cyan( 1 , 1 , "My name is %s, I'm %d.\n" , 'Jack' , 32 ) ;
Use Node Package Manager:
npm install terminal-kit
In all examples, termkit
is assumed to be var termkit = require( 'terminal-kit' ) ;
while term
is assumed
to be var term = require( 'terminal-kit' ).terminal ;
or var term = termkit.terminal ;
.
So term
is an instanceof of termkit.Terminal
, that should in almost all cases match correctly the terminal you
are currently using. This is the default terminal.
You can also define your own terminal interface, see .createTerminal().
- Basic chainable methods
- Advanced usages and methods
- Events
- Static methods
Standard methods map low-level terminal capabilities.
For all the functions below, additional arguments can be provided.
If a boolean is provided, it will turn the feature on or off.
For example term.red( true )
turn all subsequent output in red, while term.red( false )
disable red and go back to default color.
Without arguments, it is always the same as true, e.g. term.red()
do the same thing than term.red()
.
Some function cannot be turned off, they just perform an action.
For example term.reset()
reset the terminal, usually to its default.
This is not reversible, thus term.reset( false )
does nothing.
If the additional argument is a string, then it will be sent to the output directly after turning on the feature... then the
feature is turn off.
That's it:
term.red( 'Hello world!' )
... is the same as:
term.red( true ) ; term( 'Hello world!' ) ; term.red( false ) ;
.
Also those string support a printf()-like formatting syntax.
So we can do term.red( "My name is %s, I'm %d." , 'Jack' , 32 )
to output "My name is Jack, I'm 32." in red.
New: since v0.16.x, style markup are supported as a shorthand. Style markup are introduced by a caret ^
followed by another
character.
Colors are produced by the first letter of its name, e.g. red is produced with a ^r
, except black which is produced by ^k
.
Other styles are produced with a symbol. For example ^_
switch to underline.
To remove all styles, ^:
or ^
can be used.
A style reset is always produced at the end of the string as soon as one style markup was used.
Those two lines produce the same result:
term( "My name is " ).red( "Jack" )( " and I'm " ).green( "32\n" ) ;
term( "My name is ^rJack^ and I'm ^g32\n" ) ;
See the full style markup reference for details.
All those functions are chainable, and their arguments can be combined.
We can do:
term.moveTo.red( 1 , 1 , "My name is %s, I'm %d.\n" , 'Jack' , 32 )
which will move the cursor to (1,1), then output "My name is Jack, I'm 32." in red.
- .reset(): full reset of the terminal
- .error(): it just set error to true so it will write to STDERR instead of STDOUT
- .str(): do not output anything, instead return a string containing the sequences
- .bell(): emit an audible bell
- .defaultColor(): back to the default foreground color
- .black(): ...
- .red(): ...
- .green(): ...
- .yellow(): dark yellow, most of time brown or orange
- .blue(): ...
- .magenta(): ...
- .cyan(): ...
- .white(): ...
- .brightBlack(): ...
- .brightRed(): ...
- .brightGreen(): ...
- .brightYellow(): true yellow
- .brightBlue(): ...
- .brightMagenta(): ...
- .brightCyan(): ...
- .brightWhite(): ...
- .color(register): choose between 16 colors using an 0..15 integer
- .darkColor(register): choose between 8 regular (dark) colors using an 0..7 integer
- .brightColor(register): choose between 8 bright colors using an 0..7 integer
- .color256(register): if the terminal support 256 colors, it chooses between them using an 0..255 integer
- .colorRgb(r,g,b): pick the closest match for an RGB value (from a 16 or 256 colors palette or even the exact color if the terminal support 24 bits colors), r,g,b are in the 0..255 range
- .colorGrayscale(l): pick the closest match for a grayscale value (from a 16 or 256 colors palette or even the exact color if the terminal support 24 bits colors), l is in the 0..255 range
- .bgDefaultColor(): back to the default background color
- .bgBlack(): ...
- .bgRed(): ...
- .bgGreen(): ...
- .bgYellow(): dark yellow, most of time brown or orange
- .bgBlue(): ...
- .bgMagenta(): ...
- .bgCyan(): ...
- .bgWhite(): ...
- .bgDarkColor(): ...
- .bgBrightBlack(): ...
- .bgBrightRed(): ...
- .bgBrightGreen(): ...
- .bgBrightYellow(): true yellow
- .bgBrightBlue(): ...
- .bgBrightMagenta(): ...
- .bgBrightCyan(): ...
- .bgColor(register): choose between 16 colors using an 0..15 integer
- .bgBrightWhite(): choose between 8 regular (dark) colors using an 0..7 integer
- .bgBrightColor(): choose between 8 bright colors using an 0..7 integer
- .bgColor256(register): if the terminal support 256 colors, it choose between them using an 0..255 integer
- .bgColorRgb(r,g,b): pick the closest match for an RGB value (from a 16 or 256 colors palette or even the exact color if the terminal support 24 bits colors) as the background color, r,g,b are in the 0..255 range
- .bgColorGrayscale(l): pick the closest match for a grayscale value (from a 16 or 256 colors palette or even the exact color if the terminal support 24 bits colors) as the background color, l is in the 0..255 range
- .styleReset(): reset all styles and go back to default colors
- .bold(): bold text
- .dim(): faint color
- .italic(): italic
- .underline(): underline
- .blink(): blink text, not widely supported
- .inverse(): foreground and background color
- .hidden(): invisible, but can be copy/paste'd
- .strike(): strike through
- .saveCursor(): save cursor position
- .restoreCursor(): restore a previously saved cursor position
- .up(n): move the cursor 'n' chars up
- .down(n): move the cursor 'n' chars down
- .right(n): move the cursor 'n' chars right
- .left(n): move the cursor 'n' chars left
- .nextLine(n): move the cursor to beginning of the line, 'n' lines down
- .previousLine(n): move the cursor to beginning of the line, 'n' lines up
- .column(x): move the cursor to column x
- .scrollUp(n): scroll whole page up by 'n' lines, new lines are added at the bottom, the absolute cursor position do not change (Linux Console don't support it)
- .scrollDown(n): scroll whole page down by 'n' lines, new lines are added at the top, the absolute cursor position do not change (Linux Console don't support it)
- .moveTo(x,y): move the cursor to the (x,y) coordinate (1,1 is the upper-left corner)
- .move(x,y): relative move of the cursor
- .hideCursor(): hide/show the cursor
- .clear(): clear the screen and move the cursor to the upper-left corner
- .eraseDisplayBelow(): erase everything below the cursor
- .eraseDisplayAbove(): erase everything above the cursor
- .eraseDisplay(): erase everything
- .eraseLineAfter(): erase current line after the cursor
- .eraseLineBefore(): erase current line before the cursor
- .eraseLine(): erase current line
- .insertLine(n): insert n lines
- .deleteLine(n): delete n lines
- .insert(n): insert n char after (like the INSERT key)
- .delete(n): delete n char after (like the DELETE key)
- .backDelete(): delete one char backward (like the BACKSPACE key), shorthand composed by a .left(1) followed by a .delete(1)
- .alternateScreenBuffer(): this set/unset the alternate screen buffer, many terminal do not support it or inhibit it
- .requestCursorLocation(): request the cursor location, a 'terminal' event will be fired when available
- .requestScreenSize(): DEPRECATED request for screen size, a 'terminal' event will be fired when available, DO NOT USE: use .width and .height instead, those properties are updated whenever a resize event is received
- .requestColor(n): rarely useful request for color n, DO NOT USE: use high-level .getColor() instead
- .applicationKeypad(): should allow keypad to send different code than 0..9 keys, not widely supported
- .mouseButton(): ask the terminal to send event when a mouse button is pressed, with the mouse cursor position
- .mouseDrag(): ask the terminal to send event when a mouse button is pressed and when draging, with the mouse cursor position
- .mouseMotion(): ask the terminal to send all mouse event, even mouse motion that occurs without buttons
- .mouseSGR(): another mouse protocol that extend coordinate mapping (without it, it supports only 223 rows and columns)
- .focusEvent(): ask the terminal to send event when it gains and loses focus, not widely supported
- .noFormat(str): disable string formatting - useful when your string may contain
%
(e.g. user input) and you don't want to escape them - .windowTitle(str): set the title of an xterm-compatible window to str
- .setCursorColor(register): set the cursor color to one of the 256 register
- .setCursorColorRgb(r,g,b): set the cursor color to a custom RGB value
- .setDefaultColorRgb(r,g,b): set the value of the default foreground color
- .setDefaultBgColorRgb(): set the value of the default background color, this is the terminal window background
Advanced methods are high-level library functions.
When a program is piped, its standard input (STDIN) or its standard output (STDOUT) is no longer connected to the actual terminal, but to an upstream or downstream program.
Sometime this is the behavior you want, sometime not.
The default terminal instance (require( 'terminal-kit' ).terminal
) use STDIN and STDOUT as its input and output, so if the program
is piped, it get its input from the upstream program and/or send its output to the downstream program.
However, one may want a direct access to the terminal even when piped.
For that purpose, termkit.tty.getInput()
and termkit.tty.getOutput()
can be used instead of process.stdin
and process.stdout
,
and passed to termkit.createTerminal()
.
To ease this process even more, there is another built-in terminal instance for that: require( 'terminal-kit' ).realTerminal
.
Let's write this file (my-script.js):
realTerm = require( "terminal-kit" ).realTerminal ;
realTerm.blue( "Enter your name: " ) ;
realTerm.inputField( function( error , name ) {
realTerm.green( "\nHello %s!\n" , name ) ;
process.exit() ;
} ) ;
And then execute it from the command line using pipes: someprogram | node my-script.js | someotherprogram
.
The script will totally escape the pipes and will be able to run the same way it would without pipes.
Furthermore: you can still receive and send things from STDIN and to STDOUT, so you can handle interactive stuff using
the realTerm
instance and receive from the first program, and write to the last program.
- options: true/false/object: if truthy it activate fullscreen mode, falsy return to normal mode,
if it is an object it supports those properties:
- noAlternate
boolean
true if the alternate screen buffer should not be used
- noAlternate
Basically, this method try to achieve the same goal than the native terminal capability alternate screen buffer. If alternate screen buffer is disabled on your terminal, it will provide a clean fallback, clearing the screen and positionning the cursor at the upper-left corner.
- code
number
the exit code
This method should be used instead of calling process.exit()
directly. The code argument will be transmitted to
process.exit()
as it is.
It helps quitting cleanly your application without leaving the terminal in a bad state, so the user get a working shell back.
- options: false/true/Object, false disable input grabbing, true or an Object turn it on,
if it is an Object then those properties are supported:
- mouse: if defined, it activate mouse event, those values are supported for 'mouse':
- 'button': report only button-event
- 'drag': report button-event and report motion-event only when a button is pressed (i.e. a mouse drag)
- 'motion': report button-event and all motion-event, use it only when needed, many escape sequences are sent from the terminal (e.g. you may consider it for script running over SSH)
- focus: true/false: if defined and true, focus event will be reported (if your terminal support it - xterm does)
- mouse: if defined, it activate mouse event, those values are supported for 'mouse':
This function turns input grabbing on, keyboard entries will not be echoed, and every input will generate an event
on the term
object.
Quick example:
var term = require( 'terminal-kit' ).terminal ;
function terminate()
{
term.grabInput( false ) ;
setTimeout( function() { process.exit() } , 100 ) ;
}
term.bold.cyan( 'Type anything on the keyboard...\n' ) ;
term.green( 'Hit CTRL-C to quit.\n\n' ) ;
term.grabInput( { mouse: 'button' } ) ;
term.on( 'key' , function( name , matches , data ) {
console.log( "'key' event:" , name ) ;
if ( name === 'CTRL_C' ) { terminate() ; }
} ) ;
term.on( 'terminal' , function( name , data ) {
console.log( "'terminal' event:" , name , data ) ;
} ) ;
term.on( 'mouse' , function( name , data ) {
console.log( "'mouse' event:" , name , data ) ;
} ) ;
- callback( error , x , y )
- error
mixed
truthy if an underlying error occurs - x
integer
the x coordinate of the cursor - y
integer
the y coordinate of the cursor
- error
Get the cursor location.
- register
number
the register number in the 0..255 range - callback( error , rgb )
- error
mixed
truthy if an underlying error occurs - rgb
Object
where:- r
number
in the 0..255 range, the red value - g
number
in the 0..255 range, the green value - b
number
in the 0..255 range, the blue value
- r
- error
Get the RGB values of a color register.
- register
number
the register number in the 0..255 range - r
number
in the 0..255 range, the red value - g
number
in the 0..255 range, the green value - b
number
in the 0..255 range, the blue value - rgb
Object
where:- r
number
in the 0..255 range, the red value - g
number
in the 0..255 range, the green value - b
number
in the 0..255 range, the blue value
- r
- names
Array
ofstring
: names for that color, it default to an empty array
Set the RGB values for a color indexed by the integer register.
- callback( error , palette )
- error
mixed
truthy if an underlying error occurs - palette
Array
of 16Object
where:- r
number
in the 0..255 range, the red value - g
number
in the 0..255 range, the green value - b
number
in the 0..255 range, the blue value - names
Array
ofstring
, names for this color
- r
- error
Request from the terminal the 16-colors palette in use.
If the terminal does not support the feature, then the default palette for this terminal is provided, and each color that was modified by the lib replace it.
- palette either:
Array
of 16Object
where:- r
number
in the 0..255 range, the red value - g
number
in the 0..255 range, the green value - b
number
in the 0..255 range, the blue value - names
Array
ofstring
, names for this color
- r
- OR
string
one of the built-in palette (default, gnome, konsole, linux, solarized, vga, xterm)
If the terminal support it, it will reset the 16-colors palette to the provided one.
- options
Object
where:- yes
string
orArray
contains a key code or an array of key code that will trigger the yes - no
string
orArray
contains a key code or an array of key code that will trigger the - echoYes
String
contains what to write on yes, default 'yes' - echoNo
String
contains what to write on no, default 'no'
- yes
- callback( error , result )
- error
mixed
truthy if an underlying error occurs - result
boolean
true for 'yes' or false for 'no'
- error
Wait for user input, call the completion callback when the user hit the 'y' key or the 'n' key, result will be true if the user hit any yes keys or false if the user hit any no keys. Other keys do not do anything.
Turn input grabbing on if necessary.
We can specify the keys for yes and no by providing a string or an array of string.
It returns an object featuring some functions to control things during the input process:
- abort(): abort the input process and do not even call the inputField()'s callback
Quick example:
var term = require( 'terminal-kit' ).terminal ;
function question()
{
term( 'Do you like javascript? [Y|n]\n' ) ;
// Exit on y and ENTER key
// Ask again on n
term.yesOrNo( { yes: [ 'y' , 'ENTER' ] , no: [ 'n' ] } , function( error , result ) {
if ( result )
{
term.green( "'Yes' detected! Good bye!\n" ) ;
process.exit() ;
}
else
{
term.red( "'No' detected, are you sure?\n" ) ;
question() ;
}
} ) ;
}
question() ;
It produces:
- options
Object
where:- echo
boolean
if true (the default), input are displayed on the terminal - history
Array
(optional) an history array, so UP and DOWN keys move up and down in the history - maxLength
number
(optional) the maximum length (in characters) of the user input - autoComplete
Array
orFunction( inputString , [callback] )
(optional) an array of possible completion, so the TAB key will auto-complete the input field. If it is a function, it should accept an inputstring
and return the completedstring
(if no completion can be done, it should return the input string, if multiple candidate are possible, it should return an array of string), if the function accepts 2 arguments (checked using function.length), then the auto-completer will be asynchronous! Also note that if it is an array or the result of the function is an array, and if that array has a special propertyprefix
(a string), then this prefix will be prepended to the output of the auto complete menu. - autoCompleteMenu
boolean
orObject
of options, used in conjunction with the 'autoComplete' options, if truthy any auto-complete attempt having many completion candidates will display a menu to let the user choose between each possibilities. If an object is given, it should contain options for the .singleLineMenu() that is used for the completion (notice: some options are overwritten: 'y' and 'exitOnUnexpectedKey')
- echo
- callback( error , input )
- error
mixed
truthy if an underlying error occurs - input
string
the user input
- error
Wait for user input, call the completion callback when the user hit the ENTER key and pass the user input to the callback.
It turns input grabbing on if necessary.
Special keys supported by the input field:
- ENTER, KP_ENTER: end the input process and return the current user input
- DELETE: delete
- BACKSPACE: backward delete
- LEFT, RIGHT: move the cursor one character left or right
- HOME: move the cursor at the beginning of the input field
- END: move the cursor at the end of the input field
- DOWN, UP: use the history feature (if
options.history
is set) - TAB: use the auto-completion feature (if
options.autoComplete
is set)
Additional keys are used when the auto-completion displays its menu (see .singleLineMenu() for details).
It returns an EventEmitter object featuring some functions to control things during the input process:
- abort(): abort the input process and do not even call the inputField()'s callback
- stop(): stop the input process now, call the inputField()'s callback (same behavior than a regular 'ENTER' key pressed)
- getInput(): get the current input string
- getPosition(): return an object containing 'x' and 'y' properties, the coordinates where the input field starts
- redraw(): redraw the input field, useful if you had echo'ed something that can mess it
- hide(): hide the input field, it still records keystrokes
- show(): show the input field again
- rebase(): rebase the input field to the current cursor position. Please note: it does NOT erase the previously entered text, you have to use hide() before. It works this way because you may want to modify the screen in between, and it needs some I/O with the terminal to works accordingly.
It emits:
- ready: when the input field is ready (rarely useful)
Quick example, featuring history and auto-completion:
var term = require( 'terminal-kit' ).terminal ;
var history = [ 'John' , 'Jack' , 'Joey' , 'Billy' , 'Bob' ] ;
var autoComplete = [
'Barack Obama' , 'George W. Bush' , 'Bill Clinton' , 'George Bush' ,
'Ronald W. Reagan' , 'Jimmy Carter' , 'Gerald Ford' , 'Richard Nixon' ,
'Lyndon Johnson' , 'John F. Kennedy' , 'Dwight Eisenhower' ,
'Harry Truman' , 'Franklin Roosevelt'
] ;
term( 'Please enter your name: ' ) ;
term.inputField(
{ history: history , autoComplete: autoComplete , autoCompleteMenu: true } ,
function( error , input ) {
term.green( "\nYour name is '%s'\n" , input ) ;
process.exit() ;
}
) ;
It produces:
If we need our own auto-completer, we might take advantage of the built-in static method termkit.autoComplete().
Custom auto-completer can be asynchronous, if the function's length is exactly 2.
This is an example of a file selector that exposes the async behavior of auto-completer and the usage of
the static termkit.autoComplete()
method:
var fs = require( 'fs' ) ;
var termkit = require( 'terminal-kit' ) ;
var term = termkit.terminal ;
var autoCompleter = function autoCompleter( inputString , callback )
{
fs.readdir( __dirname , function( error , files ) {
callback( undefined , termkit.autoComplete( files , inputString , true ) ) ;
} ) ;
} ;
term( 'Choose a file: ' ) ;
term.inputField(
{ autoComplete: autoCompleter , autoCompleteMenu: true } ,
function( error , input ) {
if ( error )
{
term.red.bold( "\nAn error occurs: " + error + "\n" ) ;
}
else
{
term.green( "\nYour file is '%s'\n" , input ) ;
}
process.exit() ;
}
) ;
It produces:
Also note that if the autoComplete
options is an array or if it is a function whose output is an array,
a special property prefix
(a string) can be set on it: this prefix will be prepended to the output of the auto complete menu.
- menuItems
array
of menu item text - options
object
of options, where:- y
number
the line where the menu will be displayed, default to the next line - separator
string
(default: ' ') the string separating each menu item - nextPageHint
string
(default: ' » ') string indicator for a next page - previousPageHint
string
(default: ' « ') string indicator for a previous page - style
function
the style of unselected items, default to the currentterm
- selectedStyle
function
the style of the selected item, default toterm.dim.blue.bgGreen
- exitOnUnexpectedKey
boolean
if an unexpected key is pressed, it exits, calling the callback with undefined values
- y
- callback( error , response ), where:
- error
mixed
truthy if an underlying error occurs - response
Object
where- selectedIndex
number
the user-selected menu item index - selectedText
string
the user-selected menu item text - x
number
the x coordinate of the selected menu item (the first character) - y
number
the y coordinate of the selected menu item (same coordinate for all items since it's a single line menu) - unexpectedKey
string
when 'exitOnUnexpectedKey' option is set and an unexpected key is pressed, this contains the key that produced the exit
- selectedIndex
- error
It creates an interactive menu that uses only a single line.
It features paging if items oversize the line length, and supports the following keys:
- ENTER, KP_ENTER: end the process and return the currently selected menu item
- LEFT, RIGHT: move and select the previous or the next item in the menu
- UP, DOWN: go the previous or the next page of items (if paging is used)
- HOME, END: move and select the first or the last item of the menu
If the 'exitOnUnexpectedKey' option is set, any other keys will exit the menu, the callback's response argument does not contain any property except 'unexpectedKey', that will contain the key having triggered the exit.
Example:
var term = require( 'terminal-kit' ).terminal ;
var items = [ 'File' , 'Edit' , 'View' , 'History' , 'Bookmarks' , 'Tools' , 'Help' ] ;
var options = {
y: 1 , // the menu will be on the top of the terminal
style: term.inverse ,
selectedStyle: term.dim.blue.bgGreen
} ;
term.clear() ;
term.singleLineMenu( items , options , function( error , response ) {
term( '\n' ).eraseLineAfter.green(
"#%s selected: %s (%s,%s)\n" ,
response.selectedIndex ,
response.selectedText ,
response.x ,
response.y
) ;
process.exit() ;
} ) ;
It produces:
It creates a menu on the top of the terminal, with unselected items using inverted foreground/background colors, and the selected item using blue on green. When the user press RETURN/ENTER, it displays the index, text and coordinates of the selected menu item.
- options
object
of options, all of them are OPTIONAL, where:- width:
number
the total width of the progress bar, default to the max available width - percent:
boolean
if true, it shows the progress in percent alongside with the progress bar - eta:
boolean
if true, it shows the Estimated Time of Arrival alongside with the progress bar - items
number
the number of items that should be completed, turns the item mode on - title
string
the title of the current progress bar, turns the title mode on - barStyle
function
the style of the progress bar items, default toterm.cyan
- barBracketStyle
function
the style of the progress bar bracket character, default to options.barStyle if given orterm.blue
- percentStyle
function
the style of percent value string, default toterm.yellow
- etaStyle
function
the style of the ETA display, default toterm.bold
- itemStyle
function
the style of the item display, default toterm.dim
- titleStyle
function
the style of the title display, default toterm.bold
- itemSize
number
the size of the item status, default to 33% of width - titleSize
number
the size of the title, default to 33% of width or title.length depending on context - barChar
string
the char used for the bar, default to '=' - barHeadChar
string
the char used for the bar, default to '>' - maxRefreshTime
number
the maximum time between two refresh in ms, default to 500ms - minRefreshTime
number
the minimum time between two refresh in ms, default to 100ms
- width:
It creates a nice progress bar and return a controller object to interact with it.
The controller provides those functions:
-
update( updateObject ): update the progress bar, having the arguments:
- updateObject
object
ornumber
ornull
. If updateObject is not an object, it's a shorthand for{ progress: value }
. It supports those properties:- progress
number
ornull
the progress value:- if it's a float between 0 and 1, it's the actual progress value to be displayed
- if
null
then it will display a spinning wheel: something is in progress, but cannot be quantified
- items
number
change the number of items that should be completed, turns the item mode on - title
string
change the title of the current progress bar, turns the title mode on
- progress
- updateObject
-
startItem( name ): in item mode, it informs the progress bar that a new item is processing, having arguments:
- name
string
the name of the item that will be displayed in the item status part of the progress bar
- name
-
itemDone( name ): in item mode, it informs the progress bar that an item is now done, if that item was started using
.startItem()
, it will be removed from the running item list. When the number of finished item reaches theitems
parameter (see the.progressBar()
's 'items' option or.update()
method's 'items' option), the progressBar reaches 100% and stop. It has the arguments:- name
string
the name of the item that just finished.
- name
-
stop(): stop the progress bar, no redraw will occurs
-
resume(): resume a previously stopped progress bar, it will be redrawn again
Example of a progress bar using fake progress values:
var term = require( 'terminal-kit' ).terminal ;
var progressBar , progress = 0 ;
function doProgress()
{
// Add random progress
progress += Math.random() / 10 ;
progressBar.update( progress ) ;
if ( progress >= 1 )
{
// Cleanup and exit
setTimeout( function() { term( '\n' ) ; process.exit() ; } , 200 ) ;
}
else
{
setTimeout( doProgress , 100 + Math.random() * 400 ) ;
}
}
progressBar = term.progressBar( {
width: 80 ,
title: 'Serious stuff in progress:' ,
eta: true ,
percent: true
} ) ;
doProgress() ;
It produces:
It creates a progress bar and feeds it with a random progress value, then quit when it reaches 100%.
Example of a progress bar in item mode:
var term = require( 'terminal-kit' ).terminal ;
var progressBar ;
var thingsToDo = [
'update my lib' ,
'data analyzing' ,
'serious business' ,
'decrunching data' ,
'do my laundry' ,
'optimizing'
] ;
var countDown = thingsToDo.length ;
function start()
{
if ( ! thingsToDo.length ) { return ; }
var task = thingsToDo.shift() ;
progressBar.startItem( task ) ;
// Finish the task in...
setTimeout( done.bind( null , task ) , 500 + Math.random() * 1200 ) ;
// Start another parallel task in...
setTimeout( start , 400 + Math.random() * 400 ) ;
}
function done( task )
{
progressBar.itemDone( task ) ;
countDown -- ;
// Cleanup and exit
if ( ! countDown )
{
setTimeout( function() { term( '\n' ) ; process.exit() ; } , 200 ) ;
}
}
progressBar = term.progressBar( {
width: 80 ,
title: 'Daily tasks:' ,
eta: true ,
percent: true ,
items: thingsToDo.length
} ) ;
start() ;
It produces:
It creates a progress bar and start and finish task with a random time, then quit when everything is done.
- str
string
the text to display - options
object
of options, where:- style
function
the style of text, default toterm.green
- flashStyle
function
orfalsy
if afunction
is given, then this is the style of the text for the flash effect, iffalsy
then the flash effect is turn off, default toterm.bold.brightGreen
- delay
number
average delay before printing the next char, default to 150 ms - flashDelay
number
fixed delay before theflashStyle
of the last printed char is replaced by the regularstyle
, default to 100 ms
- style
- callback
function
that will be called on completion
It outputs some text with an old-fashioned slow-typing effect.
Example:
var term = require( 'terminal-kit' ).terminal ;
term.slowTyping(
'What a wonderful world!\n' ,
{ flashStyle: term.brightWhite } ,
function() { process.exit() ; }
) ;
It produces:
Event are fired on your term
object.
- width
number
the new width in character - height
number
the new height in character
The 'resize' event is emitted when the terminal get resized, and it contains the new width and height.
Also term.width
and term.height
are updated too.
- name
string
the key name - matches
Array
of matched key name - data
Object
contains more informations, mostly useful for debugging purpose, where:- isCharacter
boolean
is true if this is a regular character, i.e. not a control character - codepoint
number
(optional) the utf-8 code point of the character, if relevant - code
number
orBuffer
, for multibyte character it is the rawBuffer
input, for single byte character it is anumber
between 0 and 255
- isCharacter
The 'key' event is emitted whenever the user type something on the keyboard.
If name
is a single char, this is a regular UTF8 character, entered by the user.
If the user type a word, each UTF8 character will produce its own 'key' event.
If name
is a multiple chars string, then it is a SPECIAL key.
ESCAPE ENTER BACKSPACE NUL TAB SHIFT_TAB
UP DOWN RIGHT LEFT
INSERT DELETE HOME END PAGE_UP PAGE_DOWN
KP_NUMLOCK KP_DIVIDE KP_MULTIPLY KP_MINUS KP_PLUS KP_DELETE KP_ENTER
KP_0 KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9
F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12
SHIFT_F1 SHIFT_F2 SHIFT_F3 SHIFT_F4 SHIFT_F5 SHIFT_F6
SHIFT_F7 SHIFT_F8 SHIFT_F9 SHIFT_F10 SHIFT_F11 SHIFT_F12
CTRL_F1 CTRL_F2 CTRL_F3 CTRL_F4 CTRL_F5 CTRL_F6
CTRL_F7 CTRL_F8 CTRL_F9 CTRL_F10 CTRL_F11 CTRL_F12
CTRL_SHIFT_F1 CTRL_SHIFT_F2 CTRL_SHIFT_F3 CTRL_SHIFT_F4
CTRL_SHIFT_F5 CTRL_SHIFT_F6 CTRL_SHIFT_F7 CTRL_SHIFT_F8
CTRL_SHIFT_F9 CTRL_SHIFT_F10 CTRL_SHIFT_F11 CTRL_SHIFT_F12
SHIFT_UP SHIFT_DOWN SHIFT_RIGHT SHIFT_LEFT
ALT_UP ALT_DOWN ALT_RIGHT ALT_LEFT
CTRL_UP CTRL_DOWN CTRL_RIGHT CTRL_LEFT
SHIFT_INSERT SHIFT_DELETE SHIFT_HOME SHIFT_END SHIFT_PAGE_UP SHIFT_PAGE_DOWN
CTRL_INSERT CTRL_DELETE CTRL_HOME CTRL_END CTRL_PAGE_UP CTRL_PAGE_DOWN
ALT_INSERT ALT_DELETE ALT_HOME ALT_END ALT_PAGE_UP ALT_PAGE_DOWN
SHIFT_TAB ALT_TAB
ALT_SPACE CTRL_ALT_SPACE
And modifier on regular A-Z key:
CTRL_A ALT_A CTRL_ALT_A ALT_SHIFT_A
CTRL_B ALT_B CTRL_ALT_B ALT_SHIFT_B
CTRL_C ALT_C CTRL_ALT_C ALT_SHIFT_C
...
Sometime, a key matches multiple combination. For example CTRL-M on linux boxes is always the same as ENTER.
So the event will provide as the 'name' argument the most useful/common, here ENTER.
However the 'matches' argument will contain [ ENTER , CTRL_M ]
.
Also notice that some terminal will support less keys. For example, the Linux Console does not support SHIFT/CTRL/ALT + Arrows keys, it will produce a normal arrow key. There is no workaround here, the underlying keyboard driver simply does not support this.
KP_* keys needs applicationKeypad()
, e.g. without it KP_1 will report '1' or END.
Some terminal does not support applicationKeypad()
at all, sometime turning numlock off can works, sometime not,
so it is nearly impossible to differentiate (for example) a KP_1 from an END, or a KP_7 from a HOME.
- name
string
the name of the subtype of event - data
Object
provide some data depending on the event's subtype
The 'terminal' event is emitted for terminal generic information.
The argument 'name' can be:
-
CURSOR_LOCATION: it is emitted in response of a requestCursorLocation(), data contains 'x' & 'y', the coordinate of the cursor.
-
SCREEN_RESIZE: DEPRECATED! Will be removed in the next non-patch version! Use the 'resize' event instead! Currently it is emitted when a terminal resizing is detected, most of time node.js will be notified of screen resizing, and so this event will be emitted, data contains 'width' & 'height', the size of the screen in characters
-
SCREEN_SIZE: rarely useful it is emitted in response of a requestScreenSize(), data contains 'width' & 'height', the size of the screen in characters, and 'resized' (true/false) if the size has changed without node.js being notified
-
FOCUS_IN: it is emitted if the terminal gains focus (if supported by your terminal)
-
FOCUS_OUT: it is emitted if the terminal loses focus (if supported by your terminal)
- name
string
the name of the subtype of event - data
Object
provide the mouse coordinates and keyboard modifiers status, where:- x
number
the row number where the mouse is - y
number
the column number where the mouse is - ctrl
boolean
true if the CTRL key is down or not - alt
boolean
true if the ALT key is down or not - shift
boolean
true if the SHIFT key is down or not
- x
Activated when grabInput() is used with the 'mouse' options, e.g. { mouse: 'button' }
, { mouse: 'drag' }
or { mouse: 'motion' }
.
The argument 'name' can be:
- MOUSE_LEFT_BUTTON_PRESSED: well... it is emitted when the left mouse button is pressed
- MOUSE_LEFT_BUTTON_RELEASED: when this button is released
- MOUSE_RIGHT_BUTTON_PRESSED, MOUSE_RIGHT_BUTTON_RELEASED, MOUSE_MIDDLE_BUTTON_PRESSED, MOUSE_MIDDEL_BUTTON_RELEASED: self explanatory
- MOUSE_WHEEL_UP, MOUSE_WHEEL_DOWN: self explanatory
- MOUSE_OTHER_BUTTON_PRESSED, MOUSE_OTHER_BUTTON_RELEASED: a fourth mouse button is sometime supported
- MOUSE_BUTTON_RELEASED: a button were released, however the terminal does not tell us which one
- MOUSE_MOTION: if the options
{ mouse: 'motion' }
is passed to grabInput(), every moves of the mouse will fire this event, if{ mouse: 'drag' }
is given, it will be fired if the mouse move while a button is pressed
- options
Object
an object of options, where:- stdin
stream.Readable
(default:process.stdin
) a readable input stream for the terminal interface's input - stdout
stream.Writable
(default:process.stdout
) a writable output stream for the terminal interface's output - stderr
stream.Writable
(default:process.stderr
) a writable output stream for the terminal interface's error output - generic
string
(default: 'xterm') generic terminal application's identifier - appId
string
specific terminal application's identifier (available ID's are files basename found in the lib/termconfig/ directory of the lib) - appName
string
just an informative field - processSigwinch
boolean
(default: false) true if the terminal can use the SIGWINCH signal to detect resizing
- stdin
This method creates a new terminal interface.
Most of time, one may just use the default terminal interface, using var term = require( 'terminal-kit' ).terminal ;
.
That should cover 98% of use cases.
However, it is sometime useful if we have some communication channel to a terminal other than STDIN/STDOUT, or if we know for sure the targeted terminal's ID and don't want to use the autodetect feature of the lib.
- callback
Function( error , codename , name , pid )
where:- error: truthy if it has failed for some reason
- codename: the code name of the terminal, as used by terminfo
- name: the real binary name of the terminal
- pid: the PID of the terminal
This method detects on which terminal your application run. It does *NOT* use the $TERM or $COLORTERM environment variable, except as a fallback. It iterates through parent process until a known terminal is found, or process of PID 1 is reached (the init process).
Obviously, it does not works over SSH.
Also, it only works on UNIX family OS.
- callback
Function( error , term )
where:- error: truthy if it has failed for some reason
- term: the terminal object created specifically for your terminal
This is a shortcut that call .getParentTerminalInfo()
then use .createTerminal()
with the correct arguments.
This will give you a terminal object with the best support that this lib is able to give to you.
It does not works over SSH, but fallback to standard terminal guessing.
Example *NOT* using .getDetectedTerminal()
:
var term = require( 'terminal-kit' ).terminal ;
term.cyan( 'Hello world!' ) ;
This will give you a terminal object based on the $TERM and $COLORTERM environment variable, that works fine in almost all cases.
Some troubles may arise if the $COLORTERM environment variable is not found.
Most of modern terminal report them as an xterm or an xterm-256color terminal in the $TERM environment variable. They claim being xterm-compatible, but most of them support only 33% to 50% of xterm features, and even major terminal like gnome-terminal or Konsole are sometimes terrible.
Example using .getDetectedTerminal()
:
require( 'terminal-kit' ).getDetectedTerminal( function( error , term ) {
term.cyan( 'Terminal name: %s\n' , term.appName ) ;
term.cyan( 'Terminal app: %s\n' , term.app ) ;
term.cyan( 'Terminal generic: %s\n' , term.generic ) ;
term.cyan( 'Config file: %s\n' , term.termconfigFile ) ;
} ) ;
This will give you the best compatibility possible, at the cost of a callback.
- array
Array
of string, it is the list of completion candidates - startString
string
this is the input string to be completed - returnAlternatives
boolean
(default: false) when many candidates match the input, if returnAlternatives is set then the method is allowed to return an array containing all matching candidates, else the input string (startString) is returned unchanged - prefix
string
(optional) prepend that string to the response string, or add aprefix
property to the response array: when used in aninputField()
, this cause this string to be prepended to the output of the auto-complete menu.
This static method is used behind the scene by .inputField() when auto-completion mechanisms kick in.
This method is exposed in the API because .inputField() supports user-defined auto-completers, such auto-completers might take advantage of this method for its final pass, after collecting relevant informations to feed it.
This is an example of its usage.