Socket
Socket
Sign inDemoInstall

terminal-kit

Package Overview
Dependencies
Maintainers
1
Versions
638
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

terminal-kit - npm Package Compare versions

Comparing version 1.49.4 to 3.0.1

browser/termkit.js

6

.eslintrc.js

@@ -28,3 +28,3 @@ module.exports = {

'no-unused-vars': 'warn' , // During development phase, it's boring to clean unused var since they can be used later
'no-lonely-if': 'error' ,
'no-lonely-if': 'off' , // Can hurt semantic programming
'no-nested-ternary': 'off' , // Now I use the streamlined ternary operator a lot

@@ -66,5 +66,3 @@ 'no-shadow': 'warn' ,

} ] ,
'newline-per-chained-call': [ 'error', {
'ignoreChainWithDepth': 2
} ] ,
'newline-per-chained-call': 'off',
'no-multi-spaces': 'off' ,

@@ -71,0 +69,0 @@ 'block-spacing': 'error' ,

@@ -33,2 +33,3 @@

* [Bar](Bar.md#top)
* [Border](Border.md#top)
* [Button](Button.md#top)

@@ -41,2 +42,4 @@ * [ColumnMenu](ColumnMenu.md#top)

* [InlineInput](InlineInput.md#top)
* [InlineFileInput](InlineFileInput.md#top)
* [InlineMenu](InlineMenu.md#top)
* [LabeledInput](LabeledInput.md#top)

@@ -43,0 +46,0 @@ * [Layout](Layout.md#top)

@@ -30,3 +30,3 @@

* [.draw()](#ref.Element.draw)
* [.redraw()](#ref.Element.redraw)
* [.outerDraw()](#ref.Element.outerDraw)
* [.drawCursor()](#ref.Element.drawCursor)

@@ -122,3 +122,3 @@ * [.saveCursor()](#ref.Element.saveCursor)

default: false. **NOTE:** not all widget support markup or ansi!
* dontDraw `boolean` when set, the content's update does not trigger the *redraw* of the *element*
* dontDraw `boolean` when set, the content's update does not trigger the *draw*/*outerDraw* of the *element*

@@ -132,5 +132,5 @@ Set the content of this *element*.

* dontDraw `boolean` when set (default: false) the element is not redrawn (it will be made visible the next time something trigger a *redraw*)
* dontDraw `boolean` when set (default: false) the element is not drawn/outerDrawn (it will be made visible the next time something trigger a *outerDraw*)
Turn the element visibility **on** and redraw it immediately (unless the `dontDraw` option is on).
Turn the element visibility **on** and outerDraw it immediately (unless the `dontDraw` option is on).

@@ -142,5 +142,5 @@

* dontDraw `boolean` when set (default: false) the element is not redrawn (it will be hidden the next time something trigger a *redraw* on its parent)
* dontDraw `boolean` when set (default: false) the element is not drawn/outerDrawn (it will be hidden the next time something trigger a *outerDraw* on its parent)
Turn the element visibility **off** and redraw its parent immediately (unless the `dontDraw` option is on).
Turn the element visibility **off** and outerDraw its parent immediately (unless the `dontDraw` option is on).

@@ -158,6 +158,6 @@

<a name="ref.Element.redraw"></a>
### .redraw( [force] )
<a name="ref.Element.outerDraw"></a>
### .outerDraw( [force] )
* force `boolean` **INTERNAL** when set (default: false) the element is *redrawn* even if it is hidden: i.e. the parent is redrawn,
* force `boolean` **INTERNAL** when set (default: false) the element is *outerDrawn* even if it is hidden: i.e. the parent is outerDrawn,
it would effectively clear an hidden element from its parent

@@ -167,3 +167,3 @@

While `.draw()` is used when drawing the current *element* is enough (the *element* has not moved, and has not been resized),
`.redraw()` is used it is necessary to draw the closest ancestor which is a container.
`.outerDraw()` is used when it is necessary to draw the closest ancestor which is a container.

@@ -170,0 +170,0 @@ It is called internally/automatically, userland code should not be bothered with that, except in rare use-cases.

@@ -554,21 +554,23 @@

```js
var term = require( 'terminal-kit' ).terminal ;
async function func() {
var term = require( 'terminal-kit' ).terminal ;
var history = [ 'John' , 'Jack' , 'Joey' , 'Billy' , 'Bob' ] ;
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'
] ;
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( 'Please enter your name: ' ) ;
var input = await term.inputField(
{ history: history , autoComplete: autoComplete , autoCompleteMenu: true }
).promise ;
var input = await term.inputField(
{ history: history , autoComplete: autoComplete , autoCompleteMenu: true }
).promise ;
term.green( "\nYour name is '%s'\n" , input ) ;
process.exit() ;
term.green( "\nYour name is '%s'\n" , input ) ;
process.exit() ;
}
```

@@ -575,0 +577,0 @@

@@ -88,3 +88,3 @@

* *endOfLine*: move the cursor at the end of input, default: END
* *copyClipboard*: copy to clipboard (rely on xclip), default: CTRL_O
* *copyClipboard*: copy to clipboard (rely on xclip), default: CTRL_Y
* *pasteClipboard*: paste from clipboard (rely on xclip), default: CTRL_P

@@ -91,0 +91,0 @@

@@ -14,4 +14,12 @@

Complex markup is used to lift the single character limitation, it starts with `^[` followed by the command, and ends with `]`.
For example, the string `"This is ^[green]green^ and this is ^[red]red^ !"` would output the word 'green' in green and 'red' in red,
when passed to most Terminal-kit functions.
Complex markup supports the `key:value` format, the previous markup is equivalent to: `"This is ^[fg:green]green^ and this is ^[fg:red]red^ !"`.
In that example, *fg* was for *ForeGround color*, in the same vein *bg* can be used to set up the *BackGround color*: `"This is ^[bg:green]green^ and this is ^[bg:red]red^ !"`.
If the terminal support *true color*, you can use hexadecimal color code (`#` followed by 3 or 6 hexadecimal characters), e.g.: `"This is ^[#f9a]pink^ !"`.
#### Special markup

@@ -73,1 +81,17 @@

#### Complex markup *key:value* format
By keys:
* `fg` (or aliases: `fgColor`, `color`, `c`) set the foreground color, the value can be one of the ANSI color (*red*, *brightRed*, etc),
it can also be any color declared in a *Palette* for methods of object supporting `Palette`, it can be a color-code (e.g.: `#aa5577`)
if both the terminal and the method support *true-color*.
* `bg` (or alias: `bgColor`) set the background color, the supported values are exactly the same than for *foreground color*.
#### Complex markup **NOT** in the *key:value* format
Any ANSI color (*red*, *brightRed*, etc) or color code (e.g.: `#aa5577`) will be considered as the value for the *foreground color*.

@@ -71,3 +71,3 @@

* *scrollRight*: scroll right, default: RIGHT
* *copyClipboard*: copy to clipboard, default: CTRL_O
* *copyClipboard*: copy to clipboard, default: CTRL_Y

@@ -96,2 +96,3 @@

if set, it is possible to scroll down until the bottom of the content reaches the top of the textBox
* tabWidth `number` (default: 4) number of cells (=spaces) for the tab character
* lineWrap `boolean` when set, the text content is wrapped to the next line instead of being clipped by the textBox border

@@ -168,3 +169,3 @@ * wordWrap `boolean` like `lineWrap` but is word-aware, i.e. it doesn't split words

* content `string` the text-content to prepend
* dontDraw `boolean` if set, don't redraw the widget (default: false, redraw)
* dontDraw `boolean` if set, don't outerDraw the widget (default: false, outerDraw)

@@ -179,3 +180,3 @@ Prepend text-content at the begining of the current content. It supports markup or ansi if the textBox was instanciated with the `contentHasMarkup` options on.

* content `string` the text-content to append
* dontDraw `boolean` if set, don't redraw the widget (default: false, redraw)
* dontDraw `boolean` if set, don't outerDraw the widget (default: false, outerDraw)

@@ -190,3 +191,3 @@ Append text-content at the end of the current content. It supports markup or ansi if the textBox was instanciated with the `contentHasMarkup` options on.

* content `string` the text-content to append
* dontDraw `boolean` if set, don't redraw the widget (default: false, redraw)
* dontDraw `boolean` if set, don't outerDraw the widget (default: false, outerDraw)

@@ -215,3 +216,3 @@ This method is almost like [.appendContent()](ref.TextBox.appendContent), but more suitable for logging.

default: false.
* dontDraw `boolean` if set, don't redraw the widget (default: false, redraw)
* dontDraw `boolean` if set, don't outerDraw the widget (default: false, outerDraw)

@@ -218,0 +219,0 @@ It set the alternate text-content, work like its [.setContent()](#ref.Element.setContent) counterpart.

@@ -567,7 +567,9 @@

<a name="ref.TextBuffer.load"></a>
### .load( filepath , callback )
### .load( filepath , [callback] )
* filepath `string` the path of the file to load
* callback `Function( error )` completion callback
* callback `Function( error )` completion callback, DEPRECATED: prefer the Promise interface.
**If callback is omitted**, it returns a Promise on completion.
This erases all contents (text, attr and misc) and loads the content of the file (which is a text file).

@@ -578,8 +580,10 @@

<a name="ref.TextBuffer.save"></a>
### .save( filepath , callback )
### .save( filepath , [callback] )
* filepath `string` the path of the file to save into
* callback `Function( error )` completion callback
* callback `Function( error )` completion callback, DEPRECATED: prefer the Promise interface.
**If callback is omitted**, it returns a Promise on completion.
This saves the raw text content into a file.

@@ -36,2 +36,10 @@

* [.setCellContent()](#ref.TextTable.setCellContent)
* [.setCellAttr()](#ref.TextTable.setCellAttr)
* [.resetCellAttr()](#ref.TextTable.resetCellAttr)
* [.setRowAttr()](#ref.TextTable.setRowAttr)
* [.resetRowAttr()](#ref.TextTable.resetRowAttr)
* [.setColumnAttr()](#ref.TextTable.setColumnAttr)
* [.resetColumnAttr()](#ref.TextTable.resetColumnAttr)
* [.setTableAttr()](#ref.TextTable.setTableAttr)
* [.resetTableAttr()](#ref.TextTable.resetTableAttr)

@@ -107,3 +115,4 @@ * Inherit methods and properties from [Element](Element.md#ref.Element.toc)

* content `string` the new content for this table cell
* dontDraw `boolean` when set, the cell content's update does not trigger the *redraw* of the *textTable*
* dontDraw `boolean` when set, the cell content's update does not trigger the *outerDraw* of the *textTable* (or of the cell's *textBox*
if *dontUpdateLayout* is set)
* dontUpdateLayout `boolean` when set, the table layout is not updated

@@ -115,1 +124,87 @@

<a name="ref.TextTable.setCellAttr"></a>
### .setCellAttr( x , y , textAttr , [voidAttr] , [dontDraw] )
* x,y `number` the cell coordinate to modify
* textAttr `object` generic/default attributes for the cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the cell's *textBox*
This update an existing cell text attribute.
<a name="ref.TextTable.resetCellAttr"></a>
### .resetCellAttr( x , y , [dontDraw] )
* x,y `number` the cell coordinate to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the cell's *textBox*
This reset an existing cell text attribute to what it should be, based upon the constructor's parameters.
<a name="ref.TextTable.setRowAttr"></a>
### .setRowAttr( y , textAttr , [voidAttr] , [dontDraw] )
* y `number` the row's index to modify
* textAttr `object` generic/default attributes for the row's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This update all cells' text attribute of a row.
<a name="ref.TextTable.resetRowAttr"></a>
### .resetRowAttr( y , [dontDraw] )
* y `number` the row's index to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This reset all cells' text attribute of a row to what it should be, based upon the constructor's parameters.
<a name="ref.TextTable.setColumnAttr"></a>
### .setColumnAttr( x , textAttr , voidAttr , [dontDraw] )
* x `number` the column's index to modify
* textAttr `object` generic/default attributes for the column's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This update all cells's text attribute of a column.
<a name="ref.TextTable.resetColumnAttr"></a>
### .resetColumnAttr( x , [dontDraw] )
* x `number` the column's index to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This reset all cells' text attribute of a column to what it should be, based upon the constructor's parameters.
<a name="ref.TextTable.setTableAttr"></a>
### .setTableAttr( textAttr , voidAttr , [dontDraw] )
* textAttr `object` generic/default attributes for the table's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This update all cells's text attribute.
<a name="ref.TextTable.resetTableAttr"></a>
### .resetTableAttr( [dontDraw] )
* dontDraw `boolean` when set, the cell attr's update does not trigger the *outerDraw* of the *textTable*
This reset all cells's text attribute to what it should be, based upon the constructor's parameters.
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -36,3 +36,3 @@ The MIT License (MIT)

module.exports = function autoComplete( array , startString , returnAlternatives , prefix , postfix ) {
var i , j , exitLoop , candidate = [] , completed = startString , hasCompleted = false ;
var i , j , exitLoop , candidates = [] , completed = startString , hasCompleted = false ;

@@ -43,11 +43,11 @@ if ( ! prefix ) { prefix = '' ; }

for ( i = 0 ; i < array.length ; i ++ ) {
if ( array[ i ].slice( 0 , startString.length ) === startString ) { candidate.push( array[ i ] ) ; }
if ( array[ i ].slice( 0 , startString.length ) === startString ) { candidates.push( array[ i ] ) ; }
}
if ( ! candidate.length ) { return prefix + completed + postfix ; }
if ( ! candidates.length ) { return prefix + completed + postfix ; }
if ( candidate.length === 1 ) { return prefix + candidate[ 0 ] + postfix ; }
if ( candidates.length === 1 ) { return prefix + candidates[ 0 ] + postfix ; }
// Multiple candidate, complete only the part they have in common
// Multiple candidates, complete only the part they have in common

@@ -58,5 +58,5 @@ j = startString.length ;

for ( j = startString.length ; j < candidate[ 0 ].length ; j ++ ) {
for ( i = 1 ; i < candidate.length ; i ++ ) {
if ( candidate[ i ][ j ] !== candidate[ 0 ][ j ] ) { exitLoop = true ; break ; }
for ( j = startString.length ; j < candidates[ 0 ].length ; j ++ ) {
for ( i = 1 ; i < candidates.length ; i ++ ) {
if ( candidates[ i ][ j ] !== candidates[ 0 ][ j ] ) { exitLoop = true ; break ; }
}

@@ -66,3 +66,3 @@

completed += candidate[ 0 ][ j ] ;
completed += candidates[ 0 ][ j ] ;
hasCompleted = true ;

@@ -72,5 +72,5 @@ }

if ( returnAlternatives && ! hasCompleted ) {
candidate.prefix = prefix ;
candidate.postfix = postfix ;
return candidate ;
candidates.prefix = prefix ;
candidates.postfix = postfix ;
return candidates ;
}

@@ -77,0 +77,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -68,3 +68,8 @@ The MIT License (MIT)

if ( platform === 'darwin' ) { appId = path.parse( appId ).name ; }
if ( platform === 'darwin' ) {
appId = path.parse( appId ).name ;
}
else if ( platform === 'android' && process.env.TERMUX_VERSION ) {
appId = 'termux' ;
}

@@ -175,2 +180,7 @@ // safe is true if we are sure about our guess

// Android
case 'termux' :
break ;
default :

@@ -177,0 +187,0 @@ if ( ! appId ) { generic = 'unknown' ; }

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,2 +31,3 @@ The MIT License (MIT)

const Element = require( './Element.js' ) ;
const Text = require( './Text.js' ) ;

@@ -76,7 +77,6 @@ const spChars = require( '../spChars.js' ) ;

module.exports = AnimatedText ;
Element.inherit( AnimatedText , Text ) ;
AnimatedText.prototype = Object.create( Text.prototype ) ;
AnimatedText.prototype.constructor = AnimatedText ;
AnimatedText.prototype.elementType = 'AnimatedText' ;
AnimatedText.prototype.inlineCursorRestoreAfterDraw = true ;

@@ -83,0 +83,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -69,9 +69,6 @@ The MIT License (MIT)

module.exports = Bar ;
Element.inherit( Bar ) ;
Bar.prototype = Object.create( Element.prototype ) ;
Bar.prototype.constructor = Bar ;
Bar.prototype.elementType = 'Bar' ;
Bar.prototype.preDrawSelf = function() {

@@ -83,3 +80,3 @@ var index , x , fullCells , emptyCells , partialCellRate ,

innerSize = this.outputWidth - 2 ,
rate = this.value - this.minValue / ( this.maxValue - this.minValue ) ;
rate = ( this.value - this.minValue ) / ( this.maxValue - this.minValue ) ;

@@ -86,0 +83,0 @@ if ( ! rate || rate < 0 ) { rate = 0 ; }

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -57,2 +57,3 @@ The MIT License (MIT)

this.buttons = [] ;
this.hotkeyToButtonIndex = new Map() ;
this.focusChild = null ;

@@ -95,3 +96,2 @@

this.onSubmenuSubmit = this.onSubmenuSubmit.bind( this ) ;
this.onKey = this.onKey.bind( this ) ;
this.onWheel = this.onWheel.bind( this ) ;

@@ -104,26 +104,26 @@ this.onFocus = this.onFocus.bind( this ) ;

this.buttonFocusAttr = options.buttonFocusAttr || this.defaultOptions.buttonFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;
this.buttonDisabledAttr = options.buttonDisabledAttr || this.defaultOptions.buttonDisabledAttr || { bgColor: 'black' , color: 'brightBlack' , bold: true } ;
this.buttonSubmittedAttr = options.buttonSubmittedAttr || this.defaultOptions.buttonSubmittedAttr || { bgColor: 'brightBlack' , color: 'brightWhite' , bold: true } ;
this.turnedOnBlurAttr = options.turnedOnBlurAttr || this.defaultOptions.turnedOnBlurAttr || { bgColor: 'cyan' } ;
this.turnedOnFocusAttr = options.turnedOnFocusAttr || this.defaultOptions.turnedOnFocusAttr || { bgColor: 'brightCyan' , bold: true } ;
this.turnedOffBlurAttr = options.turnedOffBlurAttr || this.defaultOptions.turnedOffBlurAttr || { bgColor: 'gray' , dim: true } ;
this.turnedOffFocusAttr = options.turnedOffFocusAttr || this.defaultOptions.turnedOffFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;
this.buttonDisabledAttr = options.buttonDisabledAttr || this.defaultOptions.buttonDisabledAttr || { bgColor: 'black' , color: 'gray' , bold: true } ;
this.buttonSubmittedAttr = options.buttonSubmittedAttr || this.defaultOptions.buttonSubmittedAttr || { bgColor: 'gray' , color: 'brightWhite' , bold: true } ;
this.buttonTurnedOnBlurAttr = options.buttonTurnedOnBlurAttr || this.defaultOptions.buttonTurnedOnBlurAttr || { bgColor: 'cyan' } ;
this.buttonTurnedOnFocusAttr = options.buttonTurnedOnFocusAttr || this.defaultOptions.buttonTurnedOnFocusAttr || { bgColor: 'brightCyan' , color: 'gray' , bold: true } ;
this.buttonTurnedOffBlurAttr = options.buttonTurnedOffBlurAttr || this.defaultOptions.buttonTurnedOffBlurAttr || { bgColor: 'gray' , dim: true } ;
this.buttonTurnedOffFocusAttr = options.buttonTurnedOffFocusAttr || this.defaultOptions.buttonTurnedOffFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;
// Padding
this.blurLeftPadding = options.blurLeftPadding || options.leftPadding || '' ;
this.blurRightPadding = options.blurRightPadding || options.rightPadding || '' ;
this.focusLeftPadding = options.focusLeftPadding || options.leftPadding || '' ;
this.focusRightPadding = options.focusRightPadding || options.rightPadding || '' ;
this.disabledLeftPadding = options.disabledLeftPadding || options.leftPadding || '' ;
this.disabledRightPadding = options.disabledRightPadding || options.rightPadding || '' ;
this.submittedLeftPadding = options.submittedLeftPadding || options.leftPadding || '' ;
this.submittedRightPadding = options.submittedRightPadding || options.rightPadding || '' ;
this.turnedOnFocusLeftPadding = options.turnedOnFocusLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
this.turnedOnFocusRightPadding = options.turnedOnFocusRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
this.turnedOffFocusLeftPadding = options.turnedOffFocusLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
this.turnedOffFocusRightPadding = options.turnedOffFocusRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
this.turnedOnBlurLeftPadding = options.turnedOnBlurLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
this.turnedOnBlurRightPadding = options.turnedOnBlurRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
this.turnedOffBlurLeftPadding = options.turnedOffBlurLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
this.turnedOffBlurRightPadding = options.turnedOffBlurRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
this.blurLeftPadding = options.blurLeftPadding ?? options.leftPadding ?? '' ;
this.blurRightPadding = options.blurRightPadding ?? options.rightPadding ?? '' ;
this.focusLeftPadding = options.focusLeftPadding ?? options.leftPadding ?? '' ;
this.focusRightPadding = options.focusRightPadding ?? options.rightPadding ?? '' ;
this.disabledLeftPadding = options.disabledLeftPadding ?? options.leftPadding ?? '' ;
this.disabledRightPadding = options.disabledRightPadding ?? options.rightPadding ?? '' ;
this.submittedLeftPadding = options.submittedLeftPadding ?? options.leftPadding ?? '' ;
this.submittedRightPadding = options.submittedRightPadding ?? options.rightPadding ?? '' ;
this.turnedOnBlurLeftPadding = options.turnedOnBlurLeftPadding ?? options.turnedOnLeftPadding ?? this.blurLeftPadding ;
this.turnedOnBlurRightPadding = options.turnedOnBlurRightPadding ?? options.turnedOnRightPadding ?? this.blurRightPadding ;
this.turnedOffBlurLeftPadding = options.turnedOffBlurLeftPadding ?? options.turnedOffLeftPadding ?? this.blurLeftPadding ;
this.turnedOffBlurRightPadding = options.turnedOffBlurRightPadding ?? options.turnedOffRightPadding ?? this.blurRightPadding ;
this.turnedOnFocusLeftPadding = options.turnedOnFocusLeftPadding ?? options.turnedOnLeftPadding ?? this.focusLeftPadding ;
this.turnedOnFocusRightPadding = options.turnedOnFocusRightPadding ?? options.turnedOnRightPadding ?? this.focusRightPadding ;
this.turnedOffFocusLeftPadding = options.turnedOffFocusLeftPadding ?? options.turnedOffLeftPadding ?? this.focusLeftPadding ;
this.turnedOffFocusRightPadding = options.turnedOffFocusRightPadding ?? options.turnedOffRightPadding ?? this.focusRightPadding ;
this.paddingHasMarkup = !! options.paddingHasMarkup ;

@@ -143,7 +143,6 @@

module.exports = BaseMenu ;
Element.inherit( BaseMenu ) ;
BaseMenu.prototype = Object.create( Element.prototype ) ;
BaseMenu.prototype.constructor = BaseMenu ;
BaseMenu.prototype.elementType = 'BaseMenu' ;
BaseMenu.prototype.needInput = true ;

@@ -157,6 +156,2 @@

this.off( 'key' , this.onKey ) ;
this.off( 'wheel' , this.onWheel ) ;
this.off( 'focus' , this.onFocus ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;

@@ -262,60 +257,2 @@ } ;

BaseMenu.prototype.onKey = function( key , trash , data ) {
switch( this.keyBindings[ key ] ) {
case 'previous' :
this.focusChild = this.focusPreviousChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ 0 ] && this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
break ;
case 'next' :
this.focusChild = this.focusNextChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ this.children.length - 1 ] && this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
break ;
case 'previousPage' :
if ( this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
break ;
case 'nextPage' :
if ( this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
break ;
case 'firstPage' :
if ( this.maxPage && this.page !== 0 ) {
this.toPage( 0 , 'backCycle' ) ;
}
break ;
case 'lastPage' :
if ( this.maxPage && this.page !== this.maxPage ) {
this.toPage( this.maxPage , 'cycle' ) ;
}
break ;
case 'parentMenu' :
if ( this.isSubmenu ) {
// Back up the parent, because current instance can be destroyed by parent.closeSubmenu()
let parent = this.parent ;
if ( this.parent.submenuOptions.hideParent ) { this.parent.closeSubmenu() ; }
parent.document.giveFocusTo( parent ) ;
}
break ;
case 'submenu' :
//if ( this.hasSubmenu && this.focusChild?.def?.items ) {
if ( this.hasSubmenu && this.focusChild && this.focusChild.def && this.focusChild.def.items ) {
this.openSubmenu( this.focusChild.value , this.focusChild ) ;
if ( this.submenu ) { this.document.giveFocusTo( this.submenu ) ; }
}
break ;
default :
return ; // Bubble up
}
return true ; // Do not bubble up
} ;
BaseMenu.prototype.onWheel = function( data ) {

@@ -335,4 +272,10 @@ if ( data.yDirection < 0 ) { this.previousPage( 'backCycle' ) ; }

process.nextTick( () => {
if ( this.focusChild && ! this.focusChild.destroyed ) { this.document.giveFocusTo( this.focusChild , 'delegate' ) ; }
else { this.focusChild = this.focusNextChild() ; }
let forceType = type === 'clear' ? type : undefined ;
if ( this.focusChild && ! this.focusChild.destroyed ) {
this.document.giveFocusTo( this.focusChild , forceType || 'delegate' ) ;
}
else {
this.focusChild = this.focusNextChild( undefined , forceType ) ;
}
} ) ;

@@ -363,3 +306,3 @@ }

else {
this.emit( 'submit' , buttonValue , action , this ) ;
this.emit( 'submit' , buttonValue , action , this , button ) ;
}

@@ -383,3 +326,3 @@ }

else {
this.emit( 'blinked' , buttonValue , action , this ) ;
this.emit( 'blinked' , buttonValue , action , this , button ) ;
}

@@ -407,4 +350,4 @@ }

BaseMenu.prototype.onSubmenuSubmit = function( buttonValue , action , button ) {
button.once( 'blinked' , ( buttonValue_ , reserved , button_ ) => {
BaseMenu.prototype.onSubmenuSubmit = function( buttonValue , action , submenu , button ) {
submenu.once( 'blinked' , ( buttonValue_ , reserved , submenu_ , button_ ) => {
if ( this.submenuOptions.closeOn === 'childSubmit' ) {

@@ -414,6 +357,6 @@ this.closeSubmenu() ;

}
this.emit( 'blinked' , buttonValue_ , reserved , this ) ;
this.emit( 'blinked' , buttonValue_ , reserved , this , button ) ;
} ) ;
this.emit( 'submit' , buttonValue , action , this ) ;
this.emit( 'submit' , buttonValue , action , this , button ) ;
} ;

@@ -460,3 +403,2 @@

//this.submenu = new ColumnMenu( Object.assign( {} , this.submenuOptions , {
this.submenu = new this.constructor( Object.assign( {} , this.submenuOptions , {

@@ -475,3 +417,5 @@ internal: true ,

this.redraw() ;
// Draw instead of outerDraw?
//this.draw() ;
this.outerDraw() ;

@@ -483,2 +427,5 @@ if ( this.submenuOptions.focusOnOpen ) {

this.submenu.on( 'submit' , this.onSubmenuSubmit ) ;
// Re-emit itemFocus from child
this.submenu.on( 'itemFocus' , ( ... args ) => this.emit( 'itemFocus' , ... args ) ) ;
} ;

@@ -500,3 +447,2 @@

BaseMenu.prototype.defaultOptions = {} ;
BaseMenu.prototype.keyBindings = {} ;
BaseMenu.prototype.buttonKeyBindings = {} ;

@@ -510,1 +456,80 @@ BaseMenu.prototype.buttonActionKeyBindings = {} ;

const userActions = BaseMenu.prototype.userActions ;
userActions.character =
userActions.specialKey = function( key ) {
var index = this.hotkeyToButtonIndex.get( key ) ;
if ( index !== undefined && this.buttons[ index ] ) {
if ( this.document ) {
this.document.giveFocusTo( this.buttons[ index ] ) ;
}
this.buttons[ index ].submit() ;
}
else {
// Force bubble
return false ;
}
} ;
userActions.previous = function() {
this.focusChild = this.focusPreviousChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ 0 ] && this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
} ;
userActions.next = function() {
this.focusChild = this.focusNextChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ this.children.length - 1 ] && this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
} ;
userActions.previousPage = function() {
if ( this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
} ;
userActions.nextPage = function() {
if ( this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
} ;
userActions.firstPage = function() {
if ( this.maxPage && this.page !== 0 ) {
this.toPage( 0 , 'backCycle' ) ;
}
} ;
userActions.lastPage = function() {
if ( this.maxPage && this.page !== this.maxPage ) {
this.toPage( this.maxPage , 'cycle' ) ;
}
} ;
userActions.parentMenu = function() {
if ( this.isSubmenu ) {
// Back up the parent, because current instance can be destroyed by parent.closeSubmenu()
let parent = this.parent ;
if ( this.parent.submenuOptions.hideParent ) { this.parent.closeSubmenu() ; }
parent.document.giveFocusTo( parent ) ;
}
else {
return false ;
}
} ;
userActions.submenu = function() {
if ( this.hasSubmenu && this.focusChild?.def?.items ) {
this.openSubmenu( this.focusChild.value , this.focusChild ) ;
if ( this.submenu ) { this.document.giveFocusTo( this.submenu ) ; }
}
else {
return false ;
}
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -43,59 +43,36 @@ The MIT License (MIT)

this.blurContent =
options.blurContent ? ( Array.isArray( options.blurContent ) ? options.blurContent : [ options.blurContent ] ) :
options.content ;
this.blurLeftPadding = options.blurLeftPadding ?? options.leftPadding ?? '' ;
this.blurRightPadding = options.blurRightPadding ?? options.rightPadding ?? '' ;
this.focusLeftPadding = options.focusLeftPadding ?? options.leftPadding ?? '' ;
this.focusRightPadding = options.focusRightPadding ?? options.rightPadding ?? '' ;
this.disabledLeftPadding = options.disabledLeftPadding ?? options.leftPadding ?? '' ;
this.disabledRightPadding = options.disabledRightPadding ?? options.rightPadding ?? '' ;
this.submittedLeftPadding = options.submittedLeftPadding ?? options.leftPadding ?? '' ;
this.submittedRightPadding = options.submittedRightPadding ?? options.rightPadding ?? '' ;
this.focusContent =
options.focusContent ? ( Array.isArray( options.focusContent ) ? options.focusContent : [ options.focusContent ] ) :
options.content ;
// Used by ToggleButton, it's easier to move the functionality here to compute size at only one place
this.turnedOnBlurLeftPadding = options.turnedOnBlurLeftPadding ?? options.turnedOnLeftPadding ?? this.blurLeftPadding ;
this.turnedOnBlurRightPadding = options.turnedOnBlurRightPadding ?? options.turnedOnRightPadding ?? this.blurRightPadding ;
this.turnedOffBlurLeftPadding = options.turnedOffBlurLeftPadding ?? options.turnedOffLeftPadding ?? this.blurLeftPadding ;
this.turnedOffBlurRightPadding = options.turnedOffBlurRightPadding ?? options.turnedOffRightPadding ?? this.blurRightPadding ;
this.turnedOnFocusLeftPadding = options.turnedOnFocusLeftPadding ?? options.turnedOnLeftPadding ?? this.focusLeftPadding ;
this.turnedOnFocusRightPadding = options.turnedOnFocusRightPadding ?? options.turnedOnRightPadding ?? this.focusRightPadding ;
this.turnedOffFocusLeftPadding = options.turnedOffFocusLeftPadding ?? options.turnedOffLeftPadding ?? this.focusLeftPadding ;
this.turnedOffFocusRightPadding = options.turnedOffFocusRightPadding ?? options.turnedOffRightPadding ?? this.focusRightPadding ;
this.disabledContent =
options.disabledContent ? ( Array.isArray( options.disabledContent ) ? options.disabledContent : [ options.disabledContent ] ) :
options.content ;
this.contentHasMarkup = !! options.contentHasMarkup ; // Force this now, instead of Element behavior
this.paddingHasMarkup = !! options.paddingHasMarkup ;
this.submittedContent =
options.submittedContent ? ( Array.isArray( options.submittedContent ) ? options.submittedContent : [ options.submittedContent ] ) :
options.content ;
// Set by .setContent()
this.content =
this.blurContent = this.focusContent =
this.disabledContent = this.submittedContent =
this.turnedOnBlurContent = this.turnedOffBlurContent =
this.turnedOnFocusContent = this.turnedOffFocusContent = '' ;
this.turnedOnBlurContent =
options.turnedOnBlurContent ? ( Array.isArray( options.turnedOnBlurContent ) ? options.turnedOnBlurContent : [ options.turnedOnBlurContent ] ) :
options.turnedOnContent ? ( Array.isArray( options.turnedOnContent ) ? options.turnedOnContent : [ options.turnedOnContent ] ) :
options.content ;
// We need to compute that now
if ( this.setContent === Button.prototype.setContent ) {
this.setContent( options , this.contentHasMarkup , true , true ) ;
}
this.turnedOffBlurContent =
options.turnedOffBlurContent ? ( Array.isArray( options.turnedOffBlurContent ) ? options.turnedOffBlurContent : [ options.turnedOffBlurContent ] ) :
options.turnedOffContent ? ( Array.isArray( options.turnedOffContent ) ? options.turnedOffContent : [ options.turnedOffContent ] ) :
options.content ;
this.turnedOnFocusContent =
options.turnedOnFocusContent ? ( Array.isArray( options.turnedOnFocusContent ) ? options.turnedOnFocusContent : [ options.turnedOnFocusContent ] ) :
options.turnedOnContent ? ( Array.isArray( options.turnedOnContent ) ? options.turnedOnContent : [ options.turnedOnContent ] ) :
options.content ;
this.turnedOffFocusContent =
options.turnedOffFocusContent ? ( Array.isArray( options.turnedOffFocusContent ) ? options.turnedOffFocusContent : [ options.turnedOffFocusContent ] ) :
options.turnedOffContent ? ( Array.isArray( options.turnedOffContent ) ? options.turnedOffContent : [ options.turnedOffContent ] ) :
options.content ;
this.blurLeftPadding = options.blurLeftPadding || options.leftPadding || '' ;
this.blurRightPadding = options.blurRightPadding || options.rightPadding || '' ;
this.focusLeftPadding = options.focusLeftPadding || options.leftPadding || '' ;
this.focusRightPadding = options.focusRightPadding || options.rightPadding || '' ;
this.disabledLeftPadding = options.disabledLeftPadding || options.leftPadding || '' ;
this.disabledRightPadding = options.disabledRightPadding || options.rightPadding || '' ;
this.submittedLeftPadding = options.submittedLeftPadding || options.leftPadding || '' ;
this.submittedRightPadding = options.submittedRightPadding || options.rightPadding || '' ;
// Used by ToggleButton, it's easier to move the functionality here to compute size at only one place
this.turnedOnBlurLeftPadding = options.turnedOnBlurLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
this.turnedOnBlurRightPadding = options.turnedOnBlurRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
this.turnedOffBlurLeftPadding = options.turnedOffBlurLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
this.turnedOffBlurRightPadding = options.turnedOffBlurRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
this.turnedOnFocusLeftPadding = options.turnedOnFocusLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
this.turnedOnFocusRightPadding = options.turnedOnFocusRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
this.turnedOffFocusLeftPadding = options.turnedOffFocusLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
this.turnedOffFocusRightPadding = options.turnedOffFocusRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
this.paddingHasMarkup = !! options.paddingHasMarkup ;
// Used by menus, to assign nextPage/previousPage action

@@ -110,6 +87,2 @@ this.internalRole = options.internalRole || null ;

if ( this.setContent === Button.prototype.setContent ) {
this.setContent( options.content || '' , options.contentHasMarkup , true , true ) ;
}
this.blurAttr = options.blurAttr || { bgColor: 'brightBlack' } ;

@@ -120,3 +93,3 @@ this.focusAttr = options.focusAttr || { bgColor: 'blue' } ;

this.turnedOnBlurAttr = options.turnedOnBlurAttr || { bgColor: 'cyan' } ;
this.turnedOnFocusAttr = options.turnedOnFocusAttr || { bgColor: 'brightCyan' , bold: true } ;
this.turnedOnFocusAttr = options.turnedOnFocusAttr || { bgColor: 'brightCyan' , color: 'gray' , bold: true } ;
this.turnedOffBlurAttr = options.turnedOffBlurAttr || { bgColor: 'gray' , dim: true } ;

@@ -134,3 +107,2 @@ this.turnedOffFocusAttr = options.turnedOffFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;

this.onKey = this.onKey.bind( this ) ;
this.onShortcut = this.onShortcut.bind( this ) ;

@@ -158,7 +130,6 @@ this.onFocus = this.onFocus.bind( this ) ;

module.exports = Button ;
Element.inherit( Button , Text ) ;
Button.prototype = Object.create( Text.prototype ) ;
Button.prototype.constructor = Button ;
Button.prototype.elementType = 'Button' ;
Button.prototype.needInput = true ;

@@ -180,12 +151,5 @@

Button.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'shortcut' , this.onShortcut ) ;
this.off( 'focus' , this.onFocus ) ;
this.off( 'click' , this.onClick ) ;
this.off( 'hover' , this.onHover ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
// Utility function
Button.prototype._toContentArray = function( content ) {
return ! this.forceContentArray || Array.isArray( content ) ? content : [ content || '' ] ;
} ;

@@ -196,12 +160,45 @@

Button.prototype.setContent = function( content , hasMarkup , dontDraw = false , dontResize = false ) {
Element.prototype.setContent.call( this , content , hasMarkup , true , true ) ;
this.contentHasMarkup = hasMarkup ;
this.blurContent = this.focusContent =
this.disabledContent = this.submittedContent =
this.turnedOnBlurContent = this.turnedOffBlurContent =
this.turnedOnFocusContent = this.turnedOffFocusContent =
this.content ;
if ( ! content || typeof content !== 'object' || Array.isArray( content ) ) {
this.content = this._toContentArray( content ) ;
this.contentWidth = Element.computeContentWidth( this.content , this.contentHasMarkup ) ;
this.blurContent = this.focusContent =
this.disabledContent = this.submittedContent =
this.turnedOnBlurContent = this.turnedOffBlurContent =
this.turnedOnFocusContent = this.turnedOffFocusContent =
this.content ;
}
else {
if ( content.internal ) {
// This is called from the constructor using the options argument
this.content = this._toContentArray( content.content ) ;
this.blurContent = this._toContentArray( content.blurContent ?? this.content ) ;
this.focusContent = this._toContentArray( content.focusContent ?? this.content ) ;
this.disabledContent = this._toContentArray( content.disabledContent ?? this.content ) ;
this.submittedContent = this._toContentArray( content.submittedContent ?? this.content ) ;
this.turnedOnBlurContent = this._toContentArray( content.turnedOnBlurContent ?? content.turnedOnContent ?? this.content ) ;
this.turnedOffBlurContent = this._toContentArray( content.turnedOffBlurContent ?? content.turnedOffContent ?? this.content ) ;
this.turnedOnFocusContent = this._toContentArray( content.turnedOnFocusContent ?? content.turnedOnContent ?? this.content ) ;
this.turnedOffFocusContent = this._toContentArray( content.turnedOffFocusContent ?? content.turnedOffContent ?? this.content ) ;
}
else {
// Regular call (user, normal case)
this.content = this._toContentArray( content.default ) ;
this.blurContent = this._toContentArray( content.blur ?? this.content ) ;
this.focusContent = this._toContentArray( content.focus ?? this.content ) ;
this.disabledContent = this._toContentArray( content.disabled ?? this.content ) ;
this.submittedContent = this._toContentArray( content.submitted ?? this.content ) ;
this.turnedOnBlurContent = this._toContentArray( content.turnedOnBlur ?? content.turnedOn ?? this.content ) ;
this.turnedOffBlurContent = this._toContentArray( content.turnedOffBlur ?? content.turnedOff ?? this.content ) ;
this.turnedOnFocusContent = this._toContentArray( content.turnedOnFocus ?? content.turnedOn ?? this.content ) ;
this.turnedOffFocusContent = this._toContentArray( content.turnedOffFocus ?? content.turnedOff ?? this.content ) ;
}
this.computeContentWidth( content , this.contentHasMarkup ) ;
}
if ( ! dontResize && this.resizeOnContent ) { this.resizeOnContent() ; }
if ( ! dontDraw ) { this.redraw() ; }
if ( ! dontDraw ) { this.outerDraw() ; }
} ;

@@ -211,2 +208,19 @@

Button.prototype.computeContentWidth = function() {
this.contentWidth = Math.max(
Element.computeContentWidth( this.blurContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.focusContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.disabledContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.submittedContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.turnedOnFocusContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.turnedOffFocusContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.turnedOnBlurContent , this.contentHasMarkup ) ,
Element.computeContentWidth( this.turnedOffBlurContent , this.contentHasMarkup )
) ;
return this.contentWidth ;
} ;
Button.prototype.computeRequiredWidth = function() {

@@ -274,3 +288,2 @@ return (

Button.prototype.onFocus = function( focus , type ) {
this.hasFocus = focus ;
this.updateStatus() ;

@@ -328,17 +341,2 @@ this.draw() ;

Button.prototype.onKey = function( key , altKeys , data ) {
switch( this.keyBindings[ key ] ) {
case 'submit' :
if ( this.disabled || this.submitted ) { break ; }
this.submit( this.actionKeyBindings[ key ] ) ;
break ;
default :
return ; // Bubble up
}
return true ; // Do not bubble up
} ;
Button.prototype.onHover = function( data ) {

@@ -381,1 +379,10 @@ if ( this.disabled || this.submitted ) { return ; }

const userActions = Button.prototype.userActions ;
userActions.submit = function( key ) {
if ( this.disabled || this.submitted ) { return ; }
this.submit( this.actionKeyBindings[ key ] ) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -89,9 +89,6 @@ The MIT License (MIT)

module.exports = ColumnMenu ;
Element.inherit( ColumnMenu , BaseMenu ) ;
ColumnMenu.prototype = Object.create( BaseMenu.prototype ) ;
ColumnMenu.prototype.constructor = ColumnMenu ;
ColumnMenu.prototype.elementType = 'ColumnMenu' ;
ColumnMenu.prototype.inlineNewLine = true ;

@@ -108,6 +105,6 @@ ColumnMenu.prototype.ButtonClass = Button ;

buttonSubmittedAttr: { bgColor: 'gray' , color: 'brightWhite' , bold: true } ,
turnedOnBlurAttr: { bgColor: 'cyan' } ,
turnedOnFocusAttr: { bgColor: 'brightCyan' , bold: true } ,
turnedOffBlurAttr: { bgColor: 'gray' , dim: true } ,
turnedOffFocusAttr: { bgColor: 'white' , color: 'black' , bold: true }
buttonTurnedOnBlurAttr: { bgColor: 'cyan' } ,
buttonTurnedOnFocusAttr: { bgColor: 'brightCyan' , color: 'gray' , bold: true } ,
buttonTurnedOffBlurAttr: { bgColor: 'gray' , dim: true } ,
buttonTurnedOffFocusAttr: { bgColor: 'white' , color: 'black' , bold: true }
} ;

@@ -117,14 +114,2 @@

ColumnMenu.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'focus' , this.onFocus ) ;
this.off( 'parentResize' , this.onParentResize ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
ColumnMenu.prototype.keyBindings = {

@@ -346,7 +331,12 @@ UP: 'previous' ,

ButtonConstructor = def.internalRole ? Button : this.ButtonClass ;
ButtonConstructor = def.internalRole ? Button :
def.type === 'button' ? Button :
def.type === 'toggle' ? ToggleButton :
this.ButtonClass ?? Button ;
isToggle = ButtonConstructor === ToggleButton || ButtonConstructor.prototype instanceof ToggleButton ;
key = def.key ; // For ToggleButton
value = this.childUseParentKeyValue && key && this.value && typeof this.value === 'object' ? this.value[ key ] : def.value ;
value = this.childUseParentKeyValue && key && this.value && typeof this.value === 'object' ? this.value[ key ] :
def.value === undefined && ! isToggle && def.key ? def.key :
def.value ;

@@ -388,6 +378,6 @@ if ( index % 2 ) {

submittedAttr: def.submittedAttr || this.buttonSubmittedAttr ,
turnedOnFocusAttr: def.turnedOnFocusAttr || this.turnedOnFocusAttr ,
turnedOffFocusAttr: def.turnedOffFocusAttr || this.turnedOffFocusAttr ,
turnedOnBlurAttr: def.turnedOnBlurAttr || this.turnedOnBlurAttr ,
turnedOffBlurAttr: def.turnedOffBlurAttr || this.turnedOffBlurAttr ,
turnedOnFocusAttr: def.turnedOnFocusAttr || this.buttonTurnedOnFocusAttr ,
turnedOffFocusAttr: def.turnedOffFocusAttr || this.buttonTurnedOffFocusAttr ,
turnedOnBlurAttr: def.turnedOnBlurAttr || this.buttonTurnedOnBlurAttr ,
turnedOffBlurAttr: def.turnedOffBlurAttr || this.buttonTurnedOffBlurAttr ,

@@ -433,3 +423,3 @@ blurLeftPadding: this.blurLeftPadding ,

// Set outputHeight to the correct value
if ( buttonOffsetY < this.outputHeight ) { this.needRedraw = true ; }
if ( buttonOffsetY < this.outputHeight ) { this.needOuterDraw = true ; }
this.pageHeight = this.outputHeight = buttonOffsetY ;

@@ -436,0 +426,0 @@ } ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,2 +31,3 @@ The MIT License (MIT)

const Element = require( './Element.js' ) ;
const ColumnMenu = require( './ColumnMenu.js' ) ;

@@ -59,9 +60,6 @@ const ToggleButton = require( './ToggleButton.js' ) ;

module.exports = ColumnMenuMulti ;
Element.inherit( ColumnMenuMulti , ColumnMenu ) ;
ColumnMenuMulti.prototype = Object.create( ColumnMenu.prototype ) ;
ColumnMenuMulti.prototype.constructor = ColumnMenuMulti ;
ColumnMenuMulti.prototype.elementType = 'ColumnMenuMulti' ;
ColumnMenuMulti.prototype.ButtonClass = ToggleButton ;

@@ -85,4 +83,5 @@ ColumnMenuMulti.prototype.childUseParentKeyValue = true ;

this.value = {} ;
if ( Array.isArray( value ) || value instanceof Set ) {
this.value = {} ;
for ( let key of value ) {

@@ -95,3 +94,5 @@ if ( key && typeof key === 'string' ) {

else {
this.value = value ;
for ( let key in value ) {
this.value[ key ] = !! value[ key ] ;
}
}

@@ -104,3 +105,3 @@

if ( button.internalRole || ! button.key || ! ( button instanceof ToggleButton ) ) { return ; }
button.setValue( this.value[ button.key ] ) ;
button.setValue( !! this.value[ button.key ] , true , true ) ;
} ) ;

@@ -113,44 +114,16 @@

ColumnMenuMulti.prototype.onKey = function( key , altKeys , data ) {
switch( this.keyBindings[ key ] ) {
case 'previous' :
this.focusChild = this.focusPreviousChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ 0 ] && this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
break ;
case 'next' :
this.focusChild = this.focusNextChild( ! this.maxPage ) ;
if ( this.focusChild === this.children[ this.children.length - 1 ] && this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
break ;
case 'previousPage' :
if ( this.maxPage && this.page > 0 ) {
this.previousPage( 'backCycle' ) ;
}
break ;
case 'nextPage' :
if ( this.maxPage && this.page < this.maxPage ) {
this.nextPage( 'cycle' ) ;
}
break ;
case 'firstPage' :
if ( this.maxPage && this.page !== 0 ) {
this.toPage( 0 , 'backCycle' ) ;
}
break ;
case 'lastPage' :
if ( this.maxPage && this.page !== this.maxPage ) {
this.toPage( this.maxPage , 'cycle' ) ;
}
break ;
case 'submit' :
this.emit( 'submit' , this.value , undefined , this ) ;
break ;
default :
return ; // Bubble up
}
ColumnMenuMulti.prototype.setKeyValue = function( key , value , noDraw ) {
if ( ! key ) { return ; }
return true ; // Do not bubble up
this.value[ key ] = !! value ;
// Can be called during init, before .initPage() is called
if ( ! this.buttons ) { return ; }
this.buttons.forEach( button => {
if ( button.internalRole || button.key !== key || ! ( button instanceof ToggleButton ) ) { return ; }
button.setValue( !! value , true , true ) ;
} ) ;
if ( ! noDraw ) { this.draw() ; }
} ;

@@ -169,3 +142,3 @@

default :
this.emit( 'submit' , this.value , action , this ) ;
this.emit( 'submit' , this.value , action , this , button ) ;
}

@@ -185,1 +158,9 @@ } ;

const userActions = ColumnMenuMulti.prototype.userActions ;
userActions.submit = function() {
this.emit( 'submit' , this.value , undefined , this ) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -36,7 +36,9 @@ The MIT License (MIT)

const Element = require( './Element.js' ) ;
const Slider = require( './Slider.js' ) ;
const ScreenBuffer = require( '../ScreenBuffer.js' ) ;
// Avoid requiring Slider at top-level, it could cause circular require troubles
//const Slider = require( './Slider.js' ) ;
function Container( options ) {

@@ -49,3 +51,2 @@ // Clone options if necessary

this.onKey = this.onKey.bind( this ) ;
this.onClick = this.onClick.bind( this ) ;

@@ -105,25 +106,13 @@ this.onDrag = this.onDrag.bind( this ) ;

module.exports = Container ;
Element.inherit( Container ) ;
Container.prototype = Object.create( Element.prototype ) ;
Container.prototype.constructor = Container ;
Container.prototype.elementType = 'Container' ;
Container.prototype.isContainer = true ;
Container.prototype.containerBorderSize = 0 ;
const termkit = require( '../termkit.js' ) ;
Container.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'click' , this.onClick ) ;
this.off( 'drag' , this.onDrag ) ;
this.off( 'wheel' , this.onWheel ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
Container.prototype.keyBindings = {

@@ -144,4 +133,6 @@ UP: 'tinyScrollUp' ,

Container.prototype.initChildren = function() {
// Avoid requiring Slider at top-level, it could cause circular require troubles
if ( this.hasVScrollBar ) {
this.vScrollBarSlider = new Slider( {
this.vScrollBarSlider = new termkit.Slider( {
internal: true ,

@@ -163,3 +154,3 @@ parent: this ,

if ( this.hasHScrollBar ) {
this.hScrollBarSlider = new Slider( {
this.hScrollBarSlider = new termkit.Slider( {
internal: true ,

@@ -233,3 +224,3 @@ parent: this ,

if ( ! noDraw ) { this.redraw() ; }
if ( ! noDraw ) { this.outerDraw() ; }
} ;

@@ -325,45 +316,2 @@

Container.prototype.onKey = function( key , trash , data ) {
switch( this.keyBindings[ key ] ) {
case 'tinyScrollUp' :
this.scroll( 0 , Math.ceil( this.viewportHeight / 5 ) ) ;
break ;
case 'tinyScrollDown' :
this.scroll( 0 , -Math.ceil( this.viewportHeight / 5 ) ) ;
break ;
case 'scrollUp' :
this.scroll( 0 , Math.ceil( this.viewportHeight / 2 ) ) ;
break ;
case 'scrollDown' :
this.scroll( 0 , -Math.ceil( this.viewportHeight / 2 ) ) ;
break ;
case 'scrollLeft' :
this.scroll( Math.ceil( this.viewportWidth / 2 ) , 0 ) ;
break ;
case 'scrollRight' :
this.scroll( -Math.ceil( this.viewportWidth / 2 ) , 0 ) ;
break ;
case 'scrollTop' :
this.scrollToTop() ;
break ;
case 'scrollBottom' :
this.scrollToBottom() ;
break ;
default :
return ; // Bubble up
}
return true ; // Do not bubble up
} ;
Container.prototype.onClick = function( data ) {

@@ -396,1 +344,37 @@ // It is susceptible to click event only when it is scrollable

const userActions = Container.prototype.userActions ;
userActions.tinyScrollUp = function() {
this.scroll( 0 , Math.ceil( this.viewportHeight / 5 ) ) ;
} ;
userActions.tinyScrollDown = function() {
this.scroll( 0 , -Math.ceil( this.viewportHeight / 5 ) ) ;
} ;
userActions.scrollUp = function() {
this.scroll( 0 , Math.ceil( this.viewportHeight / 2 ) ) ;
} ;
userActions.scrollDown = function() {
this.scroll( 0 , -Math.ceil( this.viewportHeight / 2 ) ) ;
} ;
userActions.scrollLeft = function() {
this.scroll( Math.ceil( this.viewportWidth / 2 ) , 0 ) ;
} ;
userActions.scrollRight = function() {
this.scroll( -Math.ceil( this.viewportWidth / 2 ) , 0 ) ;
} ;
userActions.scrollTop = function() {
this.scrollToTop() ;
} ;
userActions.scrollBottom = function() {
this.scrollToBottom() ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -109,5 +109,11 @@ The MIT License (MIT)

this.elementByShortcut = {} ;
this.documentClipboards = {} ;
//*
this.setClipboard = Promise.debounceUpdate( async ( str , source ) => {
this.getSystemClipboard = Promise.debounceDelay( 500 , async ( source ) => {
if ( ! this.outputDst.getClipboard ) { return '' ; }
return this.outputDst.getClipboard( source ) ;
} ) ;
this.setSystemClipboard = Promise.debounceUpdate( async ( str , source ) => {
if ( ! this.outputDst.setClipboard ) { return ; }

@@ -120,5 +126,8 @@ await this.outputDst.setClipboard( str , source ) ;

this.getClipboard = Promise.debounceDelay( 500 , async ( source ) => {
if ( ! this.outputDst.getClipboard ) { return '' ; }
return this.outputDst.getClipboard( source ) ;
this.clearSystemClipboard = Promise.debounceUpdate( async ( str , source ) => {
if ( ! this.outputDst.setClipboard ) { return ; }
await this.outputDst.setClipboard( '' , source ) ;
// Avoid running too much xclip shell command
await Promise.resolveTimeout( 500 ) ;
} ) ;

@@ -136,10 +145,6 @@ //*/

module.exports = Document ;
Element.inherit( Document , Container ) ;
//Document.prototype = Object.create( Element.prototype ) ;
Document.prototype = Object.create( Container.prototype ) ;
Document.prototype.constructor = Document ;
Document.prototype.elementType = 'Document' ;
Document.prototype.destroy = function( isSubDestroy , noDraw = false ) {

@@ -155,4 +160,4 @@ if ( this.destroyed ) { return ; }

this.eventSource = null ;
this.setClipboard = null ;
this.getClipboard = null ;
this.setSystemClipboard = null ;
this.getSystemClipboard = null ;
} ;

@@ -190,5 +195,4 @@

Document.prototype.giveFocusTo = function( element , type ) {
Document.prototype.giveFocusTo = function( element , type = 'direct' ) {
if ( ! ( element instanceof Element ) ) { throw new TypeError( '' + element + ' is not an instance of Element.' ) ; }
if ( ! type ) { type = 'direct' ; }
if ( this.isAncestorOf( element ) ) { return this.giveFocusTo_( element , type ) ; }

@@ -203,4 +207,9 @@ } ;

if ( this.focusElement !== element ) {
if ( this.focusElement ) { this.focusElement.emit( 'focus' , false , type , this.focusElement ) ; }
if ( this.focusElement ) {
this.focusElement.hasFocus = false ;
this.focusElement.emit( 'focus' , false , type , this.focusElement ) ;
}
this.focusElement = element ;
this.focusElement.hasFocus = true ;
this.focusElement.emit( 'focus' , true , type , this.focusElement ) ;

@@ -398,2 +407,10 @@ }

// TODOC
Document.prototype.setMetaKeyPrefix = function( prefix , remove ) { this.eventSource.setMetaKeyPrefix( prefix , remove ) ; } ;
Document.prototype.getDocumentClipboard = function( key = 'content' ) { return this.documentClipboards[ key ] ; } ;
Document.prototype.setDocumentClipboard = function( value , key = 'content' ) { this.documentClipboards[ key ] = '' + value ; } ;
Document.prototype.clearDocumentClipboard = function( value , key = 'content' ) { delete this.documentClipboards[ key ] ; } ;
Document.prototype.createShortcuts = function( element , ... keys ) {

@@ -508,25 +525,2 @@ if ( element.document !== this ) { return ; }

Document.prototype.mouseMotionStart = function( data ) {
var matches ;
this.motionData.motion = true ;
this.motionData.xFrom = data.xFrom ;
this.motionData.yFrom = data.yFrom ;
this.motionData.x = data.xFrom ; // We use xFrom/yFrom, .mouseMotion() will update it using x/y, setting dx/dy to the delta
this.motionData.y = data.yFrom ;
//this.motionData.element = matches[ 0 ].element ;
//this.motionData.localDx = matches[ 0 ].x - data.xFrom ;
//this.motionData.localDy = matches[ 0 ].y - data.yFrom ;
//matches[ 0 ].element.emit( 'motionStart' , { x: matches[ 0 ].x , y: matches[ 0 ].y } , matches[ 0 ].element ) ;
} ;
Document.prototype.mouseMotionEnd = function() {
this.motionData.motion = false ;
} ;
// Also called from within .mouseDrag()

@@ -581,3 +575,77 @@ Document.prototype.mouseMotion = function( data , exclude = null ) {

Document.prototype.mouseMotionStart = function( data ) {
var matches ;
this.motionData.motion = true ;
this.motionData.xFrom = data.xFrom ;
this.motionData.yFrom = data.yFrom ;
this.motionData.x = data.xFrom ; // We use xFrom/yFrom, .mouseMotion() will update it using x/y, setting dx/dy to the delta
this.motionData.y = data.yFrom ;
//this.motionData.element = matches[ 0 ].element ;
//this.motionData.localDx = matches[ 0 ].x - data.xFrom ;
//this.motionData.localDy = matches[ 0 ].y - data.yFrom ;
//matches[ 0 ].element.emit( 'motionStart' , { x: matches[ 0 ].x , y: matches[ 0 ].y } , matches[ 0 ].element ) ;
} ;
Document.prototype.mouseMotionEnd = function() {
this.motionData.motion = false ;
} ;
Document.prototype.mouseDrag = function( data ) {
var starting = false ;
//console.error( "Drag event:" , JSON.stringify( data ) ) ;
if ( ! this.draggingData.dragging ) {
starting = true ;
this.mouseDragStart( data ) ;
}
this.draggingData.dx = data.x - this.draggingData.x ;
this.draggingData.dy = data.y - this.draggingData.y ;
this.draggingData.x = data.x ;
this.draggingData.y = data.y ;
// Newest Gnome-Terminal send drag event even when no progress have been made, this check avoid useless computing.
if ( ! starting && ! this.draggingData.dx && ! this.draggingData.dy ) { return ; }
// To send a 'drag' event, the origin of the drag should be on the same element
if ( this.draggingData.element ) {
let emitDrag = true ;
if ( ! this.draggingData.element.outerDrag ) {
let matches = this.childrenAt( data.x - this.outputX , data.y - this.outputY , COMMON_MOUSE_AWARE_FILTER ) ;
//console.error( "\tDrag event test:" , this.draggingData.element.debugId() , matches.map( m => m.element.debugId() ) ) ;
emitDrag = matches.some( m => m.element === this.draggingData.element ) ;
}
if ( emitDrag ) {
this.draggingData.element.emit(
'drag' ,
{
xFrom: this.draggingData.xFrom + this.draggingData.localDx ,
yFrom: this.draggingData.yFrom + this.draggingData.localDy ,
x: data.x + this.draggingData.localDx ,
y: data.y + this.draggingData.localDy ,
dx: this.draggingData.dx ,
dy: this.draggingData.dy
} ,
this.draggingData.element
) ;
}
}
// Call .mouseMotion() but exclude the current dragged element
this.mouseMotion( data , this.draggingData.element ) ;
} ;
Document.prototype.mouseDragStart = function( data ) {
//console.error( "Drag START event:" , JSON.stringify( data ) ) ;
var matches ;

@@ -594,2 +662,6 @@

if ( ! matches.length ) {
this.draggingData.element = null ;
this.draggingData.localDx = null ;
this.draggingData.localDy = null ;
if ( this.hoverElement ) {

@@ -613,2 +685,3 @@ this.hoverElement.emit( 'leave' ) ;

Document.prototype.mouseDragEnd = function( data ) {
//console.error( "Drag END event:" , JSON.stringify( data ) ) ;
if ( this.draggingData.element ) {

@@ -632,42 +705,2 @@ this.draggingData.element.emit(

Document.prototype.mouseDrag = function( data ) {
var starting = false ;
if ( ! this.draggingData.dragging ) {
starting = true ;
this.mouseDragStart( data ) ;
}
//console.error( "mouseDrag" , data ) ;
this.draggingData.dx = data.x - this.draggingData.x ;
this.draggingData.dy = data.y - this.draggingData.y ;
this.draggingData.x = data.x ;
this.draggingData.y = data.y ;
// Newest Gnome-Terminal send drag event even when no progress have been made, this check avoid useless computing.
if ( ! starting && ! this.draggingData.dx && ! this.draggingData.dy ) { return ; }
// To send a 'drag' event, the origin of the drag should be on the same element
if ( this.draggingData.element ) {
this.draggingData.element.emit(
'drag' ,
{
xFrom: this.draggingData.xFrom + this.draggingData.localDx ,
yFrom: this.draggingData.yFrom + this.draggingData.localDy ,
x: data.x + this.draggingData.localDx ,
y: data.y + this.draggingData.localDy ,
dx: this.draggingData.dx ,
dy: this.draggingData.dy
} ,
this.draggingData.element
) ;
}
// Call .mouseMotion() but exclude the current dragged element
this.mouseMotion( data , this.draggingData.element ) ;
} ;
Document.prototype.mouseWheel = function( data ) {

@@ -674,0 +707,0 @@ //var matches = this.childrenAt( data.x - this.outputX , data.y - this.outputY , COMMON_MOUSE_AWARE_FILTER ) ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,5 +31,6 @@ The MIT License (MIT)

//const Element = require( './Element.js' ) ;
const Element = require( './Element.js' ) ;
const ToggleButton = require( './ToggleButton.js' ) ;
const RowMenu = require( './RowMenu.js' ) ;
const ColumnMenu = require( './ColumnMenu.js' ) ;
const ColumnMenuMixed = require( './ColumnMenuMixed.js' ) ;

@@ -45,2 +46,9 @@

if ( options.value && typeof options.value === 'object' ) {
this.setValue( options.value , true ) ;
}
else {
this.value = {} ;
}
RowMenu.call( this , options ) ;

@@ -51,18 +59,22 @@

this.columnMenu = null ;
this.columnButtonBlurAttr = options.buttonBlurAttr || { bgColor: 'gray' , color: 'white' , bold: true } ;
this.columnButtonFocusAttr = options.buttonFocusAttr || { bgColor: 'blue' , color: 'white' , bold: true } ;
this.columnButtonBlurAttr = options.buttonBlurAttr || { bgColor: 'brightBlack' , color: 'white' , bold: true } ;
this.columnButtonTurnedOnBlurAttr = options.buttonTurnedOnBlurAttr || { bgColor: 'gray' , color: 'white' , bold: true } ;
this.columnButtonTurnedOnFocusAttr = options.buttonTurnedOnFocusAttr || { bgColor: 'blue' , color: 'white' , bold: true } ;
this.columnButtonTurnedOffBlurAttr = options.buttonTurnedOffBlurAttr || { bgColor: 'gray' , color: 'white' , dim: true } ;
this.columnButtonTurnedOffFocusAttr = options.buttonTurnedOffFocusAttr || { bgColor: 'blue' , color: 'white' , dim: true } ;
this.clearColumnMenuOnSubmit = !! options.clearColumnMenuOnSubmit ;
this.lastFocusButton = null ;
this.onClickOut = this.onClickOut.bind( this ) ;
this.onButtonFocus = this.onButtonFocus.bind( this ) ;
this.onButtonSubmit = this.onButtonSubmit.bind( this ) ;
this.onColumnMenuSubmit = this.onColumnMenuSubmit.bind( this ) ;
//this.onColumnMenuFocus = this.onColumnMenuFocus.bind( this ) ;
// Bounded by BaseMenu:
//this.onButtonSubmit = this.onButtonSubmit.bind( this ) ;
//this.onButtonFocus = this.onButtonFocus.bind( this ) ;
this.on( 'clickOut' , this.onClickOut ) ;
for ( i = 0 , iMax = this.buttons.length ; i < iMax ; i ++ ) {
this.buttons[ i ].on( 'focus' , this.onButtonFocus ) ;
}
// Only draw if we are not a superclass of the object

@@ -73,19 +85,6 @@ if ( this.elementType === 'DropDownMenu' && ! options.noDraw ) { this.draw() ; }

module.exports = DropDownMenu ;
Element.inherit( DropDownMenu , RowMenu ) ;
DropDownMenu.prototype = Object.create( RowMenu.prototype ) ;
DropDownMenu.prototype.constructor = DropDownMenu ;
DropDownMenu.prototype.elementType = 'DropDownMenu' ;
DropDownMenu.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'clickOut' , this.onClickOut ) ;
RowMenu.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
DropDownMenu.prototype.keyBindings = {

@@ -104,7 +103,5 @@ LEFT: 'previous' ,

DropDownMenu.prototype.dropDown = function( index , x , y , submittedButtonValue , submittedButtonAction ) {
DropDownMenu.prototype.dropDown = function( index , x , y , submittedButtonValue , submittedButtonAction , button ) {
var itemsDef = this.itemsDef[ index ].items ;
//console.error( "Submit!" , button.childId ) ;
if ( this.columnMenu ) {

@@ -120,3 +117,3 @@ // Already dropped down? Nothing to do!

// Top-button without submenu that have a 'topSubmit' flag on submits themselves
this.emit( 'submit' , submittedButtonValue , submittedButtonAction , this ) ;
this.emit( 'submit' , submittedButtonValue , submittedButtonAction , this , button ) ;
}

@@ -127,4 +124,6 @@

var hasToggle = itemsDef.some( def => def.type === 'toggle' ) ;
// Make the ColumnMenu a child of the button, so focus cycle will work as expected
this.columnMenu = new ColumnMenu( {
var columnMenuOptions = {
internal: true ,

@@ -138,6 +137,21 @@ parent: this.children[ index ] ,

items: itemsDef ,
value: this.value ,
buttonFocusAttr: this.columnButtonFocusAttr ,
buttonBlurAttr: this.columnButtonBlurAttr
} ) ;
buttonBlurAttr: this.columnButtonBlurAttr ,
buttonTurnedOnBlurAttr: this.columnButtonTurnedOnBlurAttr ,
buttonTurnedOnFocusAttr: this.columnButtonTurnedOnFocusAttr ,
buttonTurnedOffBlurAttr: this.columnButtonTurnedOffBlurAttr ,
buttonTurnedOffFocusAttr: this.columnButtonTurnedOffFocusAttr
} ;
if ( hasToggle ) {
columnMenuOptions.leftPadding = ' ' ;
//columnMenuOptions.turnedOnLeftPadding = ' ✓ ' ;
//columnMenuOptions.turnedOffLeftPadding = ' ✗ ' ;
columnMenuOptions.turnedOnLeftPadding = ' ☑ ' ;
columnMenuOptions.turnedOffLeftPadding = ' ☐ ' ;
}
this.columnMenu = new ColumnMenuMixed( columnMenuOptions ) ;
this.columnMenu.on( 'submit' , this.onColumnMenuSubmit ) ;

@@ -154,6 +168,11 @@ //this.columnMenu.on( 'focus' , this.onColumnMenuFocus ) ;

DropDownMenu.prototype.clearColumnMenu = function() {
DropDownMenu.prototype.clearColumnMenu = function( focusHeadButton = false ) {
if ( ! this.columnMenu ) { return false ; }
this.columnMenu.destroy() ;
this.columnMenu = null ;
if ( focusHeadButton && this.lastFocusButton ) {
this.document.giveFocusTo( this.lastFocusButton , 'clear' ) ;
}
return true ;

@@ -164,2 +183,21 @@ } ;

DropDownMenu.prototype.setValue = function( value , noDraw ) {
if ( ! value || typeof value !== 'object' ) { return ; }
this.value = {} ;
for ( let key in value ) { this.value[ key ] = !! value[ key ] ; }
if ( this.columnMenu ) { this.columnMenu.setValue( value , noDraw ) ; }
} ;
DropDownMenu.prototype.setKeyValue = function( key , value , noDraw ) {
if ( ! key ) { return ; }
this.value[ key ] = !! value ;
if ( this.columnMenu ) { this.columnMenu.setKeyValue( key , value , noDraw ) ; }
} ;
DropDownMenu.prototype.setDropDownItem = function( topItemValue , dropDownItemValue , itemOptions ) {

@@ -194,3 +232,3 @@ var topItem = this.itemsDef.find( e => e.value === topItemValue ) ;

DropDownMenu.prototype.onButtonSubmit = function( buttonValue , action , button ) {
this.dropDown( button.childId , button.outputX , button.outputY + 1 , buttonValue , action ) ;
this.dropDown( button.childId , button.outputX , button.outputY + 1 , buttonValue , action , button ) ;
} ;

@@ -201,3 +239,7 @@

DropDownMenu.prototype.onButtonFocus = function( focus , type , button ) {
if ( focus ) { this.dropDown( button.childId , button.outputX , button.outputY + 1 ) ; }
this.lastFocusButton = button ;
if ( focus && type !== 'clear' ) {
this.dropDown( button.childId , button.outputX , button.outputY + 1 ) ;
}
} ;

@@ -207,9 +249,22 @@

DropDownMenu.prototype.onColumnMenuSubmit = function( buttonValue , action , button ) {
button.once( 'blinked' , ( buttonValue_ , reserved , button_ ) => {
if ( this.clearColumnMenuOnSubmit ) { this.clearColumnMenu() ; }
this.emit( 'blinked' , buttonValue_ , reserved , this ) ;
} ) ;
DropDownMenu.prototype.onColumnMenuSubmit = function( buttonValue , action , columnMenu , button ) {
//console.error( "DropDownMenu#onColumnMenuSubmit()" , buttonValue , action , columnMenu?.elementType , button?.elementType ) ;
if ( button instanceof ToggleButton ) {
//console.error( ">>> is ToggleButton" ) ;
if ( button.key ) {
this.value[ button.key ] = button.value ;
}
this.emit( 'submit' , buttonValue , action , this ) ;
if ( this.clearColumnMenuOnSubmit ) {
setTimeout( () => this.clearColumnMenu( true ) , 400 ) ;
}
}
else {
columnMenu.once( 'blinked' , ( buttonValue_ , reserved , columnMenu_ , button_ ) => {
if ( this.clearColumnMenuOnSubmit ) { this.clearColumnMenu( true ) ; }
this.emit( 'blinked' , buttonValue_ , reserved , this , button_ ) ;
} ) ;
}
this.emit( 'submit' , buttonValue , action , this , button ) ;
} ;

@@ -219,26 +274,30 @@

DropDownMenu.prototype.onKey = function( key , trash , data ) {
switch( this.keyBindings[ key ] ) {
case 'previous' :
this.focusChild = this.focusPreviousChild() ;
//this.clearColumnMenu() ;
break ;
case 'next' :
this.focusChild = this.focusNextChild() ;
//this.clearColumnMenu() ;
break ;
case 'dropDown' :
if ( this.columnMenu ) { this.columnMenu.focusNextChild() ; }
//this.focusChild = this.focusNextChild() ;
//this.clearColumnMenu() ;
break ;
case 'clearColumnMenu' :
// Bubble up only if something was cleared
return this.clearColumnMenu() ;
default :
return ; // Bubble up
const userActions = DropDownMenu.prototype.userActions ;
userActions.previous = function() {
this.focusChild = this.focusPreviousChild() ;
//this.clearColumnMenu() ;
} ;
userActions.next = function() {
this.focusChild = this.focusNextChild() ;
//this.clearColumnMenu() ;
} ;
userActions.dropDown = function() {
if ( this.columnMenu ) {
this.columnMenu.focusNextChild() ;
}
else if ( this.lastFocusButton ) {
this.dropDown( this.lastFocusButton.childId , this.lastFocusButton.outputX , this.lastFocusButton.outputY + 1 ) ;
}
return true ; // Do not bubble up
//this.focusChild = this.focusNextChild() ;
//this.clearColumnMenu() ;
} ;
userActions.clearColumnMenu = function() {
// Bubble up only if something was cleared
return this.clearColumnMenu( true ) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,4 +31,7 @@ The MIT License (MIT)

const Element = require( './Element.js' ) ;
const TextBox = require( './TextBox.js' ) ;
const string = require( 'string-kit' ) ;
const Promise = require( 'seventh' ) ;

@@ -46,7 +49,11 @@

this.onKey = this.onKey.bind( this ) ;
this.onFocus = this.onFocus.bind( this ) ;
//this.onClick = this.onClick.bind( this ) ;
this.onDragEnd = this.onDragEnd.bind( this ) ;
this.onMiddleClick = this.onMiddleClick.bind( this ) ;
this.debounceTimeout = options.debounceTimeout ?? 100 ;
this.editionUpdateDebounced =
this.debounceTimeout ? Promise.debounceUpdate( { delay: this.debounceTimeout } , this.editionUpdate ) :
this.editionUpdate ;
if ( options.keyBindings ) { this.keyBindings = options.keyBindings ; }

@@ -59,7 +66,10 @@

this.on( 'key' , this.onKey ) ;
this.on( 'focus' , this.onFocus ) ;
//this.on( 'click' , this.onClick ) ;
this.on( 'dragEnd' , this.onDragEnd ) ;
this.on( 'middleClick' , this.onMiddleClick ) ;
if ( this.setContent === EditableTextBox.prototype.setContent ) {
this.setContent( options.content , options.contentHasMarkup , true ) ;
}
// Only draw if we are not a superclass of the object

@@ -70,7 +80,6 @@ if ( this.elementType === 'EditableTextBox' && ! options.noDraw ) { this.draw() ; }

module.exports = EditableTextBox ;
Element.inherit( EditableTextBox , TextBox ) ;
EditableTextBox.prototype = Object.create( TextBox.prototype ) ;
EditableTextBox.prototype.constructor = EditableTextBox ;
EditableTextBox.prototype.elementType = 'EditableTextBox' ;
EditableTextBox.prototype.needInput = true ;

@@ -80,16 +89,4 @@

EditableTextBox.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'focus' , this.onFocus ) ;
//this.off( 'click' , this.onClick ) ;
this.off( 'middleClick' , this.onMiddleClick ) ;
TextBox.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
EditableTextBox.prototype.keyBindings = {
CTRL_K: 'meta' ,
ENTER: 'newLine' ,

@@ -99,2 +96,3 @@ KP_ENTER: 'newLine' ,

DELETE: 'delete' ,
CTRL_DELETE: 'deleteLine' ,
LEFT: 'backward' ,

@@ -111,4 +109,24 @@ RIGHT: 'forward' ,

PAGE_DOWN: 'scrollDown' ,
CTRL_O: 'copyClipboard' ,
CTRL_P: 'pasteClipboard'
META_HOME: 'scrollToCursor' ,
CTRL_B: 'startOfSelection' ,
CTRL_E: 'endOfSelection' ,
SHIFT_LEFT: 'expandSelectionBackward' ,
SHIFT_RIGHT: 'expandSelectionForward' ,
SHIFT_UP: 'expandSelectionUp' ,
SHIFT_DOWN: 'expandSelectionDown' ,
CTRL_SHIFT_LEFT: 'expandSelectionStartOfWord' ,
CTRL_SHIFT_RIGHT: 'expandSelectionEndOfWord' ,
// T for Transfer
CTRL_T: 'moveSelection' ,
ALT_T: 'copyToDocumentClipboard' ,
META_T: 'copyToSystemClipboard' ,
// P for Paste / Put
CTRL_P: 'pasteSelection' ,
ALT_P: 'pasteDocumentClipboard' ,
META_P: 'pasteSystemClipboard' ,
// D for Delete
CTRL_D: 'deleteSelection' ,
ALT_D: 'clearDocumentClipboard' ,
META_D: 'clearSystemClipboard'
} ;

@@ -118,141 +136,114 @@

EditableTextBox.prototype.drawSelfCursor = function() {
this.textBuffer.drawCursor() ;
} ;
EditableTextBox.prototype.insert = function( str , selectIt = false , internal = false ) {
let x = this.textBuffer.cx ,
y = this.textBuffer.cy ;
let count = this.textBuffer.insert( str , this.textAttr ) ;
if ( ! internal ) {
if ( selectIt ) {
this.textBuffer.setSelectionRegion( {
xmin: x , ymin: y , xmax: this.textBuffer.cx , ymax: this.textBuffer.cy
} ) ;
}
EditableTextBox.prototype.getValue = TextBox.prototype.getContent ;
this.editionUpdateDebounced() ;
}
else if ( selectIt ) {
this.textBuffer.setSelectionRegion( {
xmin: x , ymin: y , xmax: this.textBuffer.cx , ymax: this.textBuffer.cy
} ) ;
}
this.emit( 'change' , {
type: 'insert' ,
insertedString: str ,
count ,
internal ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
} ;
EditableTextBox.prototype.setValue = function( value , dontDraw ) {
return TextBox.prototype.setContent.call( value , false , dontDraw ) ;
} ;
EditableTextBox.prototype.deleteSelection = function( internal = false ) {
if ( ! this.textBuffer.selectionRegion ) { return ; }
var { xmin , xmax , ymin , ymax } = this.textBuffer.selectionRegion ;
var deleted = this.textBuffer.deleteSelection( true ) ;
EditableTextBox.prototype.onKey = function( key , trash , data ) {
var dy ;
if ( deleted && deleted.count ) {
if ( ! internal ) {
this.textBuffer.cx = xmin ;
this.textBuffer.cy = ymin ;
if ( data && data.isCharacter ) {
this.textBuffer.insert( key , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
this.editionUpdateDebounced() ;
}
this.emit( 'change' , {
type: 'delete' ,
count: deleted.count ,
internal ,
deletedString: deleted.string ,
startPosition: { x: xmin , y: ymin } ,
endPosition: { x: xmin , y: ymin }
} ) ;
}
else {
// Here we have a special key
} ;
switch( this.keyBindings[ key ] ) {
case 'newLine' :
this.textBuffer.newLine() ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
break ;
case 'backDelete' :
this.textBuffer.backDelete() ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
break ;
case 'delete' :
this.textBuffer.delete() ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
break ;
EditableTextBox.prototype.deleteRegion = function( region , internal = false ) {
var { xmin , xmax , ymin , ymax } = region ;
var deleted = this.textBuffer.deleteRegion( region , true ) ;
case 'backward' :
this.textBuffer.moveBackward() ;
this.autoScrollAndDrawCursor() ;
break ;
if ( deleted && deleted.count ) {
if ( ! internal ) {
this.textBuffer.cx = xmin ;
this.textBuffer.cy = ymin ;
case 'forward' :
this.textBuffer.moveForward() ;
this.autoScrollAndDrawCursor() ;
break ;
this.editionUpdateDebounced() ;
}
case 'startOfWord' :
this.textBuffer.moveToStartOfWord() ;
this.autoScrollAndDrawCursor() ;
break ;
this.emit( 'change' , {
type: 'delete' ,
count: deleted.count ,
internal ,
deletedString: deleted.string ,
startPosition: { x: xmin , y: ymin } ,
endPosition: { x: xmin , y: ymin }
} ) ;
}
} ;
case 'endOfWord' :
this.textBuffer.moveToEndOfWord() ;
this.autoScrollAndDrawCursor() ;
break ;
case 'startOfLine' :
this.textBuffer.moveToColumn( 0 ) ;
this.autoScrollAndDrawCursor() ;
break ;
case 'endOfLine' :
this.textBuffer.moveToEndOfLine() ;
this.autoScrollAndDrawCursor() ;
break ;
EditableTextBox.prototype.drawSelfCursor = function() {
this.textBuffer.drawCursor() ;
} ;
case 'down' :
this.textBuffer.moveDown() ;
this.autoScrollAndDrawCursor() ;
break ;
case 'up' :
this.textBuffer.moveUp() ;
this.autoScrollAndDrawCursor() ;
break ;
case 'left' :
this.textBuffer.moveLeft() ;
this.autoScrollAndDrawCursor() ;
break ;
EditableTextBox.prototype.getValue = TextBox.prototype.getContent ;
case 'right' :
this.textBuffer.moveRight() ;
this.autoScrollAndDrawCursor() ;
break ;
case 'tab' :
this.textBuffer.insert( '\t' , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
break ;
case 'scrollUp' :
dy = Math.ceil( this.outputHeight / 2 ) ;
this.textBuffer.move( 0 , -dy ) ;
this.scroll( 0 , dy ) ;
break ;
EditableTextBox.prototype.setValue = function( value , dontDraw ) {
return this.setContent( value , false , dontDraw ) ;
} ;
case 'scrollDown' :
dy = -Math.ceil( this.outputHeight / 2 ) ;
this.textBuffer.move( 0 , -dy ) ;
this.scroll( 0 , dy ) ;
break ;
case 'pasteClipboard' :
if ( this.document ) {
this.document.getClipboard().then( str => {
if ( str ) {
this.textBuffer.insert( str , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
}
} )
.catch( () => undefined ) ;
}
break ;
case 'copyClipboard' :
if ( this.document ) {
this.document.setClipboard( this.textBuffer.getSelectionText() ).catch( () => undefined ) ;
}
break ;
default :
return ; // Bubble up
}
// Called when something was edited, usually requiring to run state machine, auto-scroll and draw.
// Usually, editionUpdateDebounced is called instead.
// Sync, but return a promise (needed for Promise.debounceUpdate())
EditableTextBox.prototype.editionUpdate = function() {
if ( this.stateMachine ) {
this.textBuffer.runStateMachine() ;
}
return true ; // Do not bubble up
this.autoScrollAndDraw() ;
return Promise.resolved ;
} ;

@@ -263,3 +254,2 @@

EditableTextBox.prototype.onFocus = function( focus , type ) {
this.hasFocus = focus ;
this.updateStatus() ;

@@ -272,7 +262,32 @@ this.draw() ;

EditableTextBox.prototype.onClick = function( data ) {
if ( ! this.hasFocus ) {
//console.error( "ETB Click:" , data ) ;
if ( this.hasFocus ) {
this.textBuffer.moveTo( data.x - this.scrollX , data.y - this.scrollY ) ;
if ( this.textBuffer.selectionRegion ) {
this.textBuffer.resetSelectionRegion() ;
this.draw() ;
}
else {
this.drawCursor() ;
}
}
else {
this.document.giveFocusTo( this , 'select' ) ;
}
else {
this.textBuffer.moveTo( data.x - this.scrollX , data.y - this.scrollY ) ;
} ;
EditableTextBox.prototype.onDragEnd = function( data ) {
if ( this.hasFocus ) {
if ( data.yFrom < data.y || ( data.yFrom === data.y && data.xFrom <= data.x ) ) {
// Forward selection, put the cursor one cell to the right
this.textBuffer.moveTo( data.x - this.scrollX + 1 , data.y - this.scrollY ) ;
}
else {
// Backward selection, put the cursor one the current cell
this.textBuffer.moveTo( data.x - this.scrollX , data.y - this.scrollY ) ;
}
this.drawCursor() ;

@@ -293,8 +308,4 @@ }

if ( this.document ) {
this.document.getClipboard( 'primary' ).then( str => {
if ( str ) {
this.textBuffer.insert( str , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
this.autoScrollAndDraw() ;
}
this.document.getSystemClipboard( 'primary' ).then( str => {
if ( str ) { this.insert( str ) ; }
//else { this.drawCursor() ; }

@@ -312,1 +323,477 @@ } )

const userActions = EditableTextBox.prototype.userActions ;
userActions.character = function( key ) {
var x = this.textBuffer.cx ,
y = this.textBuffer.cy ;
var count = this.textBuffer.insert( key , this.textAttr ) ;
this.editionUpdateDebounced() ;
this.emit( 'change' , {
type: 'insert' ,
insertedString: key ,
count ,
internal: false ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
} ;
userActions.newLine = function() {
var insertedString = '\n' ,
count = 1 ,
x = this.textBuffer.cx ,
y = this.textBuffer.cy ;
this.textBuffer.newLine() ;
this.editionUpdateDebounced() ;
this.emit( 'change' , {
type: 'insert' ,
insertedString ,
count ,
internal: false ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
} ;
userActions.tab = function() {
var x = this.textBuffer.cx ,
y = this.textBuffer.cy ;
this.textBuffer.insert( '\t' , this.textAttr ) ;
this.editionUpdateDebounced() ;
this.emit( 'change' , {
type: 'insert' ,
insertedString: '\t' ,
count: 1 ,
internal: false ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
} ;
userActions.delete = function() {
var x = this.textBuffer.cx ,
y = this.textBuffer.cy ,
selectionRegion = this.textBuffer.selectionRegion ;
if ( selectionRegion && selectionRegion.ymin === y && selectionRegion.xmin === x ) {
// Instead, delete the whole selection
this.deleteSelection() ;
return ;
}
var deleted = this.textBuffer.delete( 1 , true ) ;
this.editionUpdateDebounced() ;
if ( deleted && deleted.count ) {
this.emit( 'change' , {
type: 'delete' ,
count: deleted.count ,
internal: false ,
deletedString: deleted.string ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
}
} ;
userActions.backDelete = function() {
var x = this.textBuffer.cx ,
y = this.textBuffer.cy ,
selectionRegion = this.textBuffer.selectionRegion ;
if ( selectionRegion ) {
let coord = this.textBuffer.oneStepBackward() ;
if ( selectionRegion.ymax === coord.y && selectionRegion.xmax === coord.x ) {
// Instead, delete the whole selection
this.deleteSelection() ;
return ;
}
}
var deleted = this.textBuffer.backDelete( 1 , true ) ;
this.editionUpdateDebounced() ;
if ( deleted && deleted.count ) {
this.emit( 'change' , {
type: 'backDelete' ,
count: deleted.count ,
internal: false ,
deletedString: deleted.string ,
startPosition: { x , y } ,
endPosition: { x: this.textBuffer.cx , y: this.textBuffer.cy }
} ) ;
}
} ;
userActions.deleteLine = function() {
var y = this.textBuffer.cy ;
var deleted = this.textBuffer.deleteLine( true ) ;
this.editionUpdateDebounced() ;
if ( deleted && deleted.count ) {
this.emit( 'change' , {
type: 'delete' ,
count: deleted.count ,
internal: false ,
deletedString: deleted.string ,
startPosition: { x: 0 , y } ,
endPosition: { x: 0 , y: this.textBuffer.cy }
} ) ;
}
} ;
userActions.backward = function() {
this.textBuffer.moveBackward() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.forward = function() {
this.textBuffer.moveForward() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.startOfWord = function() {
this.textBuffer.moveToStartOfWord() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.endOfWord = function() {
this.textBuffer.moveToEndOfWord() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.startOfLine = function() {
this.textBuffer.moveToColumn( 0 ) ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
// Start of line, but if already at cx = 0, move to the first non-white char (skip indent),
// Also known as “smart home”.
userActions.smartStartOfLine = function() {
if ( this.textBuffer.cx !== 0 ) {
this.textBuffer.moveToColumn( 0 ) ;
}
else {
let cy = this.textBuffer.cy ;
this.textBuffer.moveForward( ( char , x , y ) => y !== cy || ( char !== ' ' && char !== '\t' ) ) ;
if ( this.textBuffer.cy !== cy ) {
// Line has changed, it was an empty line: fallback!
this.textBuffer.moveTo( 0 , cy ) ;
}
}
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.endOfLine = function() {
this.textBuffer.moveToEndOfLine() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.down = function() {
this.textBuffer.moveDown() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.up = function() {
this.textBuffer.moveUp() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.left = function() {
this.textBuffer.moveLeft() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.right = function() {
this.textBuffer.moveRight() ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.scrollUp = function() {
var dy = Math.ceil( this.outputHeight / 2 ) ;
this.textBuffer.move( 0 , -dy ) ;
this.scroll( 0 , dy , true ) ; this.autoScrollAndDraw() ;
//this.scroll( 0 , dy ) ; this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.scrollDown = function() {
var dy = -Math.ceil( this.outputHeight / 2 ) ;
this.textBuffer.move( 0 , -dy ) ;
this.scroll( 0 , dy , true ) ; this.autoScrollAndDraw() ;
//this.scroll( 0 , dy ) ; this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.scrollTop = function() {
this.textBuffer.moveTo( 0 , 0 ) ;
this.scrollTo( 0 , 0 ) ;
this.emit( 'cursorMove' ) ;
} ;
userActions.scrollBottom = function() {
this.textBuffer.moveTo( 0 , this.textBuffer.buffer.length - 1 ) ;
this.autoScrollAndSmartDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.scrollToCursor = function() {
this.autoScrollAndDraw() ;
} ;
userActions.expandSelectionBackward = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmin === cx && selection.ymin === cy ) {
// Can expand
this.textBuffer.moveBackward() ;
this.textBuffer.startOfSelection() ;
}
else if ( selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y ) {
// Can contract
this.textBuffer.moveBackward() ;
this.textBuffer.endOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.endOfSelection() ;
this.textBuffer.moveBackward() ;
this.textBuffer.startOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.expandSelectionStartOfWord = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmin === cx && selection.ymin === cy ) {
// Can expand
this.textBuffer.moveToStartOfWord() ;
this.textBuffer.startOfSelection() ;
}
else if ( selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y ) {
// Can contract
this.textBuffer.moveToStartOfWord() ;
this.textBuffer.endOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.endOfSelection() ;
this.textBuffer.moveToStartOfWord() ;
this.textBuffer.startOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.expandSelectionUp = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmin === cx && selection.ymin === cy ) {
// Can expand
this.textBuffer.moveUp() ;
this.textBuffer.startOfSelection() ;
}
else if (
selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y
// Check that there is at least one line of selection
&& ( selection.ymin < oneStepBackward.y - 1 || ( selection.ymin === oneStepBackward.y - 1 && selection.xmin <= oneStepBackward.x ) )
) {
// Can contract
this.textBuffer.moveUp() ;
this.textBuffer.endOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.endOfSelection() ;
this.textBuffer.moveUp() ;
this.textBuffer.startOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.expandSelectionForward = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y ) {
// Can expand
this.textBuffer.moveForward() ;
this.textBuffer.endOfSelection() ;
}
else if ( selection && selection.xmin === cx && selection.ymin === cy ) {
// Can contract
this.textBuffer.moveForward() ;
this.textBuffer.startOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.startOfSelection() ;
this.textBuffer.moveForward() ;
this.textBuffer.endOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.expandSelectionEndOfWord = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y ) {
// Can expand
this.textBuffer.moveToEndOfWord() ;
this.textBuffer.endOfSelection() ;
}
else if ( selection && selection.xmin === cx && selection.ymin === cy ) {
// Can contract
this.textBuffer.moveToEndOfWord() ;
this.textBuffer.startOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.startOfSelection() ;
this.textBuffer.moveToEndOfWord() ;
this.textBuffer.endOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.expandSelectionDown = function() {
var selection = this.textBuffer.selectionRegion ,
cx = this.textBuffer.cx ,
cy = this.textBuffer.cy ,
oneStepBackward = this.textBuffer.oneStepBackward() ;
if ( selection && selection.xmax === oneStepBackward.x && selection.ymax === oneStepBackward.y ) {
// Can expand
this.textBuffer.moveDown() ;
this.textBuffer.endOfSelection() ;
}
else if ( selection && selection.xmin === cx && selection.ymin === cy
&& ( selection.ymax > cy + 1 || ( selection.ymax === cy + 1 && selection.xmax >= cx - 1 ) )
) {
// Can contract
this.textBuffer.moveDown() ;
this.textBuffer.startOfSelection() ;
}
else {
// Start a new selection
this.textBuffer.startOfSelection() ;
this.textBuffer.moveDown() ;
this.textBuffer.endOfSelection() ;
}
this.autoScrollAndDraw() ;
this.emit( 'cursorMove' ) ;
} ;
userActions.startOfSelection = function() {
this.textBuffer.startOfSelection() ;
this.draw() ;
} ;
userActions.endOfSelection = function() {
this.textBuffer.endOfSelection() ;
this.draw() ;
} ;
userActions.moveSelection = function() {
var str = this.textBuffer.getSelectionText() ;
if ( ! str ) { return ; }
this.deleteSelection( true ) ;
this.insert( str , true ) ;
} ;
userActions.pasteSelection = function() {
var str = this.textBuffer.getSelectionText() ;
if ( str ) { this.insert( str ) ; }
} ;
userActions.pasteDocumentClipboard = function() {
if ( this.document ) {
let str = this.document.getDocumentClipboard() ;
if ( str && typeof str === 'string' ) {
this.insert( str ) ;
}
}
} ;
userActions.pasteSystemClipboard = function() {
if ( this.document ) {
this.document.getSystemClipboard()
.then( str => {
if ( str && typeof str === 'string' ) {
this.insert( str ) ;
}
} )
.catch( () => undefined ) ;
}
} ;
userActions.deleteSelection = function() {
this.deleteSelection() ;
} ;
userActions.clearDocumentClipboard = function() {
if ( this.document ) {
this.document.clearDocumentClipboard( this.textBuffer.getSelectionText() ) ;
}
} ;
userActions.clearSystemClipboard = function() {
if ( this.document ) {
this.document.clearSystemClipboard( this.textBuffer.getSelectionText() ).catch( () => undefined ) ;
}
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -35,10 +35,22 @@ The MIT License (MIT)

// Avoid requiring Document at top-level, it could cause circular require troubles
//const Document = require( './Document.js' ) ;
var autoId = 0 ;
function Element( options = {} ) {
this.setInterruptible( true ) ;
this.uid = autoId ++ ; // Useful for debugging
this.parent = options.parent && options.parent.elementType ? options.parent : null ;
//console.error( "Creating " + this.elementType + " #" + this.uid + ( this.parent ? " (from parent " + this.parent.elementType + " #" + this.parent.uid + ")" : '' ) ) ;
this.document = null ;
this.destroyed = false ;
// Event handler bindings
this.onKey = this.onKey.bind( this ) ;
this.inlineTerm = options.inlineTerm || null ; // inline mode, with this terminal as output

@@ -66,5 +78,6 @@ this.strictInline = !! (

this.content = '' ;
this.contentHasMarkup = false ;
this.contentWidth = 0 ;
// Default value (ensure it's not already set)
this.content = this.content ?? '' ;
this.contentHasMarkup = this.contentHasMarkup ?? false ;
this.contentWidth = this.contentWidth ?? 0 ;

@@ -97,3 +110,3 @@ if ( this.setContent === Element.prototype.setContent ) {

// Used by .updateDraw()
this.needRedraw = false ;
this.needOuterDraw = false ;

@@ -106,3 +119,2 @@ this.savedCursorX = 0 ;

this.zChildren = [] ; // like children, but ordered by zIndex
//this.onKey = this.onKey.bind( this ) , writable: true } ,

@@ -130,7 +142,10 @@ // Children needs an inputDst, by default, everything is the same as for output (except for Container)

const termkit = require( '../termkit.js' ) ;
// Destroy the element and all its children, detaching them and removing listeners
Element.prototype.destroy = function( isSubDestroy = false , noDraw = false ) {
if ( this.destroyed ) { return ; }
//console.error( "Destroying" , this.elementType , this.uid , this.key ) ;

@@ -144,2 +159,3 @@ var i , iMax , document = this.document ;

this.removeAllListeners() ;
this.children.length = 0 ;

@@ -165,6 +181,22 @@ this.zChildren.length = 0 ;

Element.inherit = function( Class , FromClass = Element ) {
Class.prototype = Object.create( FromClass.prototype ) ;
Class.prototype.constructor = Class ;
Class.prototype.elementType = Class.name ;
Class.prototype.userActions = Object.create( FromClass.prototype.userActions ) ;
Class.prototype.userActions.__parent = FromClass.prototype.userActions ;
} ;
// Debug function
Element.prototype.debugId = function() { return this.elementType + '#' + this.uid ; } ;
Element.prototype.show = function( noDraw = false ) {
if ( ! this.hidden ) { return this ; }
this.hidden = false ;
if ( ! noDraw ) { this.redraw() ; }
if ( ! noDraw ) { this.outerDraw() ; }
return this ;

@@ -180,4 +212,4 @@ } ;

if ( ! noDraw ) {
// .redraw() with the 'force' option on, because .redraw() does nothing if the element is hidden, but here we want to clear it from its parent
this.redraw( true ) ;
// .outerDraw() with the 'force' option on, because .outerDraw() does nothing if the element is hidden, but here we want to clear it from its parent
this.outerDraw( true ) ;
}

@@ -256,3 +288,2 @@

for ( i = 0 , iMax = this.children.length ; i < iMax ; i ++ ) {
//console.error( ">>>" , i , iMax ) ;
this.children[ i ].recursiveFixAttachment( document ) ;

@@ -293,2 +324,10 @@ }

// Resize the element to its content
Element.prototype.resizeToContent = function() {
this.outputWidth = this.contentWidth ;
this.outputHeight = this.contentHeight ;
} ;
// Sort zChildren, only necessary when a child zIndex changed

@@ -364,3 +403,3 @@ Element.prototype.zSort = function() {

return (
hasMarkup === 'ansi' ? Math.max( ... content.map( line => misc.ansiWidth( line ) ) ) :
hasMarkup === 'ansi' || hasMarkup === 'legacyAnsi' ? Math.max( ... content.map( line => misc.ansiWidth( line ) ) ) :
hasMarkup ? Math.max( ... content.map( line => misc.markupWidth( line ) ) ) :

@@ -372,3 +411,3 @@ Math.max( ... content.map( line => string.unicode.width( line ) ) )

return (
hasMarkup === 'ansi' ? misc.ansiWidth( content ) :
hasMarkup === 'ansi' || hasMarkup === 'legacyAnsi' ? misc.ansiWidth( content ) :
hasMarkup ? misc.markupWidth( content ) :

@@ -385,3 +424,3 @@ string.unicode.width( content )

if ( hasMarkup === 'ansi' ) {
if ( hasMarkup === 'ansi' || hasMarkup === 'legacyAnsi' ) {
str = misc.truncateAnsiString( content , maxWidth ) ;

@@ -404,3 +443,3 @@ lastTruncateWidth = misc.getLastTruncateWidth() ;

Element.wordWrapContent = ( content , width , hasMarkup ) =>
hasMarkup === 'ansi' ? misc.wordWrapAnsi( content , width ) :
hasMarkup === 'ansi' || hasMarkup === 'legacyAnsi' ? misc.wordWrapAnsi( content , width ) :
hasMarkup ? misc.wordWrapMarkup( content , width ) :

@@ -416,6 +455,17 @@ string.wordwrap( content , { width , fill: true , noJoin: true } ) ;

this.contentHasMarkup = hasMarkup ;
var oldContentWidth = this.contentWidth ;
this.contentWidth = Element.computeContentWidth( content , this.contentHasMarkup ) ;
if ( ! dontResize && this.resizeOnContent ) { this.resizeOnContent() ; }
if ( ! dontDraw ) { this.redraw() ; }
if ( ! dontDraw ) {
// This condition is bad, and is only relevant for Text ATM,
// Should find a clean way to split outputWidth/outputHeight from a sort of wantedWidth/wantedHeight
if ( this.contentWidth !== oldContentWidth && ( this.contentWidth > this.outputWidth || this.resizeOnContent ) ) {
this.outerDraw() ;
}
else {
this.draw() ;
}
}
} ;

@@ -500,3 +550,3 @@

Element.prototype.focusNextChild = function( loop = true ) {
Element.prototype.focusNextChild = function( loop = true , type = 'cycle' ) {
var index , startingIndex , focusAware ;

@@ -520,3 +570,3 @@

focusAware = this.document.giveFocusTo_( this.children[ index ] , 'cycle' ) ;
focusAware = this.document.giveFocusTo_( this.children[ index ] , type ) ;

@@ -636,2 +686,3 @@ // Exit if the focus was given to a focus-aware element or if we have done a full loop already

Element.prototype.draw = function( isInitialInlineDraw = false ) {
//console.error( "\n----------------------------\nCalling .draw() for" , this.debugId() , new Error( 'trace:' ) ) ;
if ( ! this.document || this.hidden ) { return this ; }

@@ -659,6 +710,6 @@

// If it has, then it is necessary to draw the closest ancestor which is a container.
// /!\ THIS METHOD IS WRONG: it should draw the parent container, but don't redraw any children of its children Container
// /!\ Maybe rename this .outerDraw() or .parentDraw()
// /!\ IS THIS METHOD WRONG? it should draw the parent container, but don't redraw any children of its children Container
// Option 'force' redraw even if the element is hidden, in fact it is used by the .hide() method to effectively hide the element on the parent container.
Element.prototype.redraw = function( force = false ) {
Element.prototype.redraw = // DEPRECATED name, use .outerDraw()
Element.prototype.outerDraw = function( force = false ) {
if ( ! this.document || ( this.hidden && ! force ) ) { return this ; }

@@ -668,3 +719,2 @@

//console.error( "parentContainer:" , container ) ;
if ( ! container ) { this.draw() ; }

@@ -678,7 +728,7 @@ else { container.draw() ; }

// Hard to find a good name, .draw() or .redraw() depending on what have been updated
// Hard to find a good name, .draw() or .outerDraw() depending on what have been updated
Element.prototype.updateDraw = function() {
if ( this.needRedraw ) { this.redraw() ; }
if ( this.needOuterDraw ) { this.outerDraw() ; }
else { this.draw() ; }
this.needRedraw = false ;
this.needOuterDraw = false ;
} ;

@@ -695,3 +745,2 @@

if ( this.preDrawSelf ) {
//console.error( 'preDrawSelf: ' , this.elementType , this.id ) ;
this.preDrawSelf( ! isSubcall ) ;

@@ -706,3 +755,2 @@ }

if ( isSubcall && this.postDrawSelf ) {
//console.error( 'postDrawSelf: ' , this.elementType , this.id ) ;
this.postDrawSelf( ! isSubcall ) ;

@@ -718,7 +766,5 @@ }

Element.prototype.ascendantDraw = function() {
//console.error( '\nascendantDraw: ' , this.elementType , this.id ) ;
var currentElement ;
if ( this.postDrawSelf && ! this.hidden ) {
//console.error( 'postDrawSelf: ' , this.elementType , this.id ) ;
this.postDrawSelf( true ) ;

@@ -733,3 +779,2 @@ }

if ( currentElement.outputDst !== currentElement.inputDst && currentElement.postDrawSelf && ! currentElement.hidden ) {
//console.error( 'postDrawSelf: ' , currentElement.elementType , currentElement.id ) ;
currentElement.postDrawSelf( false ) ;

@@ -767,2 +812,23 @@ }

// TODOC
Element.prototype.bindKey = function( key , action ) { this.keyBindings[ key ] = action ; } ;
// TODOC
Element.prototype.getKeyBinding = function( key ) { return this.keyBindings[ key ] ?? null ; } ;
// TODOC
Element.prototype.getKeyBindings = function( key ) { return Object.assign( {} , this.keyBindings ) ; } ;
// TODOC
Element.prototype.getActionBinding = function( action , ui = false ) {
var keys = [] ;
for ( let key in this.keyBindings ) {
if ( this.keyBindings[ key ] === action ) {
keys.push( ui ? misc.keyToUserInterfaceName( key ) : key ) ;
}
}
return keys ;
} ;
// For inline widget, having eventually a document just for him, that fit its own size

@@ -813,6 +879,2 @@ Element.createInline = async function( term , Type , options ) {

let scrollY = position.y + element.outputHeight - term.height ;
//console.error( "INLINE -- element.outputWidth" , element.outputWidth ) ;
//console.error( "INLINE -- element.outputHeight" , element.outputHeight ) ;
//console.error( "INLINE -- element.outputY" , element.outputY ) ;
//console.error( "INLINE -- scrollY" , scrollY ) ;

@@ -826,2 +888,6 @@ if ( scrollY > 0 ) {

if ( element.inlineResizeToContent ) {
element.resizeToContent() ;
}
var documentOptions = {

@@ -841,3 +907,3 @@ internal: true ,

var document = new Document( documentOptions ) ;
var document = new termkit.Document( documentOptions ) ;

@@ -859,2 +925,36 @@ document.attach( element ) ;

// Default 'key' event management, suitable for almost all use-case, but could be derivated if needed
Element.prototype.onKey = function( key , trash , data ) {
var action = this.keyBindings[ key ] ;
//console.error( this.debugId() , "Key:" , key , "Actions:" , action , !! this.userActions?.[ action ] ) ; // action && this.userActions[ action ] ? "fn: " + this.userActions[ action ].toString() : '' ) ;
if ( action ) {
if ( action === 'meta' ) {
if ( this.document ) {
this.document.setMetaKeyPrefix( 'META' , 'CTRL' ) ;
}
return true ; // Do not bubble up
}
else if ( this.userActions[ action ] ) {
// Do not bubble up except if explicitly false
return ( this.userActions[ action ].call( this , key , trash , data ) ?? true ) || undefined ;
}
}
else if ( data && data.isCharacter ) {
if ( this.userActions.character ) {
// Do not bubble up except if explicitly false
return ( this.userActions.character.call( this , key , trash , data ) ?? true ) || undefined ;
}
}
else if ( this.userActions.specialKey ) {
// Do not bubble up except if explicitly false
return ( this.userActions.specialKey.call( this , key , trash , data ) ?? true ) || undefined ;
}
// Nothing found, bubble up
return ;
} ;
// Should be redefined

@@ -875,4 +975,6 @@ Element.prototype.isContainer = false ; // boolean, true if it's a container, having a different inputDst and outputDst and local coords

Element.prototype.needInput = false ; // no need for input by default (used to configure inline mode)
Element.prototype.outerDrag = false ; // boolean, true if drag event are sent when out of bounds (e.g. useful for moving windows)
const Document = require( './Document.js' ) ;
Element.prototype.keyBindings = {} ; // object, store key bindings, the key is a Terminal Kit key code, the value is an user-action name
Element.prototype.userActions = {} ; // object, the key is an user-action name, the value is a function... THIS IS INHERITED
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -54,3 +54,2 @@ The MIT License (MIT)

this.onButtonSubmit = this.onButtonSubmit.bind( this ) ;
this.onKey = this.onKey.bind( this ) ;
this.onFocus = this.onFocus.bind( this ) ;

@@ -83,7 +82,6 @@

module.exports = Form ;
Element.inherit( Form ) ;
Form.prototype = Object.create( Element.prototype ) ;
Form.prototype.constructor = Form ;
Form.prototype.elementType = 'Form' ;
Form.prototype.needInput = true ;

@@ -93,13 +91,2 @@

Form.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'focus' , this.onFocus ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
Form.prototype.keyBindings = {

@@ -291,19 +278,2 @@ LEFT: 'previous' ,

Form.prototype.onKey = function( key , altKeys , data ) {
switch( this.keyBindings[ key ] ) {
case 'previous' :
this.focusChild = this.focusPreviousChild() ;
break ;
case 'next' :
this.focusChild = this.focusNextChild() ;
break ;
default :
return ; // Bubble up
}
return true ; // Do not bubble up
} ;
Form.prototype.onFocus = function( focus , type ) {

@@ -323,6 +293,18 @@ if ( type === 'cycle' || type === 'backCycle' ) { return ; }

Form.prototype.onButtonSubmit = function( buttonValue , action ) {
Form.prototype.onButtonSubmit = function( buttonValue , action , button ) {
this.submitValue = buttonValue ;
this.emit( 'submit' , this.getValue() , action , this ) ;
this.emit( 'submit' , this.getValue() , action , this , button ) ;
} ;
const userActions = Form.prototype.userActions ;
userActions.previous = function() {
this.focusChild = this.focusPreviousChild() ;
} ;
userActions.next = function() {
this.focusChild = this.focusNextChild() ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,6 +31,8 @@ The MIT License (MIT)

const Promise = require( 'seventh' ) ;
const Element = require( './Element.js' ) ;
const TextBox = require( './TextBox.js' ) ;
const EditableTextBox = require( './EditableTextBox.js' ) ;
const RowMenu = require( './RowMenu.js' ) ;
const Promise = require( 'seventh' ) ;
const string = require( 'string-kit' ) ;

@@ -51,3 +53,2 @@ const computeAutoCompleteArray = require( '../autoComplete.js' ) ;

* editing actions: deleteAllBefore, deleteAllAfter, deletePreviousWord, deleteNextWord
* meta key for more keyboard commands, e.g.: maybe something like CTRL_K <key> --> META_<key>
* allow placeholder to be used as default (submitting without actually entering anything) when appropriate

@@ -78,2 +79,3 @@ * disable echoing (no output and no cursor movements)

this.onAutoCompleteMenuSubmit = this.onAutoCompleteMenuSubmit.bind( this ) ;
this.onAutoCompleteMenuItemFocus = this.onAutoCompleteMenuItemFocus.bind( this ) ;
this.onAutoCompleteMenuCancel = this.onAutoCompleteMenuCancel.bind( this ) ;

@@ -123,2 +125,4 @@

this.noEmpty = !! options.noEmpty ; // if set, do not submit empty string
this.disabled = !! options.disabled ;

@@ -131,2 +135,3 @@ this.submitted = !! options.submitted ;

this.useAutoCompleteHint = !! ( this.autoComplete && ( options.useAutoCompleteHint || options.autoCompleteHint ) ) ;
this.autoCompleteHintMinInput = options.autoCompleteHintMinInput || 1 ; // number of input chars before starting to hint
this.useAutoCompleteMenu = !! ( this.autoComplete && ( options.useAutoCompleteMenu || options.autoCompleteMenu ) ) ;

@@ -136,2 +141,5 @@ this.autoCompleteMenu = null ;

this.autoCompleteRightPart = null ;
this.autoCompleteCursorCell = null ;
this.autoCompleteMenuPrefix = null ;
this.autoCompleteMenuPostfix = null ;

@@ -156,7 +164,6 @@ this.menuOptions = Object.assign( {} , this.defaultMenuOptions , options.menu ) ;

module.exports = InlineInput ;
Element.inherit( InlineInput , EditableTextBox ) ;
InlineInput.prototype = Object.create( EditableTextBox.prototype ) ;
InlineInput.prototype.constructor = InlineInput ;
InlineInput.prototype.elementType = 'InlineInput' ;
// Has a fallback textBuffer for hint/placeholder

@@ -185,2 +192,3 @@ InlineInput.prototype.useAltTextBuffer = true ;

InlineInput.prototype.keyBindings = {
CTRL_K: 'meta' ,
ENTER: 'submit' ,

@@ -201,4 +209,17 @@ KP_ENTER: 'submit' ,

END: 'endOfLine' ,
CTRL_O: 'copyClipboard' ,
CTRL_P: 'pasteClipboard'
CTRL_B: 'startOfSelection' ,
CTRL_E: 'endOfSelection' ,
// T for Transfer
//CTRL_T: 'moveSelection' , // TODO
ALT_T: 'copyToDocumentClipboard' ,
META_T: 'copyToSystemClipboard' ,
// P for Paste / Put
CTRL_P: 'pasteSelection' ,
ALT_P: 'pasteDocumentClipboard' ,
META_P: 'pasteSystemClipboard' ,
// D for Delete
//CTRL_D: 'deleteSelection' , // TODO
ALT_D: 'clearDocumentClipboard' ,
META_D: 'clearSystemClipboard'
} ;

@@ -208,2 +229,11 @@

InlineInput.prototype.insert = function( str ) {
this.textBuffer.insert( str , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; } // async
else { this.autoResizeAndDraw() ; }
} ;
InlineInput.prototype.preDrawSelf = function() {

@@ -247,3 +277,9 @@ /*

InlineInput.prototype.runAutoCompleteHint = async function( autoComplete ) {
//console.error( "bob, please")
if ( this.textBuffer.cy === 0 && this.textBuffer.cx < this.autoCompleteHintMinInput ) {
// Not enough input for starting to hint
this.altTextBuffer.setText( '' ) ;
this.autoResizeAndDraw() ;
return ;
}
var autoCompleted ;

@@ -255,27 +291,35 @@

this.altTextBuffer.setText( '' ) ;
this.autoResizeAndDraw() ;
return ;
}
if ( Array.isArray( autoComplete ) ) {
autoCompleted = computeAutoCompleteArray( autoComplete , leftPart , false ) ;
}
else if ( typeof autoComplete === 'function' ) {
autoCompleted = await autoComplete( leftPart , false ) ;
}
else {
if ( Array.isArray( autoComplete ) ) {
autoCompleted = computeAutoCompleteArray( autoComplete , leftPart , false ) ;
}
else if ( typeof autoComplete === 'function' ) {
autoCompleted = await autoComplete( leftPart , false ) ;
}
else {
this.altTextBuffer.setText( '' ) ;
this.autoResizeAndDraw() ;
return ;
}
if ( Array.isArray( autoCompleted ) ) {
if ( ! autoCompleted.length || autoCompleted.length > 1 ) {
this.altTextBuffer.setText( '' ) ;
this.autoResizeAndDraw() ;
return ;
}
if ( Array.isArray( autoCompleted ) ) {
if ( ! autoCompleted.length ) { return ; }
autoCompleted = autoCompleted[ 0 ] ;
}
autoCompleted = ( autoCompleted.prefix ?? '' ) + autoCompleted[ 0 ] + ( autoCompleted.postfix ?? '' ) ;
}
if ( autoCompleted === leftPart ) {
this.altTextBuffer.setText( '' ) ;
}
else {
this.altTextBuffer.setText( autoCompleted ) ;
//this.altTextBuffer.runStateMachine() ;
}
if ( autoCompleted === leftPart ) {
this.altTextBuffer.setText( '' ) ;
}
else {
this.altTextBuffer.setText( autoCompleted ) ;
//this.altTextBuffer.runStateMachine() ;
}

@@ -290,2 +334,3 @@ this.autoResizeAndDraw() ;

this.autoCompleteCursorCell = this.textBuffer.getCursorCell() ;
[ this.autoCompleteLeftPart , this.autoCompleteRightPart ] = this.textBuffer.getCursorSplittedText() ;

@@ -311,3 +356,3 @@

autoCompleted = autoCompleted[ 0 ] ;
autoCompleted = ( autoCompleted.prefix ?? '' ) + autoCompleted[ 0 ] + ( autoCompleted.postfix ?? '' ) ;
}

@@ -321,4 +366,13 @@

InlineInput.prototype.runAutoCompleted = async function( autoCompleted ) {
this.textBuffer.setText( autoCompleted + this.autoCompleteRightPart ) ;
this.textBuffer.setCursorOffset( autoCompleted.length ) ;
if ( autoCompleted.startsWith( this.autoCompleteLeftPart ) ) {
this.textBuffer.insert( autoCompleted.slice( this.autoCompleteLeftPart.length ) ) ;
if ( ! this.textBuffer.updateCursorFromCell( this.autoCompleteCursorCell ) ) {
this.textBuffer.moveToEndOfBuffer() ;
}
}
else {
this.textBuffer.setText( autoCompleted + this.autoCompleteRightPart ) ;
this.textBuffer.moveToEndOfBuffer() ;
}
this.textBuffer.runStateMachine() ;

@@ -349,2 +403,5 @@ this.autoResizeAndDraw() ;

this.autoCompleteMenuPrefix = items.prefix ?? '' ;
this.autoCompleteMenuPostfix = items.postfix ?? '' ;
this.document.giveFocusTo( this.autoCompleteMenu ) ;

@@ -354,2 +411,3 @@

this.autoCompleteMenu.once( 'cancel' , this.onAutoCompleteMenuCancel ) ;
this.autoCompleteMenu.on( 'itemFocus' , this.onAutoCompleteMenuItemFocus ) ;
} ;

@@ -360,4 +418,9 @@

InlineInput.prototype.onAutoCompleteMenuSubmit = function( selectedText ) {
selectedText = this.autoCompleteMenuPrefix + selectedText + this.autoCompleteMenuPostfix ;
this.autoCompleteMenu.destroy() ;
this.autoCompleteMenu = null ;
this.autoCompleteMenuPrefix = null ;
this.autoCompleteMenuPostfix = null ;
this.document.giveFocusTo( this ) ;

@@ -369,205 +432,116 @@ this.runAutoCompleted( selectedText ) ;

InlineInput.prototype.onAutoCompleteMenuCancel = function() {
this.autoCompleteMenu.destroy() ;
this.autoCompleteMenu = null ;
this.document.giveFocusTo( this ) ;
} ;
InlineInput.prototype.onAutoCompleteMenuItemFocus = function( selectedText , focus ) {
if ( ! focus || this.autoCompleteRightPart ) { return ; }
selectedText = this.autoCompleteMenuPrefix + selectedText + this.autoCompleteMenuPostfix ;
InlineInput.prototype.onKey = function( key , trash , data ) {
if ( this.autoCompleteMenu ) {
// If the autoCompleteMenu is on, force a cancel
this.autoCompleteMenu.emit( 'cancel' ) ;
if ( selectedText === this.autoCompleteLeftPart ) {
this.altTextBuffer.setText( '' ) ;
}
if ( data && data.isCharacter ) {
if ( this.placeholder ) {
// Remove the placeholder on the first input
this.placeholder = null ;
this.setAltContent( '' , false , true ) ;
}
this.textBuffer.insert( key , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; }
else { this.autoResizeAndDraw() ; }
else {
this.altTextBuffer.setText( selectedText ) ;
//this.altTextBuffer.runStateMachine() ;
}
else {
// Here we have a special key
switch( this.keyBindings[ key ] ) {
case 'submit' :
if ( this.disabled || this.submitted || this.canceled ) { break ; }
//this.submitted = true ;
this.emit( 'submit' , this.getValue() , undefined , this ) ;
break ;
this.autoResizeAndDraw() ;
} ;
case 'cancel' :
if ( ! this.cancelable || this.disabled || this.canceled ) { break ; }
//this.canceled = true ;
this.emit( 'cancel' , this ) ;
break ;
case 'autoComplete' :
if ( ! this.autoComplete ) { break ; }
this.runAutoComplete( this.autoComplete ) ;
break ;
case 'historyAutoComplete' :
if ( ! this.autoComplete ) { break ; }
this.runAutoComplete( this.history ) ;
break ;
InlineInput.prototype.onAutoCompleteMenuCancel = function() {
this.autoCompleteMenu.destroy() ;
this.autoCompleteMenu = null ;
this.document.giveFocusTo( this ) ;
} ;
case 'historyPrevious' :
if ( this.contentIndex <= 0 ) { break ; }
this.contentArray[ this.contentIndex ] = this.getContent() ;
this.contentIndex -- ;
this.setContent( this.contentArray[ this.contentIndex ] ) ;
this.textBuffer.runStateMachine() ;
this.autoResizeAndDraw() ;
break ;
case 'historyNext' :
if ( this.contentIndex >= this.contentArray.length - 1 ) { break ; }
this.contentArray[ this.contentIndex ] = this.getContent() ;
this.contentIndex ++ ;
this.setContent( this.contentArray[ this.contentIndex ] ) ;
this.textBuffer.runStateMachine() ;
this.autoResizeAndDraw() ;
break ;
case 'backDelete' :
this.textBuffer.backDelete() ;
this.textBuffer.runStateMachine() ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; }
else { this.autoResizeAndDraw() ; }
break ;
// Can be derived (e.g. by InlineFileInput)
InlineInput.prototype.submit = function() {
if ( this.disabled || this.submitted || this.canceled ) { return ; }
case 'delete' :
this.textBuffer.delete() ;
this.textBuffer.runStateMachine() ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; }
else { this.autoResizeAndDraw() ; }
break ;
var value = this.getValue() ;
if ( this.noEmpty && ! value ) { return ; }
case 'backward' :
this.textBuffer.moveBackward() ;
this.autoResizeAndDrawCursor() ;
break ;
//this.submitted = true ;
this.emit( 'submit' , value , undefined , this ) ;
} ;
case 'forward' :
this.textBuffer.moveForward() ;
this.autoResizeAndDrawCursor() ;
break ;
case 'startOfWord' :
this.textBuffer.moveToStartOfWord() ;
this.autoResizeAndDrawCursor() ;
break ;
case 'endOfWord' :
this.textBuffer.moveToEndOfWord() ;
this.autoResizeAndDrawCursor() ;
break ;
InlineInput.prototype.onKey = function( key , trash , data ) {
if ( this.autoCompleteMenu ) {
// If the autoCompleteMenu is on, force a cancel
this.autoCompleteMenu.emit( 'cancel' ) ;
}
case 'startOfLine' :
this.textBuffer.moveToColumn( 0 ) ;
this.autoResizeAndDrawCursor() ;
break ;
return Element.prototype.onKey.call( this , key , trash , data ) ;
} ;
case 'endOfLine' :
this.textBuffer.moveToEndOfLine() ;
this.autoResizeAndDrawCursor() ;
break ;
case 'left' :
this.textBuffer.moveLeft() ;
this.autoResizeAndDrawCursor() ;
break ;
case 'right' :
this.textBuffer.moveRight() ;
this.autoResizeAndDrawCursor() ;
break ;
const userActions = InlineInput.prototype.userActions ;
case 'pasteClipboard' :
if ( this.document ) {
this.document.getClipboard().then( str => {
if ( str ) {
this.textBuffer.insert( str , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; }
else { this.autoResizeAndDraw() ; }
}
} )
.catch( () => undefined ) ;
}
break ;
case 'copyClipboard' :
if ( this.document ) {
this.document.setClipboard( this.textBuffer.getSelectionText() ).catch( () => undefined ) ;
}
break ;
default :
return ; // Bubble up
}
userActions.character = function( key , trash , data ) {
if ( this.placeholder ) {
// Remove the placeholder on the first user input
this.placeholder = null ;
this.setAltContent( '' , false , true ) ;
}
return true ; // Do not bubble up
this.insert( key ) ;
} ;
userActions.submit = function() {
this.submit() ;
} ;
userActions.cancel = function() {
if ( ! this.cancelable || this.disabled || this.canceled ) { return ; }
//this.canceled = true ;
this.emit( 'cancel' , this ) ;
} ;
/*
InlineInput.prototype.onFocus = function( focus , type ) {
this.hasFocus = focus ;
this.updateStatus() ;
this.draw() ;
userActions.autoComplete = function() {
if ( ! this.autoComplete ) { return ; }
this.runAutoComplete( this.autoComplete ) ;
} ;
*/
userActions.historyAutoComplete = function() {
if ( ! this.autoComplete ) { return ; }
this.runAutoComplete( this.history ) ;
} ;
/*
InlineInput.prototype.onClick = function( data ) {
if ( ! this.hasFocus ) {
this.document.giveFocusTo( this , 'select' ) ;
}
else {
this.textBuffer.moveTo( data.x - this.scrollX , data.y - this.scrollY ) ;
this.drawCursor() ;
}
userActions.historyPrevious = function() {
if ( this.contentIndex <= 0 ) { return ; }
this.contentArray[ this.contentIndex ] = this.getContent() ;
this.contentIndex -- ;
this.setContent( this.contentArray[ this.contentIndex ] ) ;
this.textBuffer.runStateMachine() ;
this.autoResizeAndDraw() ;
} ;
*/
/*
InlineInput.prototype.onMiddleClick = function( data ) {
if ( ! this.hasFocus ) {
this.document.giveFocusTo( this , 'select' ) ;
}
userActions.historyNext = function() {
if ( this.contentIndex >= this.contentArray.length - 1 ) { return ; }
this.contentArray[ this.contentIndex ] = this.getContent() ;
this.contentIndex ++ ;
this.setContent( this.contentArray[ this.contentIndex ] ) ;
this.textBuffer.runStateMachine() ;
this.autoResizeAndDraw() ;
} ;
// Do not moveTo, it's quite boring
//this.textBuffer.moveTo( data.x , data.y ) ;
userActions.backDelete = function() {
this.textBuffer.backDelete() ;
this.textBuffer.runStateMachine() ;
if ( this.document ) {
this.document.getClipboard( 'primary' ).then( str => {
if ( str ) {
this.textBuffer.insert( str , this.textAttr ) ;
this.textBuffer.runStateMachine() ;
this.autoResizeAndDraw() ;
}
//else { this.drawCursor() ; }
} )
.catch( () => undefined ) ;
}
//else { this.drawCursor() ; }
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; } // async
else { this.autoResizeAndDraw() ; }
} ;
*/
userActions.delete = function() {
this.textBuffer.delete() ;
this.textBuffer.runStateMachine() ;
// There isn't much to do ATM
//InlineInput.prototype.updateStatus = function() {} ;
if ( this.useAutoCompleteHint ) { this.runAutoCompleteHint( this.autoComplete ) ; } // async
else { this.autoResizeAndDraw() ; }
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -65,3 +65,3 @@ The MIT License (MIT)

this.turnedOnBlurAttr = options.turnedOnBlurAttr || { bgColor: 'cyan' } ;
this.turnedOnFocusAttr = options.turnedOnFocusAttr || { bgColor: 'brightCyan' , bold: true } ;
this.turnedOnFocusAttr = options.turnedOnFocusAttr || { bgColor: 'brightCyan' , color: 'gray' , bold: true } ;
this.turnedOffBlurAttr = options.turnedOffBlurAttr || { bgColor: 'gray' , dim: true } ;

@@ -93,3 +93,2 @@ this.turnedOffFocusAttr = options.turnedOffFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;

this.onKey = this.onKey.bind( this ) ;
this.onFocus = this.onFocus.bind( this ) ;

@@ -111,7 +110,6 @@ this.onClick = this.onClick.bind( this ) ;

module.exports = LabeledInput ;
Element.inherit( LabeledInput ) ;
LabeledInput.prototype = Object.create( Element.prototype ) ;
LabeledInput.prototype.constructor = LabeledInput ;
LabeledInput.prototype.elementType = 'LabeledInput' ;
LabeledInput.prototype.needInput = true ;

@@ -123,15 +121,2 @@ LabeledInput.prototype.noChildFocus = true ;

LabeledInput.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'focus' , this.onFocus ) ;
this.off( 'click' , this.onClick ) ;
if ( this.input ) { this.off( 'submit' , this.onInputSubmit ) ; }
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
LabeledInput.prototype.keyBindings = {

@@ -147,2 +132,3 @@ ENTER: 'submit' ,

LabeledInput.prototype.editableTextBoxKeyBindings = {
CTRL_K: 'meta' ,
BACKSPACE: 'backDelete' ,

@@ -156,4 +142,17 @@ DELETE: 'delete' ,

END: 'endOfLine' ,
CTRL_O: 'copyClipboard' ,
CTRL_P: 'pasteClipboard'
CTRL_B: 'startOfSelection' ,
CTRL_E: 'endOfSelection' ,
// T for Transfer
CTRL_T: 'moveSelection' ,
ALT_T: 'copyToDocumentClipboard' ,
META_T: 'copyToSystemClipboard' ,
// P for Paste / Put
CTRL_P: 'pasteSelection' ,
ALT_P: 'pasteDocumentClipboard' ,
META_P: 'pasteSystemClipboard' ,
// D for Delete
CTRL_D: 'deleteSelection' ,
ALT_D: 'clearDocumentClipboard' ,
META_D: 'clearSystemClipboard'
} ;

@@ -170,4 +169,10 @@

PAGE_DOWN: 'scrollDown' ,
CTRL_O: 'copyClipboard' ,
CTRL_P: 'pasteClipboard'
CTRL_B: 'startOfSelection' ,
CTRL_E: 'endOfSelection' ,
CTRL_K: 'meta' ,
// We copy vi/vim here, that use 'y' for copy (yank) and 'p' for paste (put)
CTRL_Y: 'copy' ,
META_Y: 'copyClipboard' ,
CTRL_P: 'paste' ,
META_P: 'pasteClipboard'
} ) ;

@@ -348,12 +353,3 @@

switch( this.keyBindings[ key ] ) {
case 'submit' :
this.emit( 'submit' , this.getValue() , undefined , this ) ;
break ;
default :
return ;
}
return true ; // Do not bubble up
return Element.prototype.onKey.call( this , key , altKeys , data ) ;
} ;

@@ -370,4 +366,2 @@

LabeledInput.prototype.onFocus = function( focus , type ) {
this.hasFocus = focus ;
if ( type === 'delegate' ) { return ; }

@@ -403,1 +397,9 @@

const userActions = LabeledInput.prototype.userActions ;
userActions.submit = function() {
this.emit( 'submit' , this.getValue() , undefined , this ) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -69,19 +69,6 @@ The MIT License (MIT)

module.exports = Layout ;
Element.inherit( Layout ) ;
Layout.prototype = Object.create( Element.prototype ) ;
Layout.prototype.constructor = Layout ;
Layout.prototype.elementType = 'Layout' ;
Layout.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'parentResize' , this.onParentResize ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
Layout.prototype.computeBoundingBoxes = function() {

@@ -88,0 +75,0 @@ var computed = this.computed = {} ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -59,2 +59,3 @@ The MIT License (MIT)

this.justify = !! options.justify ;
this.leftMargin = this.leftMargin ?? 0 ; // useful for InlineMenu: it's the place where the prompt is put

@@ -73,9 +74,6 @@ this.separator = options.separator || options.buttonSeparator || ' ' ;

module.exports = RowMenu ;
Element.inherit( RowMenu , BaseMenu ) ;
RowMenu.prototype = Object.create( BaseMenu.prototype ) ;
RowMenu.prototype.constructor = RowMenu ;
RowMenu.prototype.elementType = 'RowMenu' ;
RowMenu.prototype.inlineNewLine = true ;

@@ -95,13 +93,2 @@ RowMenu.prototype.ButtonClass = Button ;

RowMenu.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'focus' , this.onFocus ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
RowMenu.prototype.keyBindings = {

@@ -160,3 +147,3 @@ LEFT: 'previous' ,

if ( this.buttonPaddingWidth > this.outputWidth ) {
if ( this.buttonPaddingWidth > this.outputWidth - this.leftMargin ) {
// The padding itself is bigger than the width... so what should we do?

@@ -195,5 +182,5 @@ return ;

+ ( isLastItem ? 0 : this.nextPageDef.width + this.separatorWidth )
- this.outputWidth ;
- this.outputWidth - this.leftMargin ;
//console.error( "overflow",overflow,pageWidth,def.width,isLastItem,this.nextPageDef.width,this.separatorWidth,this.outputWidth);
//console.error( "overflow",overflow,pageWidth,def.width,isLastItem,this.nextPageDef.width,this.separatorWidth,this.outputWidth,this.leftMargin);
if ( overflow > 0 ) {

@@ -207,3 +194,3 @@ if ( pageItemCount ) {

+ ( isLastItem ? 0 : this.nextPageDef.width + this.separatorWidth )
- this.outputWidth ;
- this.outputWidth - this.leftMargin ;
}

@@ -236,3 +223,3 @@

pageDef.justifyWidth = Math.max( 0 ,
this.justify ? ( this.outputWidth - pageDef.buttonsAndSeparatorsWidth ) / ( pageDef.length - 1 )
this.justify ? ( this.outputWidth - this.leftMargin - pageDef.buttonsAndSeparatorsWidth ) / ( pageDef.length - 1 )
: 0

@@ -252,3 +239,3 @@ ) ;

justifyWidthError = 0 ,
buttonOffsetX = 0 ,
buttonOffsetX = this.leftMargin ,
buttonOffsetY = 0 ;

@@ -260,2 +247,3 @@

this.buttons.length = 0 ;
this.hotkeyToButtonIndex.clear() ;

@@ -300,6 +288,6 @@ //console.error( "pageDef.justifyWidth" , pageDef.justifyWidth ) ;

submittedAttr: def.submittedAttr || this.buttonSubmittedAttr ,
turnedOnFocusAttr: def.turnedOnFocusAttr || this.turnedOnFocusAttr ,
turnedOffFocusAttr: def.turnedOffFocusAttr || this.turnedOffFocusAttr ,
turnedOnBlurAttr: def.turnedOnBlurAttr || this.turnedOnBlurAttr ,
turnedOffBlurAttr: def.turnedOffBlurAttr || this.turnedOffBlurAttr ,
turnedOnFocusAttr: def.turnedOnFocusAttr || this.buttonTurnedOnFocusAttr ,
turnedOffFocusAttr: def.turnedOffFocusAttr || this.buttonTurnedOffFocusAttr ,
turnedOnBlurAttr: def.turnedOnBlurAttr || this.buttonTurnedOnBlurAttr ,
turnedOffBlurAttr: def.turnedOffBlurAttr || this.buttonTurnedOffBlurAttr ,

@@ -337,2 +325,11 @@ blurLeftPadding: this.blurLeftPadding ,

if ( def.hotkey ) {
if ( Array.isArray( def.hotkey ) ) {
def.hotkey.forEach( hotkey => this.hotkeyToButtonIndex.set( hotkey , index ) ) ;
}
else {
this.hotkeyToButtonIndex.set( def.hotkey , index ) ;
}
}
if ( isToggle ) {

@@ -350,3 +347,3 @@ this.buttons[ index ].on( 'toggle' , this.onButtonToggle ) ;

// Set outputWidth to the correct value
//if ( buttonOffsetX < this.outputWidth ) { this.needRedraw = true ; }
//if ( buttonOffsetX < this.outputWidth ) { this.needOuterDraw = true ; }
//this.pageWidth = buttonOffsetX ;

@@ -360,3 +357,3 @@ //this.outputWidth = buttonOffsetY ;

//console.error( string.format( "Call preDrawSelf(), page %i" , this.page ));
this.outputDst.put( { x: this.outputX , y: this.outputY , attr: this.backgroundAttr } , ' '.repeat( this.outputWidth ) ) ;
this.outputDst.put( { x: this.outputX + this.leftMargin , y: this.outputY , attr: this.backgroundAttr } , ' '.repeat( this.outputWidth - this.leftMargin ) ) ;

@@ -363,0 +360,0 @@ if ( this.separator ) {

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -87,9 +87,6 @@ The MIT License (MIT)

module.exports = SelectList ;
Element.inherit( SelectList , ColumnMenu ) ;
SelectList.prototype = Object.create( ColumnMenu.prototype ) ;
SelectList.prototype.constructor = SelectList ;
SelectList.prototype.elementType = 'SelectList' ;
SelectList.prototype.defaultOptions = {

@@ -103,3 +100,3 @@ buttonBlurAttr: { bgColor: 'gray' , color: 'white' , bold: true } ,

turnedOnBlurAttr: { bgColor: 'cyan' } ,
turnedOnFocusAttr: { bgColor: 'brightCyan' , bold: true } ,
turnedOnFocusAttr: { bgColor: 'brightCyan' , color: 'gray' , bold: true } ,
turnedOffBlurAttr: { bgColor: 'gray' , dim: true } ,

@@ -122,12 +119,2 @@ turnedOffFocusAttr: { bgColor: 'white' , color: 'black' , bold: true } ,

SelectList.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'clickOut' , this.onClickOut ) ;
ColumnMenu.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
SelectList.prototype.toggle = function( showMenu = null , noDraw = false ) {

@@ -164,3 +151,3 @@ var i , iMax ;

this.redraw() ;
this.outerDraw() ;
} ;

@@ -225,3 +212,3 @@

this.select( button ) ;
this.emit( 'submit' , buttonValue , action , this ) ;
this.emit( 'submit' , buttonValue , action , this , button ) ;
}

@@ -228,0 +215,0 @@ } ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -80,9 +80,6 @@ The MIT License (MIT)

module.exports = SelectListMulti ;
Element.inherit( SelectListMulti , ColumnMenuMulti ) ;
SelectListMulti.prototype = Object.create( ColumnMenuMulti.prototype ) ;
SelectListMulti.prototype.constructor = SelectListMulti ;
SelectListMulti.prototype.elementType = 'SelectListMulti' ;
SelectListMulti.prototype.defaultOptions = {

@@ -96,3 +93,3 @@ buttonBlurAttr: { bgColor: 'gray' , color: 'white' , bold: true } ,

turnedOnBlurAttr: { bgColor: 'cyan' } ,
turnedOnFocusAttr: { bgColor: 'brightCyan' , bold: true } ,
turnedOnFocusAttr: { bgColor: 'brightCyan' , color: 'gray' , bold: true } ,
turnedOffBlurAttr: { bgColor: 'gray' , dim: true } ,

@@ -115,12 +112,2 @@ turnedOffFocusAttr: { bgColor: 'white' , color: 'black' , bold: true } ,

SelectListMulti.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'clickOut' , this.onClickOut ) ;
ColumnMenuMulti.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
SelectListMulti.prototype.toggle = function( showMenu = null , noDraw = false ) {

@@ -147,3 +134,3 @@ var i , iMax ;

this.redraw() ;
this.outerDraw() ;
} ;

@@ -166,7 +153,7 @@

if ( ! this.showMenu ) {
this.emit( 'submit' , this.value , action , this ) ;
this.emit( 'submit' , this.value , action , this , button ) ;
}
break ;
default :
this.emit( 'submit' , this.value , action , this ) ;
this.emit( 'submit' , this.value , action , this , button ) ;
}

@@ -173,0 +160,0 @@ } ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -84,8 +84,8 @@ The MIT License (MIT)

module.exports = Slider ;
Element.inherit( Slider ) ;
Slider.prototype = Object.create( Element.prototype ) ;
Slider.prototype.constructor = Slider ;
Slider.prototype.elementType = 'Slider' ;
Slider.prototype.needInput = true ;
Slider.prototype.outerDrag = true ;

@@ -116,14 +116,2 @@

Slider.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'click' , this.onClick ) ;
this.off( 'drag' , this.onDrag ) ;
this.off( 'wheel' , this.onWheel ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
// Create Buttons automatically

@@ -295,2 +283,14 @@ Slider.prototype.initChildren = function() {

Slider.prototype.getValue = function() {
return this.rateToValue( this.slideRate ) ;
} ;
Slider.prototype.setValue = function( value , internalAndNoDraw ) {
return this.setSlideRate( this.valueToRate( value ) , internalAndNoDraw ) ;
} ;
Slider.prototype.getHandleOffset = function() { return this.handleOffset ; } ;

@@ -314,14 +314,2 @@ Slider.prototype.getSlideRate = function() { return this.slideRate ; } ;

Slider.prototype.getValue = function() {
return this.rateToValue( this.slideRate ) ;
} ;
Slider.prototype.setValue = function( value , internalAndNoDraw ) {
return this.setSlideRate( this.valueToRate( value ) , internalAndNoDraw ) ;
} ;
Slider.prototype.onClick = function( data ) {

@@ -328,0 +316,0 @@ if ( ! this.hasFocus ) { this.document.giveFocusTo( this , 'select' ) ; }

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -48,6 +48,7 @@ The MIT License (MIT)

// Usually done by the Element's constructor, but it's required now
this.content = options.content ;
this.contentHasMarkup = !! options.contentHasMarkup ;
// Also check that sub-class hasn't defined it yet...
this.content = this.content ?? options.content ;
this.contentHasMarkup = this.contentHasMarkup ?? options.contentHasMarkup ;
// For width and height, we centralize here works for sub-class having animations
// For width and height, we centralize here the work for sub-class having animations
if ( ! options.width ) {

@@ -65,7 +66,6 @@ options.width = this.computeRequiredWidth() ;

module.exports = Text ;
Element.inherit( Text ) ;
Text.prototype = Object.create( Element.prototype ) ;
Text.prototype.constructor = Text ;
Text.prototype.elementType = 'Text' ;
Text.prototype.forceContentArray = true ;

@@ -99,2 +99,3 @@

Text.prototype.resizeOnContent = function() {
// /!\ .width and .height are unused ATM
this.width = this.computeRequiredWidth( this.content , this.contentHasMarkup ) ;

@@ -101,0 +102,0 @@ this.height = this.computeRequiredHeight( this.content , this.contentHasMarkup ) ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -49,3 +49,2 @@ The MIT License (MIT)

this.onKey = this.onKey.bind( this ) ;
this.onClick = this.onClick.bind( this ) ;

@@ -72,5 +71,10 @@ this.onDrag = this.onDrag.bind( this ) ;

this.autoScrollContextLines = options.autoScrollContextLines ?? 0 ;
this.autoScrollContextColumns = options.autoScrollContextColumns ?? 1 ;
// Right shift of the first-line, may be useful for prompt, or continuing another box in the flow
this.firstLineRightShift = options.firstLineRightShift || 0 ;
this.tabWidth = options.tabWidth || 4 ; // How many cells (=spaces) for the tab character
this.wordWrap = !! ( options.wordWrap || options.wordwrap ) ;

@@ -108,9 +112,6 @@ this.lineWrap = !! ( options.lineWrap || this.wordWrap ) ;

module.exports = TextBox ;
Element.inherit( TextBox ) ;
TextBox.prototype = Object.create( Element.prototype ) ;
TextBox.prototype.constructor = TextBox ;
TextBox.prototype.elementType = 'TextBox' ;
// Support for strictInline mode

@@ -121,17 +122,4 @@ TextBox.prototype.strictInlineSupport = true ;

TextBox.prototype.destroy = function( isSubDestroy , noDraw = false ) {
if ( this.destroyed ) { return ; }
this.off( 'key' , this.onKey ) ;
this.off( 'click' , this.onClick ) ;
this.off( 'drag' , this.onDrag ) ;
this.off( 'wheel' , this.onWheel ) ;
this.off( 'parentResize' , this.onParentResize ) ;
Element.prototype.destroy.call( this , isSubDestroy , noDraw ) ;
} ;
TextBox.prototype.keyBindings = {
CTRL_K: 'meta' ,
UP: 'tinyScrollUp' ,

@@ -146,3 +134,6 @@ DOWN: 'tinyScrollDown' ,

RIGHT: 'scrollRight' ,
CTRL_O: 'copyClipboard'
// T for Transfer
ALT_T: 'copyToDocumentClipboard' ,
META_T: 'copyToSystemClipboard'
} ;

@@ -161,2 +152,3 @@

firstLineRightShift: this.firstLineRightShift ,
tabWidth: this.tabWidth ,
lineWrapWidth: this.lineWrap ? this.textAreaWidth : null ,

@@ -175,4 +167,3 @@ wordWrap: this.wordWrap ,

this.textBuffer.setDefaultAttr( this.textAttr ) ;
this.textBuffer.setVoidAttr( this.voidAttr ) ;
this.setAttr( undefined , undefined , true ) ;

@@ -183,2 +174,3 @@

firstLineRightShift: this.firstLineRightShift ,
tabWidth: this.tabWidth ,
lineWrapWidth: this.lineWrap ? this.textAreaWidth : null ,

@@ -195,4 +187,3 @@ wordWrap: this.wordWrap ,

this.altTextBuffer.setDefaultAttr( this.altTextAttr ) ;
this.altTextBuffer.setVoidAttr( this.voidAttr ) ;
this.setAltAttr() ;
this.textBuffer.setVoidTextBuffer( this.altTextBuffer ) ;

@@ -305,3 +296,3 @@ }

// It's best to force the dst now, because it avoids to set textBuffer.dst everytime it changes,
// and it could be changed by userland (so hard to keep it in sync without setters/getters)
// and it could be changed by userland (so it's hard to keep it in sync without setters/getters)
this.textBuffer.draw( { dst: this.outputDst } ) ;

@@ -312,21 +303,2 @@ } ;

TextBox.prototype.scroll = function( dx , dy , dontDraw = false ) {
return this.scrollTo( dx ? this.scrollX + dx : null , dy ? this.scrollY + dy : null , dontDraw ) ;
} ;
TextBox.prototype.scrollToTop = function( dontDraw = false ) {
return this.scrollTo( null , 0 , dontDraw ) ;
} ;
TextBox.prototype.scrollToBottom = function( dontDraw = false ) {
// Ignore extra scrolling here
return this.scrollTo( null , this.textAreaHeight - this.textBuffer.buffer.length , dontDraw ) ;
} ;
TextBox.prototype.scrollTo = function( x , y , noDraw = false ) {

@@ -363,21 +335,39 @@ if ( ! this.scrollable ) { return ; }

TextBox.prototype.scroll = function( dx , dy , dontDraw = false ) {
return this.scrollTo( dx ? this.scrollX + dx : null , dy ? this.scrollY + dy : null , dontDraw ) ;
} ;
TextBox.prototype.scrollToTop = function( dontDraw = false ) {
return this.scrollTo( null , 0 , dontDraw ) ;
} ;
TextBox.prototype.autoScrollAndDraw = function( onlyDrawCursor = false ) {
var x , y ;
TextBox.prototype.scrollToBottom = function( dontDraw = false ) {
// Ignore extra scrolling here
return this.scrollTo( null , this.textAreaHeight - this.textBuffer.buffer.length , dontDraw ) ;
} ;
// We use cx-1 because at least we want to see the char just before the cursor (backspace, etc...)
// But do nothing if there is no scrolling yet (do not set x to 0 if it's unnecessary)
if ( this.textBuffer.cx - 1 < -this.scrollX && this.scrollX !== 0 ) {
x = -Math.max( 0 , this.textBuffer.cx - 1 ) ;
TextBox.prototype.autoScrollAndDraw = function( onlyDrawCursorExceptIfScrolled = false , noDraw = false ) {
var x , y ,
contextColumns = Math.min( Math.floor( this.textAreaWidth / 2 ) , this.autoScrollContextColumns ) ,
contextLines = Math.min( Math.floor( this.textAreaHeight / 2 ) , this.autoScrollContextLines ) ;
// Do nothing if there is no scrolling yet (do not set x to 0 if it's unnecessary)
if ( this.textBuffer.cx < -this.scrollX + contextColumns && this.scrollX !== 0 ) {
// The cursor will be on left of the viewport
x = Math.min( 0 , -this.textBuffer.cx + contextColumns ) ;
}
else if ( this.textBuffer.cx > this.textAreaWidth - this.scrollX - 1 ) {
x = this.textAreaWidth - 1 - this.textBuffer.cx ;
else if ( this.textBuffer.cx > this.textAreaWidth - this.scrollX - 1 - contextColumns ) {
// The cursor will be on right of the viewport
x = this.textAreaWidth - 1 - this.textBuffer.cx - contextColumns ;
}
if ( this.textBuffer.cy < -this.scrollY ) {
y = -this.textBuffer.cy ;
if ( this.textBuffer.cy < -this.scrollY + contextLines ) {
// The cursor will be on top of the viewport
y = Math.min( 0 , -this.textBuffer.cy + contextLines ) ;
}
else if ( this.textBuffer.cy > this.textAreaHeight - this.scrollY - 1 ) {
y = this.textAreaHeight - 1 - this.textBuffer.cy ;
else if ( this.textBuffer.cy > this.textAreaHeight - this.scrollY - 1 - contextLines ) {
// The cursor will be at the bottom of the viewport
y = this.textAreaHeight - 1 - this.textBuffer.cy - contextLines ;
}

@@ -387,5 +377,5 @@

// .scrollTo() call .draw(), so no need to do that here...
this.scrollTo( x , y ) ;
this.scrollTo( x , y , noDraw ) ;
}
else if ( ! onlyDrawCursor ) {
else if ( ! onlyDrawCursorExceptIfScrolled ) {
this.draw() ;

@@ -398,6 +388,13 @@ }

TextBox.prototype.autoScrollAndSmartDraw = function() { return this.autoScrollAndDraw( true ) ; } ;
TextBox.prototype.autoScrollAndDrawCursor = function() {
return this.autoScrollAndDraw( true ) ;
TextBox.prototype.setAttr = function( textAttr = this.textAttr , voidAttr = this.voidAttr , dontDraw = false , dontSetContent = false ) {
this.textAttr = textAttr ;
this.voidAttr = voidAttr ;
this.textBuffer.setDefaultAttr( this.textAttr ) ;
this.textBuffer.setVoidAttr( this.voidAttr ) ;
if ( ! dontSetContent ) { this.setContent( this.content , this.contentHasMarkup , dontDraw ) ; }
} ;

@@ -407,4 +404,6 @@

TextBox.prototype.getContentSize = function() {
return this.textBuffer.getContentSize() ;
TextBox.prototype.setAltAttr = function( altTextAttr = this.altTextAttr ) {
this.altTextAttr = altTextAttr ;
this.altTextBuffer.setDefaultAttr( this.altTextAttr ) ;
this.altTextBuffer.setVoidAttr( this.voidAttr ) ;
} ;

@@ -414,5 +413,4 @@

TextBox.prototype.getContent = function() {
return this.textBuffer.getText() ;
} ;
TextBox.prototype.getContentSize = function() { return this.textBuffer.getContentSize() ; } ;
TextBox.prototype.getContent = function() { return this.textBuffer.getText() ; } ;

@@ -443,3 +441,3 @@

this.drawCursor() ;
this.redraw() ;
this.outerDraw() ;
}

@@ -478,3 +476,3 @@ } ;

this.drawCursor() ;
this.redraw() ;
this.outerDraw() ;
}

@@ -505,6 +503,8 @@ } ;

case 'appendLog' :
// Like 'append' but add a newLine if the last line is not empty, and also check if we need to scroll
scroll = this.textBuffer.buffer.length <= this.textAreaHeight || this.scrollY <= this.textAreaHeight - this.textBuffer.buffer.length ;
content = '\n' + content ;
this.textBuffer.moveToEndOfBuffer() ;
if ( this.textBuffer.cx ) { content = '\n' + content ; }
this.content += content ;
this.textBuffer.append( content , this.contentHasMarkup , this.textAttr ) ;
this.textBuffer.insert( content , this.contentHasMarkup , this.textAttr ) ;
break ;

@@ -536,3 +536,3 @@ case 'append' :

this.draw() ;
//this.redraw() ;
//this.outerDraw() ;
}

@@ -543,47 +543,11 @@ } ;

TextBox.prototype.onKey = function( key , trash , data ) {
switch( this.keyBindings[ key ] ) {
case 'tinyScrollUp' :
this.scroll( 0 , Math.ceil( this.textAreaHeight / 5 ) ) ;
break ;
// TODOC
TextBox.prototype.setTabWidth = function( tabWidth , internal = false ) {
this.tabWidth = + tabWidth || 4 ;
this.textBuffer.setTabWidth( this.tabWidth ) ;
if ( this.altTextBuffer ) { this.altTextBuffer.setTabWidth( this.tabWidth ) ; }
case 'tinyScrollDown' :
this.scroll( 0 , -Math.ceil( this.textAreaHeight / 5 ) ) ;
break ;
case 'scrollUp' :
this.scroll( 0 , Math.ceil( this.textAreaHeight / 2 ) ) ;
break ;
case 'scrollDown' :
this.scroll( 0 , -Math.ceil( this.textAreaHeight / 2 ) ) ;
break ;
case 'scrollLeft' :
this.scroll( Math.ceil( this.textAreaWidth / 2 ) , 0 ) ;
break ;
case 'scrollRight' :
this.scroll( -Math.ceil( this.textAreaWidth / 2 ) , 0 ) ;
break ;
case 'scrollTop' :
this.scrollToTop() ;
break ;
case 'scrollBottom' :
this.scrollToBottom() ;
break ;
case 'copyClipboard' :
if ( this.document ) {
this.document.setClipboard( this.textBuffer.getSelectionText() ).catch( () => undefined ) ;
}
break ;
default :
return ; // Bubble up
if ( ! internal ) {
this.draw() ;
}
return true ; // Do not bubble up
} ;

@@ -593,6 +557,10 @@

TextBox.prototype.onClick = function( data ) {
// It is susceptible to click event only when it is scrollable
if ( this.scrollable && ! this.hasFocus ) {
this.document.giveFocusTo( this , 'select' ) ;
// TODOC
TextBox.prototype.setStateMachine = function( stateMachine , internal = false ) {
this.stateMachine = stateMachine ;
this.textBuffer.stateMachine = this.stateMachine ;
if ( this.stateMachine && ! internal ) {
this.textBuffer.runStateMachine() ;
this.draw() ;
}

@@ -616,3 +584,21 @@ } ;

TextBox.prototype.onClick = function( data ) {
if ( this.hasFocus ) {
if ( this.textBuffer.selectionRegion ) {
this.textBuffer.resetSelectionRegion() ;
this.draw() ;
}
}
else {
if ( this.scrollable ) {
// It is susceptible to click event only when it is scrollable
this.document.giveFocusTo( this , 'select' ) ;
}
}
} ;
TextBox.prototype.onDrag = function( data ) {
//console.error( "TB Drag:" , data ) ;
var xmin , ymin , xmax , ymax ;

@@ -645,3 +631,3 @@

if ( this.document ) {
this.document.setClipboard( this.textBuffer.getSelectionText() , 'primary' ).catch( () => undefined ) ;
this.document.setSystemClipboard( this.textBuffer.getSelectionText() , 'primary' ).catch( () => undefined ) ;
}

@@ -671,1 +657,57 @@

const userActions = TextBox.prototype.userActions ;
userActions.tinyScrollUp = function() {
this.scroll( 0 , Math.ceil( this.textAreaHeight / 5 ) ) ;
this.emit( 'scroll' ) ;
} ;
userActions.tinyScrollDown = function() {
this.scroll( 0 , -Math.ceil( this.textAreaHeight / 5 ) ) ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollUp = function() {
this.scroll( 0 , Math.ceil( this.textAreaHeight / 2 ) ) ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollDown = function() {
this.scroll( 0 , -Math.ceil( this.textAreaHeight / 2 ) ) ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollLeft = function() {
this.scroll( Math.ceil( this.textAreaWidth / 2 ) , 0 ) ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollRight = function() {
this.scroll( -Math.ceil( this.textAreaWidth / 2 ) , 0 ) ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollTop = function() {
this.scrollToTop() ;
this.emit( 'scroll' ) ;
} ;
userActions.scrollBottom = function() {
this.scrollToBottom() ;
this.emit( 'scroll' ) ;
} ;
userActions.copyToDocumentClipboard = function() {
if ( this.document ) {
this.document.setDocumentClipboard( this.textBuffer.getSelectionText() ) ;
}
} ;
userActions.copyToSystemClipboard = function() {
if ( this.document ) {
this.document.setSystemClipboard( this.textBuffer.getSelectionText() ).catch( () => undefined ) ;
}
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -45,2 +45,7 @@ The MIT License (MIT)

this.cellContents = options.cellContents ; // Should be an array of array of text
// This replace .contentWidth/.contentHeight for cell-only size (without shrinking/expanding/fitting)
this.rawContentWidth = 0 ;
this.rawContentHeight = 0 ;
this.contentHasMarkup = options.contentHasMarkup ;

@@ -79,2 +84,12 @@

/*
// Select attr
// /!\ NOT IMPLEMENTED YET /!\
// Would allow one to navigate the table (it could be useful for making editable cells)
this.selectedTextAttr = options.selectedTextAttr || null ;
this.selectedVoidAttr = options.selectedVoidAttr || null ;
this.selectable = options.selectable || null ; // Can be 'row', 'column' or 'cell'
this.selectedX = this.selectedY = 0 ;
*/
this.expandToWidth = options.expandToWidth !== undefined ? !! options.expandToWidth : !! options.fit ;

@@ -99,3 +114,3 @@ this.shrinkToWidth = options.shrinkToWidth !== undefined ? !! options.shrinkToWidth : !! options.fit ;

if ( typeof options.borderChars === 'object' ) {
this.borderChars = options.borderChars ;
this.borderChars = boxesChars.__fix__( options.borderChars ) ;
}

@@ -111,5 +126,2 @@ else if ( typeof options.borderChars === 'string' && boxesChars[ options.borderChars ] ) {

if ( ! options.width ) { this.outputWidth = this.contentWidth ; }
if ( ! options.height ) { this.outputHeight = this.contentHeight ; }
// Only draw if we are not a superclass of the object

@@ -120,12 +132,10 @@ if ( this.elementType === 'TextTable' && ! options.noDraw ) { this.draw() ; }

module.exports = TextTable ;
Element.inherit( TextTable ) ;
TextTable.prototype = Object.create( Element.prototype ) ;
TextTable.prototype.constructor = TextTable ;
TextTable.prototype.elementType = 'TextTable' ;
// Support for strictInline mode
TextTable.prototype.strictInlineSupport = true ;
TextTable.prototype.staticInline = true ;
TextTable.prototype.inlineResizeToContent = true ;

@@ -144,7 +154,42 @@

// For instance, .cellContents is rather useless, but we still update it
// Save cell content
this.cellContents[ y ][ x ] = content ;
textBox.setContent( content , this.contentHasMarkup , true ) ;
if ( ! dontUpdateLayout ) { this.computeCells() ; }
if ( ! dontUpdateLayout ) {
this.computeCells() ;
if ( ! dontDraw ) { this.draw() ; }
}
else {
if ( ! dontDraw ) { textBox.draw() ; }
}
} ;
TextTable.prototype.setCellAttr = function( x , y , textAttr , voidAttr , dontDraw = false ) {
var textBox = this.textBoxes[ y ] && this.textBoxes[ y ][ x ] ;
if ( ! textBox ) { return ; }
if ( voidAttr === undefined ) { voidAttr = textAttr ; }
textBox.setAttr( textAttr , voidAttr , dontDraw ) ;
} ;
TextTable.prototype.resetCellAttr = function( x , y , dontDraw = false ) {
var textBox = this.textBoxes[ y ] && this.textBoxes[ y ][ x ] ;
if ( ! textBox ) { return ; }
var textAttr = this.getTextAttrForCell( x , y ) ,
voidAttr = this.getVoidAttrForCell( x , y , textAttr ) ;
textBox.setAttr( textAttr , voidAttr , dontDraw ) ;
} ;
TextTable.prototype.setRowAttr = function( y , textAttr , voidAttr , dontDraw = false ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
if ( ! dontDraw ) { this.draw() ; }

@@ -155,2 +200,69 @@ } ;

TextTable.prototype.resetRowAttr = function( y , dontDraw = false ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.resetCellAttr( x , y , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;
TextTable.prototype.setColumnAttr = function( x , textAttr , voidAttr , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;
TextTable.prototype.resetColumnAttr = function( x , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) { this.resetCellAttr( x , y , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;
TextTable.prototype.setTableAttr = function( textAttr , voidAttr , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
}
if ( ! dontDraw ) { this.draw() ; }
} ;
TextTable.prototype.resetTableAttr = function( dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.resetCellAttr( x , y , true ) ; }
}
if ( ! dontDraw ) { this.draw() ; }
} ;
TextTable.prototype.getTextAttrForCell = function( x , y ) {
return this.firstCellTextAttr && ! x && ! y ? this.firstCellTextAttr :
this.firstRowTextAttr && ! y ? this.firstRowTextAttr :
this.firstColumnTextAttr && ! x ? this.firstColumnTextAttr :
this.evenCellTextAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellTextAttr :
this.checkerEvenCellTextAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellTextAttr :
this.evenRowTextAttr && ! ( y % 2 ) ? this.evenRowTextAttr :
this.evenColumnTextAttr && ! ( y % 2 ) ? this.evenColumnTextAttr :
this.textAttr ;
} ;
TextTable.prototype.getVoidAttrForCell = function( x , y , textAttr ) {
return this.firstCellVoidAttr && ! x && ! y ? this.firstCellVoidAttr :
this.firstRowVoidAttr && ! y ? this.firstRowVoidAttr :
this.firstColumnVoidAttr && ! x ? this.firstColumnVoidAttr :
this.evenCellVoidAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellVoidAttr :
this.checkerEvenCellVoidAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellVoidAttr :
this.evenRowVoidAttr && ! ( y % 2 ) ? this.evenRowVoidAttr :
this.evenColumnVoidAttr && ! ( y % 2 ) ? this.evenColumnVoidAttr :
this.voidAttr || textAttr ;
} ;
TextTable.prototype.initChildren = function() {

@@ -172,22 +284,5 @@ var row , cellContent , textAttr , voidAttr ;

textAttr =
this.firstCellTextAttr && ! x && ! y ? this.firstCellTextAttr :
this.firstRowTextAttr && ! y ? this.firstRowTextAttr :
this.firstColumnTextAttr && ! x ? this.firstColumnTextAttr :
this.evenCellTextAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellTextAttr :
this.checkerEvenCellTextAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellTextAttr :
this.evenRowTextAttr && ! ( y % 2 ) ? this.evenRowTextAttr :
this.evenColumnTextAttr && ! ( y % 2 ) ? this.evenColumnTextAttr :
this.textAttr ;
textAttr = this.getTextAttrForCell( x , y ) ;
voidAttr = this.getVoidAttrForCell( x , y , textAttr ) ;
voidAttr =
this.firstCellVoidAttr && ! x && ! y ? this.firstCellVoidAttr :
this.firstRowVoidAttr && ! y ? this.firstRowVoidAttr :
this.firstColumnVoidAttr && ! x ? this.firstColumnVoidAttr :
this.evenCellVoidAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellVoidAttr :
this.checkerEvenCellVoidAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellVoidAttr :
this.evenRowVoidAttr && ! ( y % 2 ) ? this.evenRowVoidAttr :
this.evenColumnVoidAttr && ! ( y % 2 ) ? this.evenColumnVoidAttr :
this.voidAttr || textAttr ;
this.textBoxes[ y ][ x ] = new TextBox( {

@@ -241,3 +336,3 @@ internal: true ,

this.contentWidth = + this.hasBorder ; // +true = 1
this.rawContentWidth = + this.hasBorder ; // +true = 1

@@ -253,10 +348,14 @@ for ( x = 0 ; x < this.columnCount ; x ++ ) {

this.columnWidths[ x ] = max ;
this.contentWidth += max + this.hasBorder ; // +true = 1
this.rawContentWidth += max + this.hasBorder ; // +true = 1
}
if ( this.expandToWidth && this.contentWidth < this.outputWidth ) {
this.expand( this.contentWidth , this.outputWidth , this.columnWidths ) ;
this.contentWidth = this.rawContentWidth ;
if ( this.expandToWidth && this.rawContentWidth < this.outputWidth ) {
this.expand( this.rawContentWidth , this.outputWidth , this.columnWidths ) ;
this.contentWidth = this.outputWidth ;
}
else if ( this.shrinkToWidth && this.contentWidth > this.outputWidth ) {
this.shrink( this.contentWidth , this.outputWidth , this.columnWidths ) ;
else if ( this.shrinkToWidth && this.rawContentWidth > this.outputWidth ) {
this.shrink( this.rawContentWidth , this.outputWidth , this.columnWidths ) ;
this.contentWidth = this.outputWidth ;
return true ;

@@ -273,3 +372,3 @@ }

this.contentHeight = + this.hasBorder ; // +true = 1
this.rawContentHeight = + this.hasBorder ; // +true = 1

@@ -285,12 +384,18 @@ for ( y = 0 ; y < this.rowCount ; y ++ ) {

this.rowHeights[ y ] = max ;
this.contentHeight += max + this.hasBorder ; // +true = 1
this.rawContentHeight += max + this.hasBorder ; // +true = 1
}
if ( this.expandToHeight && this.contentHeight < this.outputHeight ) {
this.expand( this.contentHeight , this.outputHeight , this.rowHeights ) ;
this.contentHeight = this.rawContentHeight ;
if ( this.expandToHeight && this.rawContentHeight < this.outputHeight ) {
this.expand( this.rawContentHeight , this.outputHeight , this.rowHeights ) ;
this.contentHeight = this.outputHeight ;
}
else if ( this.shrinkToHeight && this.contentHeight > this.outputHeight ) {
this.shrink( this.contentHeight , this.outputHeight , this.rowHeights ) ;
else if ( this.shrinkToHeight && this.rawContentHeight > this.outputHeight ) {
this.shrink( this.rawContentHeight , this.outputHeight , this.rowHeights ) ;
this.contentHeight = this.outputHeight ;
return true ;
}
return false ;
} ;

@@ -332,4 +437,2 @@

//console.log( contentSize , outputSize , delta ) ;
while ( delta > 0 ) {

@@ -437,4 +540,2 @@ max = 0 ;

//console.log( this.columnWidths , this.rowHeights , this.columnCount , this.rowCount ) ;
y = this.outputY ;

@@ -441,0 +542,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -52,9 +52,6 @@ The MIT License (MIT)

module.exports = ToggleButton ;
Element.inherit( ToggleButton , Button ) ;
ToggleButton.prototype = Object.create( Button.prototype ) ;
ToggleButton.prototype.constructor = ToggleButton ;
ToggleButton.prototype.elementType = 'ToggleButton' ;
ToggleButton.prototype.keyBindings = {

@@ -73,3 +70,5 @@ ENTER: 'toggle' ,

ToggleButton.prototype.setValue = function( value , noDraw ) {
ToggleButton.prototype.getValue = function() { return this.value ; } ;
ToggleButton.prototype.setValue = function( value , noDraw , noEmit ) {
value = !! value ;

@@ -79,4 +78,8 @@ if ( this.value === value ) { return ; }

this.updateStatus() ;
this.emit( 'toggle' , this.value , undefined , this ) ;
this.emit( this.value ? 'turnOn' : 'turnOff' , this.value , undefined , this ) ;
if ( ! noEmit ) {
this.emit( 'toggle' , this.value , undefined , this ) ;
this.emit( this.value ? 'turnOn' : 'turnOff' , this.value , undefined , this ) ;
}
if ( ! noDraw ) { this.draw() ; }

@@ -96,2 +99,3 @@ } ;

this.attr = this.disabledAttr ;
this.content = this.disabledContent ;
this.leftPadding = this.disabledLeftPadding ;

@@ -103,2 +107,3 @@ this.rightPadding = this.disabledRightPadding ;

this.attr = this.turnedOnFocusAttr ;
this.content = this.turnedOnFocusContent ;
this.leftPadding = this.turnedOnFocusLeftPadding ;

@@ -109,2 +114,3 @@ this.rightPadding = this.turnedOnFocusRightPadding ;

this.attr = this.turnedOffFocusAttr ;
this.content = this.turnedOffFocusContent ;
this.leftPadding = this.turnedOffFocusLeftPadding ;

@@ -116,2 +122,3 @@ this.rightPadding = this.turnedOffFocusRightPadding ;

this.attr = this.turnedOnBlurAttr ;
this.content = this.turnedOnBlurContent ;
this.leftPadding = this.turnedOnBlurLeftPadding ;

@@ -122,2 +129,3 @@ this.rightPadding = this.turnedOnBlurRightPadding ;

this.attr = this.turnedOffBlurAttr ;
this.content = this.turnedOffBlurContent ;
this.leftPadding = this.turnedOffBlurLeftPadding ;

@@ -130,21 +138,2 @@ this.rightPadding = this.turnedOffBlurRightPadding ;

ToggleButton.prototype.onKey = function( key , altKeys , data ) {
switch( this.keyBindings[ key ] ) {
case 'toggle' :
if ( this.disabled ) { break ; }
this.toggle() ;
break ;
case 'submit' :
if ( this.disabled ) { break ; }
this.emit( 'submit' , this.key ? { [ this.key ]: this.value } : this.value , this.actionKeyBindings[ key ] , this ) ;
break ;
default :
return ; // Bubble up
}
return true ; // Do not bubble up
} ;
ToggleButton.prototype.onHover = function( data ) {

@@ -171,1 +160,15 @@ if ( this.disabled ) { return ; }

const userActions = ToggleButton.prototype.userActions ;
userActions.toggle = function() {
if ( this.disabled ) { return ; }
this.toggle() ;
} ;
userActions.submit = function( key ) {
if ( this.disabled ) { return ; }
this.emit( 'submit' , this.key ? { [ this.key ]: this.value } : this.value , this.actionKeyBindings[ key ] , this ) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -33,3 +33,3 @@ The MIT License (MIT)

const Container = require( './Container.js' ) ;
const boxesChars = require( '../spChars.js' ).box ;
const framesChars = require( '../spChars.js' ).box ;

@@ -49,10 +49,13 @@

this.boxChars = boxesChars.double ;
this.frameChars = framesChars.double ;
if ( options.boxChars ) {
if ( typeof options.boxChars === 'object' ) {
this.boxChars = options.boxChars ;
// Backward compatibility, boxChars is DEPRECATED
if ( options.boxChars && ! options.frameChars ) { options.frameChars = options.boxChars ; }
if ( options.frameChars ) {
if ( typeof options.frameChars === 'object' ) {
this.frameChars = options.frameChars ;
}
else if ( typeof options.boxChars === 'string' && boxesChars[ options.boxChars ] ) {
this.boxChars = boxesChars[ options.boxChars ] ;
else if ( typeof options.frameChars === 'string' && framesChars[ options.frameChars ] ) {
this.frameChars = framesChars[ options.frameChars ] ;
}

@@ -66,8 +69,8 @@ }

module.exports = Window ;
Element.inherit( Window , Container ) ;
Window.prototype = Object.create( Container.prototype ) ;
Window.prototype.constructor = Window ;
Window.prototype.elementType = 'Window' ;
Window.prototype.containerBorderSize = 1 ;
Window.prototype.outerDrag = true ;

@@ -77,3 +80,3 @@

Window.prototype.preDrawSelf = function() {
var y , title , titleWidth ,
var y , title , titleWidth , vFrame ,
titleMaxWidth = this.outputWidth - 8 ;

@@ -88,6 +91,6 @@

{ x: this.outputX , y: this.outputY , markup: this.contentHasMarkup } ,
this.boxChars.topLeft + this.boxChars.horizontal
this.frameChars.topLeft + this.frameChars.horizontal
+ '[' + title + ']'
+ this.boxChars.horizontal.repeat( this.outputWidth - 5 - titleWidth )
+ this.boxChars.topRight
+ this.frameChars.horizontal.repeat( this.outputWidth - 5 - titleWidth )
+ this.frameChars.topRight
) ;

@@ -98,3 +101,3 @@ }

{ x: this.outputX , y: this.outputY } ,
this.boxChars.topLeft + this.boxChars.horizontal.repeat( this.outputWidth - 2 ) + this.boxChars.topRight
this.frameChars.topLeft + this.frameChars.horizontal.repeat( this.outputWidth - 2 ) + this.frameChars.topRight
) ;

@@ -106,10 +109,9 @@ }

{ x: this.outputX , y: this.outputY + this.outputHeight - 1 } ,
this.boxChars.bottomLeft + this.boxChars.horizontal.repeat( this.outputWidth - 2 ) + this.boxChars.bottomRight
this.frameChars.bottomLeft + this.frameChars.horizontal.repeat( this.outputWidth - 2 ) + this.frameChars.bottomRight
) ;
// Draw the left and right border
for ( y = this.outputY + 1 ; y < this.outputY + this.outputHeight - 1 ; y ++ ) {
this.outputDst.put( { x: this.outputX , y: y } , this.boxChars.vertical ) ;
this.outputDst.put( { x: this.outputX + this.outputWidth - 1 , y: y } , this.boxChars.vertical ) ;
}
vFrame = this.frameChars.vertical.repeat( this.outputHeight - 2 ) ;
this.outputDst.put( { x: this.outputX , y: this.outputY + 1 , direction: 'down' } , vFrame ) ;
this.outputDst.put( { x: this.outputX + this.outputWidth - 1 , y: this.outputY + 1 , direction: 'down' } , vFrame ) ;

@@ -116,0 +118,0 @@ Container.prototype.preDrawSelf.call( this ) ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,6 +31,4 @@ The MIT License (MIT)

var Promise = require( 'seventh' ) ;
var autoComplete = require( './autoComplete.js' ) ;
var fs = require( 'fs' ) ;
var path = require( 'path' ) ;
const fileHelpers = require( './fileHelpers.js' ) ;
const path = require( 'path' ) ;

@@ -42,132 +40,38 @@

*/
module.exports = function fileInput( options , callback ) {
module.exports = async function fileInput( options , callback ) {
var baseDir , autoCompleteFileOptions , inputFieldOptions , input ;
if ( typeof options === 'function' ) { callback = options ; options = {} ; }
if ( ! options || typeof options !== 'object' ) { options = {} ; }
var baseDir ;
try {
baseDir = await fileHelpers.resolveBaseDir( options.baseDir ) ;
var promise = new Promise() ;
autoCompleteFileOptions = { baseDir } ;
if ( options.baseDir ) {
baseDir = path.resolve( options.baseDir ) ;
// Transmit options to inputField()
inputFieldOptions = Object.assign( {} , options , {
autoComplete: inputString => fileHelpers.autoCompleteFile( inputString , autoCompleteFileOptions ) ,
autoCompleteMenu: true ,
minLength: 1
} ) ;
if ( ! path.isAbsolute( baseDir ) ) {
fs.realpath( options.baseDir , ( error , resolvedPath ) => {
if ( error ) {
if ( callback ) { callback( error ) ; }
else { promise.reject( error ) ; }
return ;
}
input = await this.inputField( inputFieldOptions ).promise ;
}
catch ( error ) {
if ( callback ) { callback( error ) ; return ; }
throw error ;
}
options.baseDir = resolvedPath ;
this.fileInput( options ).then(
input => {
if ( callback ) { callback( input ) ; }
else { promise.resolve( input ) ; }
} ,
error_ => {
if ( callback ) { callback( error_ ) ; }
else { promise.reject( error_ ) ; }
}
) ;
} ) ;
return promise ;
}
if ( ! input && typeof input !== 'string' ) {
input = undefined ;
}
else {
baseDir = process.cwd() ;
input = path.resolve( path.isAbsolute( input ) ? input : baseDir + input ) ;
}
if ( baseDir[ baseDir.length - 1 ] !== '/' ) { baseDir += '/' ; }
if ( callback ) { callback( undefined , input ) ; }
var autoCompleter = async function autoCompleter( inputString ) {
var inputDir , inputFile , currentDir , files , completion ;
if ( inputString[ inputString.length - 1 ] === '/' ) {
inputDir = inputString ;
inputFile = '' ;
}
else {
inputDir = path.dirname( inputString ) ;
inputDir = inputDir === '.' ? '' : inputDir + '/' ;
inputFile = path.basename( inputString ) ;
}
// If the input start with a '/', then forget about the baseDir
if ( path.isAbsolute( inputString ) ) { currentDir = inputDir ; }
else { currentDir = baseDir + inputDir ; }
//console.error( "### '" + inputDir +"' '"+ inputFile +"' '"+ currentDir + "'" ) ;
try {
files = await readdir( currentDir ) ;
}
catch ( error ) {
return inputString ;
}
if ( ! Array.isArray( files ) || ! files.length ) { return inputString ; }
completion = autoComplete( files , inputFile , true ) ;
// force inputField() to prefix that *AFTER* singleLineMenu()
if ( Array.isArray( completion ) ) { completion.prefix = inputDir ; }
else { completion = path.normalize( inputDir + completion ) ; }
return completion ;
} ;
// Transmit options to inputField()
options = Object.assign( {} , options , { autoComplete: autoCompleter , autoCompleteMenu: true , minLength: 1 } ) ;
this.inputField( options ).promise.then(
input => {
if ( ! input && typeof input !== 'string' ) {
input = undefined ;
}
else {
input = path.resolve( path.isAbsolute( input ) ? input : baseDir + input ) ;
}
if ( callback ) { callback( undefined , input ) ; }
else { promise.resolve( input ) ; }
} ,
error => {
if ( callback ) { callback( error ) ; }
else { promise.reject( error ) ; }
}
) ;
return promise ;
return input ;
} ;
// Like fs.readdir(), but performs fs.stat() for each file in order to add a '/' to directories
function readdir( dir ) {
var promise = new Promise() ;
if ( dir[ dir.length - 1 ] !== '/' ) { dir += '/' ; }
fs.readdir( dir , ( error , files ) => {
if ( error ) { promise.reject( error ) ; return ; }
Promise.map( files , file => {
return new Promise( ( resolve , reject ) => {
fs.lstat( dir + file , ( error_ , stats ) => {
if ( error_ ) { reject( error_ ) ; return ; }
if ( stats.isDirectory() ) { file += '/' ; }
resolve( file ) ;
} ) ;
} ) ;
} )
.toPromise( promise ) ;
} ) ;
return promise ;
}
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -37,7 +37,7 @@ The MIT License (MIT)

var net = require( 'net' ) ;
var NextGenEvents = require( 'nextgen-events' ) ;
var termkit = require( './termkit.js' ) ;
const net = require( 'net' ) ;
const NextGenEvents = require( 'nextgen-events' ) ;
const termkit = require( './termkit.js' ) ;
var gpm = {} ;
const gpm = {} ;
module.exports = gpm ;

@@ -55,3 +55,3 @@

// Can't figure out the usage of the GPM_MAGIC constant ATM
var gpmMagic = Buffer.allocUnsafe( 4 ) ;
const gpmMagic = Buffer.allocUnsafe( 4 ) ;
gpmMagic.writeUInt32LE( 0x47706D4C , 0 ) ;

@@ -62,3 +62,3 @@

// Return a Buffer containing a Gpm_Connect structure, using a pid and a ttyIndex
gpm.connectStructureBuffer = function connectStructureBuffer( gpmConnect ) {
gpm.connectStructureBuffer = gpmConnect => {
var buffer = Buffer.allocUnsafe( 16 ) ;

@@ -87,3 +87,3 @@

// Extract a Gpm_Event from a Buffer
gpm.eventStructure = function eventStructure( buffer ) {
gpm.eventStructure = buffer => {
var event = {} ;

@@ -159,3 +159,3 @@

// Create a new GPM Handler
gpm.createHandler = function createHandler( options ) {
gpm.createHandler = function( options ) {
if ( ! options || typeof options !== 'object' ) { options = {} ; }

@@ -225,3 +225,3 @@

// End/Close the underlying connection
gpm.Handler.prototype.close = function handlerClose() {
gpm.Handler.prototype.close = function() {
if ( this.socket ) {

@@ -236,3 +236,3 @@ this.socket.destroy() ;

// Transform raw GPM event to terminal-kit event
gpm.raw2terminalKitEvent = function raw2terminalKitEvent( event ) {
gpm.raw2terminalKitEvent = function( event ) {
var name ;

@@ -265,2 +265,1 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,8 +31,8 @@ The MIT License (MIT)

var ndarray = require( 'ndarray' ) ;
var Promise = require( 'seventh' ) ;
const ndarray = require( 'ndarray' ) ;
const Promise = require( 'seventh' ) ;
var image = {} ;
const image = {} ;
module.exports = image ;

@@ -43,2 +43,3 @@

var getPixels ;
if ( global.IS_BROWSER ) { getPixels = require( '@cronvel/get-pixels' ) ; }

@@ -45,0 +46,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -35,7 +35,2 @@ The MIT License (MIT)

const misc = {} ;
module.exports = misc ;
const colorNameToIndexDict = {

@@ -68,3 +63,3 @@ // ANSI

// Color name to index
misc.colorNameToIndex = color => colorNameToIndexDict[ color.toLowerCase() ] ;
exports.colorNameToIndex = color => colorNameToIndexDict[ color.toLowerCase() ] ;

@@ -81,7 +76,7 @@

// Color name to index
misc.indexToColorName = index => indexToColorNameArray[ index ] ;
exports.indexToColorName = index => indexToColorNameArray[ index ] ;
misc.hexToRgba = hex => {
exports.hexToRgba = hex => {
// Strip the # if necessary

@@ -95,6 +90,6 @@ if ( hex[ 0 ] === '#' ) { hex = hex.slice( 1 ) ; }

return {
r: parseInt( hex.slice( 0 , 2 ) , 16 ) ,
g: parseInt( hex.slice( 2 , 4 ) , 16 ) ,
b: parseInt( hex.slice( 4 , 6 ) , 16 ) ,
a: hex.length > 6 ? parseInt( hex.slice( 6 , 8 ) , 16 ) : 255
r: parseInt( hex.slice( 0 , 2 ) , 16 ) || 0 ,
g: parseInt( hex.slice( 2 , 4 ) , 16 ) || 0 ,
b: parseInt( hex.slice( 4 , 6 ) , 16 ) || 0 ,
a: hex.length > 6 ? parseInt( hex.slice( 6 , 8 ) , 16 ) || 0 : 255
} ;

@@ -106,5 +101,5 @@ } ;

// DEPRECATED function names
misc.color2index = misc.colorNameToIndex ;
misc.index2color = misc.indexToColorName ;
misc.hexToColor = misc.hexToRgba ;
exports.color2index = exports.colorNameToIndex ;
exports.index2color = exports.indexToColorName ;
exports.hexToColor = exports.hexToRgba ;

@@ -114,3 +109,3 @@

// Strip all control chars, if newline is true, only newline control chars are preserved
misc.stripControlChars = ( str , newline ) => {
exports.stripControlChars = ( str , newline ) => {
if ( newline ) { return str.replace( /[\x00-\x09\x0b-\x1f\x7f]/g , '' ) ; }

@@ -128,3 +123,3 @@ return str.replace( /[\x00-\x1f\x7f]/g , '' ) ;

misc.stripEscapeSequences = str => str.replace( escapeSequenceRegex , '' ) ;
exports.stripEscapeSequences = str => str.replace( escapeSequenceRegex , '' ) ;

@@ -134,4 +129,4 @@

// Return the real width of the string (i.e. as displayed in the terminal)
misc.ansiWidth =
misc.stringWidth = str => {
exports.ansiWidth =
exports.stringWidth = str => {
var matches , width = 0 ;

@@ -156,3 +151,3 @@

var lastTruncateWidth = 0 ;
misc.getLastTruncateWidth = () => lastTruncateWidth ;
exports.getLastTruncateWidth = () => lastTruncateWidth ;

@@ -162,4 +157,4 @@

// Truncate a string to a given real width
misc.truncateAnsiString =
misc.truncateString = ( str , maxWidth ) => {
exports.truncateAnsiString =
exports.truncateString = ( str , maxWidth ) => {
var matches , width = 0 ;

@@ -193,5 +188,7 @@

// width of a string with a markup, without control chars
misc.markupWidth = str => {
return string.unicode.width( str.replace( /\^\[[^\]]*]|\^(.)/g , ( match , second ) => {
// Width of a string with a markup, without control chars
exports.markupWidth = str => {
// Fix a possible ReDoS, the regex: /\^\[[^\]]*]|\^(.)/g was replaced by: /\^\[[^\]]*]?|\^(.)/g
// The exploit was possible with a string like: '^['.repeat(bigNumber)
return string.unicode.width( str.replace( /\^\[[^\]]*]?|\^(.)/g , ( match , second ) => {
if ( second === ' ' || second === '^' ) {

@@ -208,3 +205,3 @@ return second ;

// Truncate a string to a given real width, the string may contains markup, but no control chars
misc.truncateMarkupString = ( str , maxWidth ) => {
exports.truncateMarkupString = ( str , maxWidth ) => {
var index = 0 , charWidth ,

@@ -249,3 +246,3 @@ strArray = string.unicode.toArray( str ) ;

// TODO: many issues remaining
misc.escapeSequenceSkipFn = ( strArray , index ) => {
exports.escapeSequenceSkipFn = ( strArray , index ) => {
//console.error( '>>> Entering' ) ;

@@ -275,3 +272,3 @@ var code ;

misc.wordWrapAnsi = ( str , width ) => string.wordwrap( str , {
exports.wordWrapAnsi = ( str , width ) => string.wordwrap( str , {
width: width ,

@@ -327,4 +324,4 @@ noJoin: true ,

misc.wordwrapMarkup = // <-- DEPRECATED
misc.wordWrapMarkup = ( str , width ) => string.wordwrap( str , {
exports.wordwrapMarkup = // <-- DEPRECATED name (bad camel case)
exports.wordWrapMarkup = ( str , width ) => string.wordwrap( str , {
width: width ,

@@ -381,3 +378,3 @@ noJoin: true ,

misc.preserveMarkupFormat = string.createFormatter( {
exports.preserveMarkupFormat = string.createFormatter( {
argumentSanitizer: str => str.replace( /[\x00-\x1f\x7f^]/g , char => char === '^' ? '^^' : '' ) ,

@@ -389,8 +386,60 @@ noMarkup: true

misc.markupOptions = {
complexMarkupAliases: {
c: 'color' ,
fg: 'color' ,
bg: 'bgColor'
} ,
// Catch-all keywords to key:value
const CATCH_ALL_KEYWORDS = {
// Foreground colors
defaultColor: [ 'color' , 'default' ] ,
black: [ 'color' , 'black' ] ,
red: [ 'color' , 'red' ] ,
green: [ 'color' , 'green' ] ,
yellow: [ 'color' , 'yellow' ] ,
blue: [ 'color' , 'blue' ] ,
magenta: [ 'color' , 'magenta' ] ,
cyan: [ 'color' , 'cyan' ] ,
white: [ 'color' , 'white' ] ,
grey: [ 'color' , 'grey' ] ,
gray: [ 'color' , 'gray' ] ,
brightBlack: [ 'color' , 'brightBlack' ] ,
brightRed: [ 'color' , 'brightRed' ] ,
brightGreen: [ 'color' , 'brightGreen' ] ,
brightYellow: [ 'color' , 'brightYellow' ] ,
brightBlue: [ 'color' , 'brightBlue' ] ,
brightMagenta: [ 'color' , 'brightMagenta' ] ,
brightCyan: [ 'color' , 'brightCyan' ] ,
brightWhite: [ 'color' , 'brightWhite' ] ,
// Background colors
defaultBgColor: [ 'bgColor' , 'default' ] ,
bgBlack: [ 'bgColor' , 'black' ] ,
bgRed: [ 'bgColor' , 'red' ] ,
bgGreen: [ 'bgColor' , 'green' ] ,
bgYellow: [ 'bgColor' , 'yellow' ] ,
bgBlue: [ 'bgColor' , 'blue' ] ,
bgMagenta: [ 'bgColor' , 'magenta' ] ,
bgCyan: [ 'bgColor' , 'cyan' ] ,
bgWhite: [ 'bgColor' , 'white' ] ,
bgGrey: [ 'bgColor' , 'grey' ] ,
bgGray: [ 'bgColor' , 'gray' ] ,
bgBrightBlack: [ 'bgColor' , 'brightBlack' ] ,
bgBrightRed: [ 'bgColor' , 'brightRed' ] ,
bgBrightGreen: [ 'bgColor' , 'brightGreen' ] ,
bgBrightYellow: [ 'bgColor' , 'brightYellow' ] ,
bgBrightBlue: [ 'bgColor' , 'brightBlue' ] ,
bgBrightMagenta: [ 'bgColor' , 'brightMagenta' ] ,
bgBrightCyan: [ 'bgColor' , 'brightCyan' ] ,
bgBrightWhite: [ 'bgColor' , 'brightWhite' ] ,
// Other styles
dim: [ 'dim' , true ] ,
bold: [ 'bold' , true ] ,
underline: [ 'underline' , true ] ,
italic: [ 'italic' , true ] ,
inverse: [ 'inverse' , true ]
} ;
exports.markupCatchAllKeywords = CATCH_ALL_KEYWORDS ;
exports.markupOptions = {
parse: true ,
shiftMarkup: {

@@ -400,5 +449,11 @@ '#': 'background'

markup: {
':': { reset: true } ,
' ': { reset: true , raw: ' ' } ,
';': { reset: true , special: true } , // "Special reset" can reset forced attr (Document-model)
':': null ,
' ': markupStack => {
markupStack.length = 0 ;
return [ null , ' ' ] ;
} ,
';': markupStack => {
markupStack.length = 0 ;
return [ null , { specialReset: true } ] ;
} ,

@@ -430,8 +485,10 @@ '-': { dim: true } ,

background: {
':': { reset: true , defaultColor: true , bgDefaultColor: true } ,
' ': {
reset: true , defaultColor: true , bgDefaultColor: true , raw: ' '
':': [ null , { defaultColor: true , bgDefaultColor: true } ] ,
' ': markupStack => {
markupStack.length = 0 ;
return [ null , { defaultColor: true , bgDefaultColor: true } , ' ' ] ;
} ,
';': {
reset: true , special: true , defaultColor: true , bgDefaultColor: true
';': markupStack => {
markupStack.length = 0 ;
return [ null , { specialReset: true , defaultColor: true , bgDefaultColor: true } ] ;
} ,

@@ -456,39 +513,30 @@

}
}
} ;
} ,
dataMarkup: {
color: 'color' ,
fgColor: 'color' ,
fg: 'color' ,
c: 'color' ,
bgColor: 'bgColor' ,
bg: 'bgColor'
} ,
markupCatchAll: ( markupStack , key , value ) => {
var attr = {} ;
// /!\ Should be moved to string-kit once finished /!\
const parseMarkupRegexp = /\^\[([^\]]*)]|\^(.)|([^^]+)/g ;
misc.parseMarkup = ( str , options ) => {
var complex , markup , raw , match ,
base = options.markup ,
output = [] ;
parseMarkupRegexp.lastIndex = 0 ;
while ( ( match = parseMarkupRegexp.exec( str ) ) ) {
[ , complex , markup , raw ] = match ;
if ( complex ) {
var custom = {} ;
complex.split( ',' ).forEach( part => {
var [ k , v ] = part.split( ':' ) ;
if ( options.complexMarkupAliases[ k ] ) { k = options.complexMarkupAliases[ k ] ; }
custom[ k ] = v || true ;
} ) ;
output.push( { markup: custom } ) ;
if ( value === undefined ) {
if ( key[ 0 ] === '#' ) {
attr.color = key ;
}
else if ( CATCH_ALL_KEYWORDS[ key ] ) {
attr[ CATCH_ALL_KEYWORDS[ key ][ 0 ] ] = CATCH_ALL_KEYWORDS[ key ][ 1 ] ;
}
else {
// Fallback: it's a foreground color
attr.color = key ;
}
}
else if ( raw ) { output.push( raw ) ; }
else if ( markup === '^' ) { output.push( '^' ) ; }
else if ( options.shiftMarkup[ markup ] ) { base = options.shiftedMarkup[ options.shiftMarkup[ markup ] ] ; continue ; }
else if ( base[ markup ] ) { output.push( { markup: base[ markup ] } ) ; }
base = options.markup ;
markupStack.push( attr ) ;
return attr || {} ;
}
return output ;
} ;

@@ -498,83 +546,67 @@

const ANSI_CODES = {
'0': { reset: true } ,
const asciiSymbolName = {
' ': 'SPACE' ,
'!': 'EXCLAMATION' ,
'"': 'DOUBLE_QUOTE' ,
'#': 'HASH' ,
'$': 'DOLLAR' ,
'%': 'PERCENT' ,
'&': 'AMPERSAND' ,
"'": 'SINGLE_QUOTE' ,
'(': 'OPEN_PARENTHESIS' ,
')': 'CLOSE_PARENTHESIS' ,
'*': 'ASTERISK' ,
'+': 'PLUS' ,
',': 'COMMA' ,
'-': 'HYPHEN' ,
'.': 'DOT' ,
'/': 'SLASH' ,
':': 'COLON' ,
';': 'SEMICOLON' ,
'<': 'LESS_THAN' ,
'=': 'EQUAL' ,
'>': 'GREATER_THAN' ,
'?': 'QUESTION' ,
'@': 'AT' ,
'[': 'OPEN_BRACKET' ,
'\\': 'BACKSLASH' ,
']': 'CLOSE_BRACKET' ,
'^': 'CARET' ,
'_': 'UNDERSCORE' ,
'`': 'BACK_QUOTE' ,
'{': 'OPEN_BRACE' ,
'|': 'PIPE' ,
'}': 'CLOSE_BRACE' ,
'~': 'TILDE'
} ;
'1': { bold: true } ,
'2': { dim: true } ,
'22': { bold: false , dim: false } ,
'3': { italic: true } ,
'23': { italic: false } ,
'4': { underline: true } ,
'24': { underline: false } ,
'5': { blink: true } ,
'25': { blink: false } ,
'7': { inverse: true } ,
'27': { inverse: false } ,
'8': { hidden: true } ,
'28': { hidden: false } ,
'9': { strike: true } ,
'29': { strike: false } ,
// Non-control character name
exports.characterName = char => {
if ( asciiSymbolName[ char ] ) { return asciiSymbolName[ char ] ; }
return char.toUpperCase() ;
} ;
'30': { color: 0 } ,
'31': { color: 1 } ,
'32': { color: 2 } ,
'33': { color: 3 } ,
'34': { color: 4 } ,
'35': { color: 5 } ,
'36': { color: 6 } ,
'37': { color: 7 } ,
'39:': { defaultColor: true } ,
// Transform a Terminal-Kit Key code (like CTRL_C) to user-friendly/interface name (like Ctrl-C)
exports.keyToUserInterfaceName = key => {
if ( asciiSymbolName[ key ] ) { return asciiSymbolName[ key ] ; }
'90': { color: 8 } ,
'91': { color: 9 } ,
'92': { color: 10 } ,
'93': { color: 11 } ,
'94': { color: 12 } ,
'95': { color: 13 } ,
'96': { color: 14 } ,
'97': { color: 15 } ,
'40': { bgColor: 0 } ,
'41': { bgColor: 1 } ,
'42': { bgColor: 2 } ,
'43': { bgColor: 3 } ,
'44': { bgColor: 4 } ,
'45': { bgColor: 5 } ,
'46': { bgColor: 6 } ,
'47': { bgColor: 7 } ,
'49:': { bgDefaultColor: true } ,
'100': { bgColor: 8 } ,
'101': { bgColor: 9 } ,
'102': { bgColor: 10 } ,
'103': { bgColor: 11 } ,
'104': { bgColor: 12 } ,
'105': { bgColor: 13 } ,
'106': { bgColor: 14 } ,
'107': { bgColor: 15 }
return key.replace(
/([A-Za-z0-9])([A-Za-z0-9]*)|([_-]+)/g ,
( match , firstLetter , endOfWord , separator ) => {
if ( separator ) { return '-' ; }
return firstLetter.toUpperCase() + endOfWord.toLowerCase() ;
}
) ;
} ;
// /!\ Should be moved to string-kit once finished /!\
const parseAnsiRegexp = /\x1b\[([0-9;]+)m|(.[^\x1b]*)/g ;
misc.parseAnsi = str => {
var match , ansiCodes , raw , output = [] ;
parseAnsiRegexp.lastIndex = 0 ;
while ( ( match = parseAnsiRegexp.exec( str ) ) ) {
[ , ansiCodes , raw ] = match ;
if ( raw ) { output.push( raw ) ; }
else {
ansiCodes.split( /;/g ).forEach( ansiCode => {
if ( ANSI_CODES[ ansiCode ] ) { output.push( { markup: ANSI_CODES[ ansiCode ] } ) ; }
} ) ;
// Transform a user-friendly/interface name (like Ctrl-C) to a Terminal-Kit Key code (like CTRL_C)
exports.userInterfaceNameToKey = key => {
return key.replace(
/([A-Za-z0-9]+)|([_-]+)/g ,
( match , word , separator ) => {
if ( separator ) { return '_' ; }
return word.toUpperCase() ;
}
}
return output ;
) ;
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -217,4 +217,4 @@ The MIT License (MIT)

for ( j = 2 ; j >= -3 ; j -- ) {
if ( j > 0 ) {

@@ -238,3 +238,2 @@ lightnessMark = '+'.repeat( j ) ;

}
}

@@ -241,0 +240,0 @@ } ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -264,3 +264,3 @@ The MIT License (MIT)

ScreenBuffer.prototype.preserveMarkupFormat = misc.preserveMarkupFormat ;
ScreenBuffer.prototype.markupOptions = misc.markupOptions ;
ScreenBuffer.prototype.parseMarkup = string.markupMethod.bind( misc.markupOptions ) ;

@@ -276,3 +276,4 @@

* y: bypass this.cy
* markup: boolean or 'ansi', true if the text contains markup that should be interpreted, 'ansi' if it contains ansi code
* markup: boolean or 'ansi' or 'legacyAnsi', true if the text contains markup that should be interpreted,
'ansi' if it contains ansi code, 'legacyAnsi' is bold is bright fg and blink is bright bg
* attr: standard attributes

@@ -288,3 +289,3 @@ * resumeAttr: attr to resume to

ScreenBuffer.prototype.put = function( options , str , ... args ) {
var parser , startX , startY , x , y , dx , dy , baseAttr , attr , attrObject , wrap ;
var startX , startY , x , y , dx , dy , baseAttr , attr , attrObject , wrap ;

@@ -344,10 +345,7 @@ // Manage options

if ( args.length ) {
str = ! options.markup || options.markup === 'ansi' ? string.format( str , ... args ) :
this.preserveMarkupFormat( str , ... args ) ;
str = options.markup === true ? this.preserveMarkupFormat( str , ... args ) : string.format( str , ... args ) ;
}
parser = ! options.markup ? null :
options.markup === 'ansi' ? termkit.parseAnsi :
termkit.parseMarkup ;
// The processing of raw chunk of text

@@ -448,25 +446,33 @@ var processRaw = part => {

else {
attrObject = this.attr2object( attr ) ;
parser( str , this.markupOptions ).forEach( part => {
if ( typeof part === 'string' ) {
processRaw( part ) ;
}
else {
if ( part.markup.reset ) {
attr = part.markup.special ? this.DEFAULT_ATTR : baseAttr ;
attrObject = this.attr2object( attr ) ;
}
else {
Object.assign( attrObject , part.markup ) ;
const defaultAttrObject = this.attr2object( this.DEFAULT_ATTR ) ;
const baseAttrObject = this.attr2object( baseAttr ) ;
// Remove incompatible flags
if ( attrObject.defaultColor && attrObject.color ) { delete attrObject.defaultColor ; }
if ( attrObject.bgDefaultColor && attrObject.bgColor ) { delete attrObject.bgDefaultColor ; }
let legacyColor = false ;
let parts = null ;
attr = this.object2attr( attrObject ) ;
}
switch ( options.markup ) {
case 'ansi' :
parts = string.ansi.parse( str ) ;
break ;
case 'legacyAnsi' :
parts = string.ansi.parse( str ) ;
legacyColor = true ;
break ;
case true :
parts = this.parseMarkup( str ) ;
break ;
}
if ( part.markup.raw ) {
processRaw( part.markup.raw ) ;
}
parts.forEach( part => {
attrObject = Object.assign( {} , part.specialReset ? defaultAttrObject : baseAttrObject , part ) ;
delete attrObject.text ;
// Remove incompatible flags
if ( attrObject.defaultColor && attrObject.color ) { delete attrObject.defaultColor ; }
if ( attrObject.bgDefaultColor && attrObject.bgColor ) { delete attrObject.bgDefaultColor ; }
attr = this.object2attr( attrObject , undefined , legacyColor ) ;
if ( part.text ) {
processRaw( part.text ) ;
}

@@ -1409,4 +1415,4 @@ } ) ;

ScreenBuffer.object2attr = function( object , colorNameToIndex ) {
var attr = 0 ;
ScreenBuffer.object2attr = function( object , colorNameToIndex , legacyColor = false ) {
var attr = 0 , brightFg = false , brightBg = false ;

@@ -1416,2 +1422,18 @@ if ( ! object || typeof object !== 'object' ) { object = {} ; }

// Style part
if ( object.bold ) {
if ( legacyColor ) { brightFg = true ; }
else { attr |= BOLD ; }
}
if ( object.dim ) { attr |= DIM ; }
if ( object.italic ) { attr |= ITALIC ; }
if ( object.underline ) { attr |= UNDERLINE ; }
if ( object.blink ) {
if ( legacyColor ) { brightBg = true ; }
else { attr |= BLINK ; }
}
if ( object.inverse ) { attr |= INVERSE ; }
if ( object.hidden ) { attr |= HIDDEN ; }
if ( object.strike ) { attr |= STRIKE ; }
// Color part

@@ -1429,2 +1451,6 @@ if ( typeof object.color === 'string' ) {

object.color = Math.floor( object.color ) ;
if ( legacyColor && object.color <= 15 ) {
if ( brightFg && object.color <= 7 ) { object.color += 8 ; }
else if ( ! brightFg && object.color >= 8 ) { object.color -= 8 ; }
}
}

@@ -1446,2 +1472,6 @@

object.bgColor = Math.floor( object.bgColor ) ;
if ( legacyColor && object.bgColor <= 15 ) {
if ( brightBg && object.bgColor <= 7 ) { object.bgColor += 8 ; }
else if ( ! brightBg && object.bgColor >= 8 ) { object.bgColor -= 8 ; }
}
}

@@ -1455,12 +1485,2 @@

// Style part
if ( object.bold ) { attr |= BOLD ; }
if ( object.dim ) { attr |= DIM ; }
if ( object.italic ) { attr |= ITALIC ; }
if ( object.underline ) { attr |= UNDERLINE ; }
if ( object.blink ) { attr |= BLINK ; }
if ( object.inverse ) { attr |= INVERSE ; }
if ( object.hidden ) { attr |= HIDDEN ; }
if ( object.strike ) { attr |= STRIKE ; }
// Blending part

@@ -1476,4 +1496,4 @@ if ( object.transparency ) { attr |= TRANSPARENCY ; }

ScreenBuffer.prototype.object2attr = function( object ) {
return ScreenBuffer.object2attr( object , this.palette && this.palette.colorNameToIndex ) ;
ScreenBuffer.prototype.object2attr = function( object , colorNameToIndex = this.palette && this.palette.colorNameToIndex , legacyColor = false ) {
return ScreenBuffer.object2attr( object , colorNameToIndex , legacyColor ) ;
} ;

@@ -1564,5 +1584,4 @@

// Add the selection flag, i.e. the INVERSE flag
ScreenBuffer.attrSelect = ScreenBuffer.prototype.attrSelect = attr => attr | INVERSE ;
ScreenBuffer.attrUnselect = ScreenBuffer.prototype.attrUnselect = attr => attr & ~ INVERSE ;
// Used by TextBuffer for selection
ScreenBuffer.attrInverse = ScreenBuffer.prototype.attrInverse = attr => attr ^ INVERSE ;

@@ -1634,2 +1653,3 @@

ScreenBuffer.DEFAULT_ATTR = // <- used by TextBuffer
ScreenBuffer.prototype.DEFAULT_ATTR = ScreenBuffer.object2attr( { defaultColor: true , bgDefaultColor: true } ) ;

@@ -1636,0 +1656,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -32,2 +32,3 @@ The MIT License (MIT)

const ScreenBuffer = require( './ScreenBuffer.js' ) ;
const misc = require( './misc.js' ) ;

@@ -843,4 +844,11 @@ const fs = require( 'fs' ) ;

if ( object.color && typeof object.color === 'object' ) {
// Color part
// Color part
if ( typeof object.color === 'string' ) {
let color = misc.hexToRgba( object.color ) ;
attr[ BPOS_R ] = color.r ;
attr[ BPOS_G ] = color.g ;
attr[ BPOS_B ] = color.b ;
attr[ BPOS_A ] = color.a ;
}
else if ( object.color && typeof object.color === 'object' ) {
attr[ BPOS_R ] = + object.color.r || 0 ;

@@ -858,4 +866,11 @@ attr[ BPOS_G ] = + object.color.g || 0 ;

if ( object.bgColor && typeof object.bgColor === 'object' ) {
// Background color part
// Background color part
if ( typeof object.bgColor === 'string' ) {
let color = misc.hexToRgba( object.bgColor ) ;
attr[ BPOS_BG_R ] = color.r ;
attr[ BPOS_BG_G ] = color.g ;
attr[ BPOS_BG_B ] = color.b ;
attr[ BPOS_BG_A ] = color.a ;
}
else if ( object.bgColor && typeof object.bgColor === 'object' ) {
attr[ BPOS_BG_R ] = + object.bgColor.r || 0 ;

@@ -950,5 +965,4 @@ attr[ BPOS_BG_G ] = + object.bgColor.g || 0 ;

// Add the selection flag, i.e. the INVERSE flag
ScreenBufferHD.attrSelect = ScreenBufferHD.prototype.attrSelect = attr => { attr[ BPOS_STYLE ] |= INVERSE ; return attr ; } ;
ScreenBufferHD.attrUnselect = ScreenBufferHD.prototype.attrUnselect = attr => { attr[ BPOS_STYLE ] &= ~ INVERSE ; return attr ; } ;
// Used by TextBuffer for selection
ScreenBufferHD.attrInverse = ScreenBufferHD.prototype.attrInverse = attr => { attr[ BPOS_STYLE ] ^= INVERSE ; return attr ; } ;

@@ -1035,2 +1049,3 @@

ScreenBufferHD.DEFAULT_ATTR = // <- used by TextBuffer
ScreenBufferHD.prototype.DEFAULT_ATTR = ScreenBufferHD.object2attr( {

@@ -1037,0 +1052,0 @@ color: {

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -42,2 +42,3 @@ The MIT License (MIT)

password: '●' , // Currently: the same as blackCircle
ellispsis: '…' ,

@@ -103,2 +104,15 @@ forwardSingleQuote: '´' , // Altgr + ,

box: {
__fix__: object => ( {
vertical: object.vertical || ' ' ,
horizontal: object.horizontal || ' ' ,
topLeft: object.topLeft || ' ' ,
topRight: object.topRight || ' ' ,
bottomLeft: object.bottomLeft || ' ' ,
bottomRight: object.bottomRight || ' ' ,
topTee: object.topTee || ' ' ,
bottomTee: object.bottomTee || ' ' ,
leftTee: object.leftTee || ' ' ,
rightTee: object.rightTee || ' ' ,
cross: object.cross || ' '
} ) ,
plain: {

@@ -105,0 +119,0 @@ vertical: '█' ,

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -41,3 +41,3 @@ The MIT License (MIT)

LEFT: '\x1b[D' ,
DELETE: '\x7f' ,
BACKSPACE: '\x7f' ,
SHIFT_F1: '\x1b[1;2P' ,

@@ -44,0 +44,0 @@ SHIFT_F2: '\x1b[1;2Q' ,

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -645,2 +645,6 @@ The MIT License (MIT)

ALT_LEFT: '\x1b[1;3D' ,
ALT_SHIFT_UP: '\x1b[1;4A' ,
ALT_SHIFT_DOWN: '\x1b[1;4B' ,
ALT_SHIFT_RIGHT: '\x1b[1;4C' ,
ALT_SHIFT_LEFT: '\x1b[1;4D' ,
CTRL_UP: '\x1b[1;5A' ,

@@ -650,2 +654,6 @@ CTRL_DOWN: '\x1b[1;5B' ,

CTRL_LEFT: '\x1b[1;5D' ,
CTRL_SHIFT_UP: '\x1b[1;6A' ,
CTRL_SHIFT_DOWN: '\x1b[1;6B' ,
CTRL_SHIFT_RIGHT: '\x1b[1;6C' ,
CTRL_SHIFT_LEFT: '\x1b[1;6D' ,

@@ -652,0 +660,0 @@ //BACKSPACE: '\x7f' ,

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -42,3 +42,3 @@ The MIT License (MIT)

/*
Since there is a lot of hack with the Terminal instance creation, we can't use the 'new' operator at all...
Since there is a lot of hacks with the Terminal instance creation, we can't use the 'new' operator at all...
*/

@@ -99,2 +99,4 @@ function Terminal( ... args ) { return Terminal.create( ... args ) ; }

term.prependStdinChunk = null ;
term.metaKeyPrefix = null ;
term.metaKeyRemove = null ;

@@ -264,3 +266,2 @@ term.lock = {} ;

Object.keys( term.esc ).forEach( ( key ) => {
if ( ! term.esc[ key ] || typeof term.esc[ key ] !== 'object' ) {

@@ -406,5 +407,83 @@ console.error( "Bad escape sequence entry '" + key + "' using termconfig: '" + term.termconfigFile + "'." ) ;

}
} ,
dataMarkup: {
fg: ( markupStack , key , value ) => {
var str ;
if ( typeof value === 'string' && value[ 0 ] === '#' ) {
let hex = value.slice( 1 ) ;
if ( hex.length === 3 ) { hex = hex[ 0 ] + hex[ 0 ] + hex[ 1 ] + hex[ 1 ] + hex[ 2 ] + hex[ 2 ] ; }
let r = parseInt( hex.slice( 0 , 2 ) , 16 ) || 0 ;
let g = parseInt( hex.slice( 2 , 4 ) , 16 ) || 0 ;
let b = parseInt( hex.slice( 4 , 6 ) , 16 ) || 0 ;
str = term.optimized.color24bits( r , g , b ) ;
}
else {
str = term.str.color( value ) ;
}
markupStack.push( str ) ;
return str ;
} ,
bg: ( markupStack , key , value ) => {
var str ;
if ( typeof value === 'string' && value[ 0 ] === '#' ) {
let hex = value.slice( 1 ) ;
if ( hex.length === 3 ) { hex = hex[ 0 ] + hex[ 0 ] + hex[ 1 ] + hex[ 1 ] + hex[ 2 ] + hex[ 2 ] ; }
let r = parseInt( hex.slice( 0 , 2 ) , 16 ) || 0 ;
let g = parseInt( hex.slice( 2 , 4 ) , 16 ) || 0 ;
let b = parseInt( hex.slice( 4 , 6 ) , 16 ) || 0 ;
str = term.optimized.bgColor24bits( r , g , b ) ;
}
else {
str = term.str.bgColor( value ) ;
}
markupStack.push( str ) ;
return str ;
}
} ,
markupCatchAll: ( markupStack , key , value ) => {
term.optimized.bgColor24bits ;
var str = '' ;
if ( value === undefined ) {
if ( key[ 0 ] === '#' ) {
return term.formatConfig.dataMarkup.fg( markupStack , 'fg' , key ) ;
}
else if ( termkit.markupCatchAllKeywords[ key ] ) {
switch ( termkit.markupCatchAllKeywords[ key ][ 0 ] ) {
case 'color' :
return term.formatConfig.dataMarkup.fg( markupStack , 'fg' , termkit.markupCatchAllKeywords[ key ][ 1 ] ) ;
case 'bgColor' :
return term.formatConfig.dataMarkup.bg( markupStack , 'bg' , termkit.markupCatchAllKeywords[ key ][ 1 ] ) ;
case 'dim' :
str = term.str.dim() ;
break ;
case 'bold' :
str = term.str.bold() ;
break ;
case 'underline' :
str = term.str.underline() ;
break ;
case 'italic' :
str = term.str.italic() ;
break ;
case 'inverse' :
str = term.str.inverse() ;
break ;
}
}
}
markupStack.push( str ) ;
return str ;
}
} ;
// Aliases...
term.formatConfig.dataMarkup.color = term.formatConfig.dataMarkup.fgColor = term.formatConfig.dataMarkup.c = term.formatConfig.dataMarkup.fg ;
term.formatConfig.dataMarkup.bgColor = term.formatConfig.dataMarkup.bg ;
term.formatConfig.rawMarkupConfig = Object.create( term.formatConfig ) ;

@@ -525,3 +604,3 @@ term.formatConfig.rawMarkupConfig.startingMarkupReset = false ;

// CAUTION: 'options' MUST NOT BE OVERWRITTEN!
// It is binded at the function creation and contains function specificities!
// It is bound at the function creation and contains function specificities!
function applyEscape( options , ... args ) {

@@ -940,2 +1019,6 @@ var fn , newOptions , wrapOptions ;

}
else if ( ! this.isTTY ) {
// If it's not a TTY, we are probably piping to a file, in that case the size is virtually infinite
this.width = this.height = Infinity ;
}

@@ -1114,3 +1197,3 @@ this.emit( 'resize' , this.width , this.height ) ;

bytes = i ;
this.emit( 'key' , keymap.name , keymap.matches , { isCharacter: false , code: startBuffer } ) ;
this.emitKey( keymap.name , keymap.matches , { isCharacter: false , code: startBuffer } ) ;
}

@@ -1186,3 +1269,3 @@

this.emit( 'key' , char , [ char ] , { isCharacter: true , codepoint: codepoint , code: buffer } ) ;
this.emitKey( char , [ char ] , { isCharacter: true , codepoint: codepoint , code: buffer } ) ;
}

@@ -1192,3 +1275,3 @@ else {

char = String.fromCharCode( chunk[ index ] ) ;
this.emit( 'key' , char , [ char ] , { isCharacter: true , codepoint: chunk[ index ] , code: chunk[ index ] } ) ;
this.emitKey( char , [ char ] , { isCharacter: true , codepoint: chunk[ index ] , code: chunk[ index ] } ) ;
}

@@ -1209,2 +1292,41 @@

// Internal?
notChainable.emitKey = function( name , matches , data ) {
if ( this.metaKeyPrefix ) {
data.meta = this.metaKeyPrefix ;
data.isCharacter = false ;
if ( this.metaKeyRemove ) {
let regexp = new RegExp( '(^|_)' + this.metaKeyRemove + '_' ) ;
// We force using a match that contains the key to remove,
// e.g.: META + RETURN/CTRL_M would produce META_M instead of META_RETURN
if ( matches.length > 1 ) {
let index = matches.findIndex( oneMatch => oneMatch.match( regexp ) ) ;
regexp.lastIndex = 0 ;
if ( index >= 0 ) { name = matches[ index ] ; }
}
name = name.replace( regexp , '$1' ) ;
}
name = this.metaKeyPrefix + '_' + termkit.characterName( name ) ;
this.metaKeyPrefix = null ;
this.metaKeyRemove = null ;
}
this.emit( 'key' , name , matches , data ) ;
} ;
// TODOC
notChainable.setMetaKeyPrefix = function( prefix , remove ) {
this.metaKeyPrefix = prefix && typeof prefix === 'string' ? prefix : null ;
this.metaKeyRemove = remove && typeof remove === 'string' ? remove : null ;
} ;
/*

@@ -1237,3 +1359,3 @@ * options `false` or `Object` where:

var disable = () => {
// Very important: removing all listeners don't switch back to pause mode.
// Very important: removing all listeners doesn't switch back to pause mode.
// This is some nasty Node.js quirks (the documentation pleads for backward compatibility).

@@ -1240,0 +1362,0 @@ this.stdin.pause() ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -103,3 +103,3 @@ The MIT License (MIT)

function parseTermBuffer( bufPair , termName ) {
var i , j , getInt , intSize ,
var i , getInt , intSize ,
buf = bufPair.buf ,

@@ -106,0 +106,0 @@ offset = 0 ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,2 +31,12 @@ The MIT License (MIT)

const path = require( 'path' ) ;
if ( process.browser || require.cache[ path.join( __dirname , 'termkit-no-lazy-require.js' ) ] ) {
console.log( 'using termkit-no-lazy-require.js' ) ;
module.exports = require( './termkit-no-lazy-require.js' ) ;
return ;
}
const termkit = {} ;

@@ -90,2 +100,4 @@ module.exports = termkit ;

InlineInput: './document/InlineInput.js' ,
InlineFileInput: './document/InlineFileInput.js' ,
InlineMenu: './document/InlineMenu.js' ,
Form: './document/Form.js' ,

@@ -95,2 +107,3 @@ RowMenu: './document/RowMenu.js' ,

ColumnMenuMulti: './document/ColumnMenuMulti.js' ,
ColumnMenuMixed: './document/ColumnMenuMixed.js' ,
SelectList: './document/SelectList.js' ,

@@ -101,2 +114,3 @@ SelectListMulti: './document/SelectListMulti.js' ,

Layout: './document/Layout.js' ,
Border: './document/Border.js' ,
Window: './document/Window.js' ,

@@ -103,0 +117,0 @@

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,2 +31,4 @@ The MIT License (MIT)

const misc = require( './misc.js' ) ;
const fs = require( 'fs' ) ;

@@ -71,3 +73,3 @@ const string = require( 'string-kit' ) ;

this.tabWidth = options.tabWidth || 4 ;
this.tabWidth = + options.tabWidth || 4 ;
this.forceInBound = !! options.forceInBound ;

@@ -103,9 +105,13 @@

TextBuffer.prototype.parseMarkup = string.markupMethod.bind( misc.markupOptions ) ;
function Cell( char = ' ' , attr = null , misc = null ) {
this.char = char || ' ' ;
this.filler = char === null ;
// Special: if positive or 0, it's the width of the char, if -1 it's an anti-filler, if -2 it's a filler
function Cell( char = ' ' , special = 1 , attr = null , misc_ = null ) {
this.char = char ;
this.width = special >= 0 ? special : -special - 1 ;
this.filler = special < 0 ; // note: antiFiller ARE filler
this.attr = attr ;
this.misc = misc ;
this.misc = misc_ ;
}

@@ -128,2 +134,103 @@

// TODOC
TextBuffer.prototype.getLineText = function( y = this.cy ) {
if ( y >= this.buffer.length ) { return null ; }
if ( ! this.buffer[ y ] ) { this.buffer[ y ] = [] ; }
return string.unicode.fromCells( this.buffer[ y ] ) ;
} ;
// TODOC
// Get the indentation part of the line, return null if the line is empty (no char or no non-space char)
TextBuffer.prototype.getLineIndent = function( y = this.cy ) {
if ( ! this.buffer[ y ] ) { return null ; }
var x , xmin , xmax , cell ,
indent = '' ;
for ( x = 0 , xmax = this.buffer[ y ].length - 1 ; x <= xmax ; x ++ ) {
cell = this.buffer[ y ][ x ] ;
if ( ! cell.filler ) {
if ( cell.char === '\t' || cell.char === ' ' ) {
indent += cell.char ;
}
else if ( cell.char === '\n' ) {
return null ;
}
else {
return indent ;
}
}
}
return null ;
} ;
// TODOC
// Count characters in this line, excluding fillers
TextBuffer.prototype.getLineCharCount = function( y = this.cy ) {
if ( y >= this.buffer.length ) { return null ; }
if ( ! this.buffer[ y ] ) { this.buffer[ y ] = [] ; }
return this.getCellsCharCount( this.buffer[ y ] ) ;
} ;
// internal
TextBuffer.prototype.getCellsCharCount = function( cells ) {
var count = 0 ;
for ( let cell of cells ) {
if ( ! cell.filler ) { count ++ ; }
}
return count ;
} ;
// TODOC
// Remove spaces and tabs at the end of the line
TextBuffer.prototype.removeTrailingSpaces = function( y = this.cy , x = null , dry = false ) {
if ( y >= this.buffer.length ) { return '' ; }
if ( ! this.buffer[ y ] ) { this.buffer[ y ] = [] ; }
var line = this.buffer[ y ] ;
x = x ?? line.length - 1 ;
if ( x < 0 || x >= line.length ) { return '' ; }
var deletedStr = '' ,
hasNL = line[ x ].char === '\n' ;
if ( hasNL ) {
x -- ;
}
for ( ; x >= 0 ; x -- ) {
if ( line[ x ].filler ) { continue ; }
let char = line[ x ].char ;
if ( char === ' ' || char === '\t' ) {
deletedStr = char + deletedStr ;
}
else {
break ;
}
}
if ( deletedStr && ! dry ) {
line.splice( x + 1 , deletedStr.length ) ;
}
return deletedStr ;
} ;
// TODOC
// Get the text, but separate before the cursor and after the cursor

@@ -160,6 +267,10 @@ TextBuffer.prototype.getCursorSplittedText = function() {

var parser = ! hasMarkup ? null :
hasMarkup === 'ansi' ? termkit.parseAnsi :
termkit.parseMarkup ;
var legacyColor = false , parser = null ;
switch ( hasMarkup ) {
case 'ansi' : parser = string.ansi.parse ; break ;
case 'legacyAnsi' : parser = string.ansi.parse ; legacyColor = true ; break ;
case true : parser = this.parseMarkup ; break ;
}
if ( baseAttr === undefined ) { baseAttr = this.defaultAttr ; }

@@ -173,7 +284,7 @@ if ( typeof baseAttr === 'object' ) { baseAttr = this.object2attr( baseAttr ) ; }

var index = this.buffer.length ;
this.buffer[ index ] = this.lineToCells( line , parser , baseAttr , 0 ) ;
this.buffer[ index ] = this.lineToCells( line , parser , baseAttr , 0 , legacyColor ) ;
// /!\ Warning /!\ string.unicode.toCells() strips '\n', so we need to restore it at the end of the line
if ( line[ line.length - 1 ] === '\n' ) {
this.buffer[ index ].push( new Cell( '\n' , baseAttr ) ) ;
this.buffer[ index ].push( new Cell( '\n' , 1 , baseAttr ) ) ;
}

@@ -184,2 +295,4 @@

} ) ;
this.selectionRegion = null ;
} ;

@@ -190,37 +303,25 @@

// Internal, transform a line of text, with or without markup to cells...
TextBuffer.prototype.lineToCells = function( line , parser , baseAttr , offset = 0 ) {
var attr = baseAttr ,
attrObject , cells ;
TextBuffer.prototype.lineToCells = function( line , parser , baseAttr , offset = 0 , legacyColor = false ) {
if ( ! parser ) {
return string.unicode.toCells( Cell , line , this.tabWidth , offset , attr ) ;
return string.unicode.toCells( Cell , line , this.tabWidth , offset , baseAttr ) ;
}
// Reset attr at each end of line
attr = baseAttr ;
attrObject = this.ScreenBuffer.attr2object( attr ) ;
cells = [] ;
var attr , attrObject ,
cells = [] ;
parser( line , termkit.markupOptions ).forEach( part => {
if ( typeof part === 'string' ) {
cells.push( ... string.unicode.toCells( Cell , part , this.tabWidth , offset + cells.length , attr ) ) ;
return ;
}
const defaultAttrObject = this.ScreenBuffer.attr2object( this.ScreenBuffer.DEFAULT_ATTR ) ;
const baseAttrObject = this.ScreenBuffer.attr2object( baseAttr ) ;
if ( part.markup.reset ) {
attr = baseAttr ;
attrObject = this.ScreenBuffer.attr2object( attr ) ;
}
else {
Object.assign( attrObject , part.markup ) ;
parser( line ).forEach( part => {
attrObject = Object.assign( {} , part.specialReset ? defaultAttrObject : baseAttrObject , part ) ;
delete attrObject.text ;
// Remove incompatible flags
if ( attrObject.defaultColor && attrObject.color !== undefined ) { delete attrObject.defaultColor ; }
if ( attrObject.bgDefaultColor && attrObject.bgColor !== undefined ) { delete attrObject.bgDefaultColor ; }
// Remove incompatible flags
if ( attrObject.defaultColor && attrObject.color ) { delete attrObject.defaultColor ; }
if ( attrObject.bgDefaultColor && attrObject.bgColor ) { delete attrObject.bgDefaultColor ; }
attr = this.object2attr( attrObject ) ;
}
attr = this.object2attr( attrObject , undefined , legacyColor ) ;
if ( part.markup.raw ) {
cells.push( ... string.unicode.toCells( Cell , part.markup.raw , this.tabWidth , offset + cells.length , attr ) ) ;
if ( part.text ) {
cells.push( ... string.unicode.toCells( Cell , part.text , this.tabWidth , offset + cells.length , attr ) ) ;
}

@@ -262,7 +363,7 @@ } ) ;

// Cursor offset in the text-content (excluding fillers)
TextBuffer.prototype.getCursorOffset = function() {
// TODOC
TextBuffer.prototype.coordinateToOffset = function( px , py ) {
var x , y , line , offset = 0 ;
for ( y = 0 ; y < this.cy ; y ++ ) {
for ( y = 0 ; y < py ; y ++ ) {
line = this.buffer[ y ] ;

@@ -275,5 +376,5 @@ if ( ! line ) { continue ; }

line = this.buffer[ this.cy ] ;
line = this.buffer[ py ] ;
if ( line ) {
for ( x = 0 ; x < this.cx && x < line.length ; x ++ ) {
for ( x = 0 ; x < px && x < line.length ; x ++ ) {
if ( ! line[ x ].filler ) { offset ++ ; }

@@ -288,41 +389,46 @@ }

// Set the cursor position (cx,cy) depending on the offset in the text-content (excludind fillers)
TextBuffer.prototype.setCursorOffset = function( offset ) {
var line ;
// Cursor offset in the text-content (excluding fillers)
TextBuffer.prototype.getCursorOffset = function() {
return this.coordinateToOffset( this.cx , this.cy ) ;
} ;
//console.error( "Entering" , offset ) ;
this.cy = this.cx = 0 ;
if ( offset <= 0 ) { return ; }
while ( this.cy < this.buffer.length ) {
this.cx = 0 ;
line = this.buffer[ this.cy ] ;
//console.error( " iter cy" , offset , this.cy , this.cx , "---" , line.length ) ;
// TODOC
TextBuffer.prototype.offsetToCoordinate = function( offset ) {
var line ,
x = 0 ,
y = 0 ;
if ( offset < 0 ) { return ; }
while ( y < this.buffer.length ) {
x = 0 ;
line = this.buffer[ y ] ;
//console.error( " iter cy" , offset , y , x , "---" , line.length ) ;
if ( ! line ) { continue ; }
while ( this.cx < line.length ) {
//console.error( " iter cx" , offset , this.cy , this.cx ) ;
if ( line[ this.cx ].filler ) {
this.cx ++ ;
}
else {
offset -- ;
this.cx ++ ;
while ( x < line.length ) {
//console.error( " iter cx" , offset , y , x ) ;
if ( ! line[ x ].filler ) {
if ( offset <= 0 ) {
if ( this.cx === line.length && line[ line.length - 1 ].char === '\n' ) {
if ( x === line.length && line[ line.length - 1 ].char === '\n' ) {
//console.error( " Exit with \\n" ) ;
this.cx = 0 ;
this.cy ++ ;
x = 0 ;
y ++ ;
}
//console.error( "Exit" , this.cy , this.cx ) ;
return ;
//console.error( "Exit" , y , x ) ;
return { x , y } ;
}
offset -- ;
}
x ++ ;
}
this.cy ++ ;
y ++ ;
}
//console.error( "End of input" , offset , this.cy , this.cx ) ;
//console.error( "End of input" , offset , y , x ) ;
} ;

@@ -332,10 +438,37 @@

// Set the cursor position (cx,cy) depending on the offset in the text-content (excluding fillers)
TextBuffer.prototype.setCursorOffset = function( offset ) {
var coord = this.offsetToCoordinate() ;
if ( ! coord ) { return ; }
this.cx = coord.x ;
this.cy = coord.y ;
} ;
// TODOC
TextBuffer.prototype.setTabWidth = function( tabWidth ) {
this.tabWidth = + tabWidth || 4 ;
this.reTab() ;
} ;
// TODOC
TextBuffer.prototype.reTab = function() {
for ( let y = 0 ; y < this.buffer.length ; y ++ ) {
this.reTabLine( 0 , y ) ;
}
} ;
// Recompute tabs
TextBuffer.prototype.reTabLine = function( startAt = 0 ) {
TextBuffer.prototype.reTabLine = function( startAt = 0 , y = this.cy ) {
var length , cell , index , fillSize , input , output ,
linePosition = startAt ;
if ( this.buffer[ this.cy ] === undefined ) { this.buffer[ this.cy ] = [] ; }
if ( this.buffer[ y ] === undefined ) { this.buffer[ y ] = [] ; }
input = this.buffer[ this.cy ] ;
input = this.buffer[ y ] ;
output = input.slice( 0 , startAt ) ;

@@ -353,5 +486,3 @@ length = input.length ;

while ( fillSize -- ) {
// /!\ First or second?
//output.push( new Cell( null ) ) ;
output.push( new Cell( null , cell.attr , cell.misc ) ) ;
output.push( new Cell( ' ' , -2 , cell.attr , cell.misc ) ) ;
}

@@ -368,3 +499,3 @@

this.buffer[ this.cy ] = output ;
this.buffer[ y ] = output ;
} ;

@@ -625,3 +756,3 @@

if ( ! this.buffer[ y ][ x ] ) { this.buffer[ y ][ x ] = new Cell( ' ' , attr ) ; }
if ( ! this.buffer[ y ][ x ] ) { this.buffer[ y ][ x ] = new Cell( ' ' , 1 , attr ) ; }
else { this.buffer[ y ][ x ].attr = attr ; }

@@ -666,8 +797,21 @@ } ;

TextBuffer.prototype.isInSelection = function( x = this.cx , y = this.cy ) {
if ( ! this.selectionRegion ) { return false ; }
return this.isInRegion( this.selectionRegion , x , y ) ;
} ;
TextBuffer.prototype.isInRegion = function( region , x = this.cx , y = this.cy ) {
return (
y >= region.ymin && y <= region.ymax
&& ( y !== region.ymin || x >= region.xmin )
&& ( y !== region.ymax || x <= region.xmax )
) ;
} ;
TextBuffer.prototype.setSelectionRegion = function( region ) {
if ( this.selectionRegion ) {
// Start by unhilighting existing selection
this.hilightSelection( false ) ;
}
else {
if ( ! this.selectionRegion ) {
this.selectionRegion = {} ;

@@ -677,4 +821,8 @@ }

if ( region.xmin !== undefined && region.ymin !== undefined ) {
if ( region.xmin < 0 ) { region.xmin = 0 ; }
if ( region.ymin < 0 ) { region.ymin = 0 ; }
this.selectionRegion.xmin = region.xmin ;
this.selectionRegion.ymin = region.ymin ;
this.selectionRegion.cellMin = this.buffer[ region.ymin ]?.[ region.xmin ] ?? null ;
}

@@ -685,5 +833,17 @@

this.selectionRegion.ymax = region.ymax ;
this.selectionRegion.cellMax = this.buffer[ region.ymax ]?.[ region.xmax ] ?? null ;
}
} ;
this.hilightSelection() ;
// TODOC
TextBuffer.prototype.startOfSelection = function() {
if ( ! this.selectionRegion ) {
this.selectionRegion = {} ;
}
this.selectionRegion.xmin = this.cx ;
this.selectionRegion.ymin = this.cy ;
this.selectionRegion.cellMin = this.buffer[ this.cy ]?.[ this.cx ] ?? null ;
} ;

@@ -693,8 +853,19 @@

TextBuffer.prototype.resetSelectionRegion = function() {
if ( ! this.selectionRegion ) { return ; }
// TODOC
TextBuffer.prototype.endOfSelection = function() {
var coord = this.oneStepBackward() ;
// Start by unhilighting existing selection
this.hilightSelection( false ) ;
this.selectionRegion = null ;
if ( ! this.selectionRegion ) {
this.selectionRegion = {} ;
}
if ( ! coord ) {
// Start of the file
this.selectionRegion = null ;
return ;
}
this.selectionRegion.xmax = coord.x ;
this.selectionRegion.ymax = coord.y ;
this.selectionRegion.cellMax = this.buffer[ coord.y ]?.[ coord.x ] ?? null ;
} ;

@@ -704,25 +875,76 @@

// Internal
TextBuffer.prototype.hilightSelection = function( turnOn = true ) {
var x , y , xmin , xmax , ymax ,
region = this.selectionRegion ;
// TODOC
// Reset the region by scanning for the starting and ending cell
// If cursorCell is set, set cursor position to this cell
TextBuffer.prototype.updateSelectionFromCells = function( cursorCell = null ) {
if ( ! this.selectionRegion ) { return ; }
if ( ! this.selectionRegion.cellMin || ! this.selectionRegion.cellMax ) {
this.selectionRegion = null ;
return ;
}
if ( ! region || region.xmin === undefined || region.ymin === undefined || region.xmax === undefined || region.ymax === undefined ) {
var xmin , xmax , ymin , ymax ;
for ( let y = 0 ; y < this.buffer.length ; y ++ ) {
let currentLine = this.buffer[ y ] ;
if ( ! currentLine ) { continue ; }
for ( let x = 0 ; x < currentLine.length ; x ++ ) {
if ( currentLine[ x ] === this.selectionRegion.cellMin ) {
xmin = x ;
ymin = y ;
}
if ( currentLine[ x ] === this.selectionRegion.cellMax ) {
xmax = x ;
ymax = y ;
}
if ( cursorCell && currentLine[ x ] === cursorCell ) {
this.cx = x ;
this.cy = y ;
}
}
}
if ( ymin === undefined || ymax === undefined ) {
this.selectionRegion = null ;
return ;
}
ymax = Math.min( region.ymax , this.buffer.length - 1 ) ;
this.selectionRegion.xmin = xmin ;
this.selectionRegion.xmax = xmax ;
this.selectionRegion.ymin = ymin ;
this.selectionRegion.ymax = ymax ;
} ;
for ( y = region.ymin ; y <= ymax ; y ++ ) {
if ( ! this.buffer[ y ] ) { this.buffer[ y ] = [] ; }
xmin = y === region.ymin ? region.xmin : 0 ;
xmax = y === region.ymax ? Math.min( region.xmax , this.buffer[ y ].length - 1 ) : this.buffer[ y ].length - 1 ;
for ( x = xmin ; x <= xmax ; x ++ ) {
this.buffer[ y ][ x ].attr = turnOn ?
this.ScreenBuffer.attrSelect( this.buffer[ y ][ x ].attr ) :
this.ScreenBuffer.attrUnselect( this.buffer[ y ][ x ].attr ) ;
// TODOC
// Return a Cell instance that is at the cursor location, or null if none
TextBuffer.prototype.getCursorCell = function() {
return this.buffer[ this.cy ]?.[ this.cx ] ?? null ;
} ;
// TODOC
// Return true if found, else return false
TextBuffer.prototype.updateCursorFromCell = function( cursorCell ) {
if ( ! cursorCell ) { return false ; }
for ( let y = 0 ; y < this.buffer.length ; y ++ ) {
let currentLine = this.buffer[ y ] ;
if ( ! currentLine ) { continue ; }
for ( let x = 0 ; x < currentLine.length ; x ++ ) {
if ( cursorCell && currentLine[ x ] === cursorCell ) {
this.cx = x ;
this.cy = y ;
return true ;
}
}
}
return false ;
} ;

@@ -732,9 +954,23 @@

TextBuffer.prototype.resetSelectionRegion = function() {
if ( ! this.selectionRegion ) { return ; }
this.selectionRegion = null ;
} ;
TextBuffer.prototype.getSelectionText = function() {
return this.getRegionText( this.selectionRegion ) ;
} ;
// TODOC
TextBuffer.prototype.getRegionText = function( region , structured = false ) {
var x , y , xmin , xmax , ymax , cell ,
str = '' ,
region = this.selectionRegion ;
count = 0 ,
str = '' ;
if ( ! region || region.xmin === undefined || region.ymin === undefined || region.xmax === undefined || region.ymax === undefined ) {
return str ;
return ;
}

@@ -752,6 +988,10 @@

cell = this.buffer[ y ][ x ] ;
str += cell.filler ? '' : cell.char ;
if ( ! cell.filler ) {
str += cell.char ;
count ++ ;
}
}
}
if ( structured ) { return { string: str , count } ; }
return str ;

@@ -762,2 +1002,76 @@ } ;

// TODOC
TextBuffer.prototype.deleteSelection = function( getDeleted = false ) {
if ( ! this.selectionRegion ) { return ; }
var region = this.selectionRegion ;
this.selectionRegion = null ; // unselect now
return this.deleteRegion( region , getDeleted ) ;
} ;
// TODOC
// Delete current line
TextBuffer.prototype.deleteRegion = function( region , getDeleted = false ) {
var x , y , xmin , xmax , ymax , currentLine , tabIndex , deleted , cursorCell ;
if ( ! region || region.xmin === undefined || region.ymin === undefined || region.xmax === undefined || region.ymax === undefined ) {
return ;
}
cursorCell = this.buffer[ this.cy ]?.[ this.cx ] ?? null ;
if ( getDeleted ) {
deleted = this.getRegionText( region , true ) ;
}
ymax = Math.min( region.ymax , this.buffer.length - 1 ) ;
y = region.ymin ;
currentLine = this.buffer[ y ] ;
if ( y === ymax ) {
if ( ! this.buffer[ y ] ) { return deleted ; }
xmin = region.xmin ;
xmax = Math.min( region.xmax , currentLine.length - 1 ) ;
currentLine.splice( xmin , xmax - xmin + 1 ) ;
}
else {
let lastLine = this.buffer[ ymax ] ;
// First, remove next lines
this.buffer.splice( y + 1 , ymax - y ) ;
xmin = region.xmin ;
currentLine.splice( xmin , currentLine.length - xmin ) ;
if ( lastLine && lastLine.length ) {
xmax = Math.min( region.xmax , lastLine.length - 1 ) ;
lastLine.splice( 0 , xmax + 1 ) ;
if ( lastLine.length ) {
currentLine.splice( currentLine.length , 0 , ... lastLine ) ;
}
}
}
if ( y < this.buffer.length - 1 && ( ! currentLine.length || currentLine[ currentLine.length - 1 ].char !== '\n' ) ) {
this.joinLine( true , y ) ;
}
tabIndex = this.indexOfCharInLine( currentLine , '\t' , region.xmin ) ;
if ( tabIndex !== -1 ) { this.reTabLine( tabIndex , y ) ; }
if ( this.selectionRegion ) {
this.updateSelectionFromCells( cursorCell ) ;
}
else if ( cursorCell ) {
this.updateCursorFromCell( cursorCell ) ;
}
return deleted ;
} ;
// Misc data are lazily created

@@ -781,3 +1095,3 @@ TextBuffer.prototype.getMisc = function() {

TextBuffer.prototype.iterate = function( options , callback ) {
var x , y , yMax , offset = 0 , length ;
var x , y , yMax , cell , lastNonFillerCell , offset = 0 , length ;

@@ -792,16 +1106,24 @@ if ( typeof options === 'function' ) { callback = options ; options = {} ; }

length = this.buffer[ y ].length ;
lastNonFillerCell = null ;
for ( x = 0 ; x < length ; x ++ ) {
if ( this.buffer[ y ][ x ].filler ) { continue ; }
cell = this.buffer[ y ][ x ] ;
if ( cell.filler ) {
if ( options.fillerCopyAttr && lastNonFillerCell ) {
cell.attr = lastNonFillerCell.attr ;
}
}
else {
callback( {
offset: offset ,
x: x ,
y: y ,
text: cell.char ,
attr: cell.attr ,
misc: cell.misc
} ) ;
callback( {
offset: offset ,
x: x ,
y: y ,
text: this.buffer[ y ][ x ].char ,
attr: this.buffer[ y ][ x ].attr ,
misc: this.buffer[ y ][ x ].misc
} ) ;
offset ++ ;
offset ++ ;
lastNonFillerCell = cell ;
}
}

@@ -827,5 +1149,15 @@ }

// Move to the left to the leading cell of a full-width char
TextBuffer.prototype.moveToLeadingFullWidth = function() {
var currentLine = this.buffer[ this.cy ] ;
while ( this.cx && currentLine?.[ this.cx ]?.filler && currentLine?.[ this.cx ]?.width === 0 ) { this.cx -- ; }
} ;
TextBuffer.prototype.moveTo = function( x , y ) {
this.cx = x >= 0 ? x : 0 ;
this.cy = y >= 0 ? y : 0 ;
if ( this.forceInBound ) { this.moveInBound( true ) ; }
this.moveToLeadingFullWidth() ;
} ;

@@ -844,2 +1176,3 @@

if ( this.forceInBound ) { this.moveInBound( true ) ; }
this.moveToLeadingFullWidth() ;
} ;

@@ -852,2 +1185,3 @@

if ( this.forceInBound ) { this.moveInBound( true ) ; }
this.moveToLeadingFullWidth() ;
} ;

@@ -860,2 +1194,3 @@

if ( this.forceInBound ) { this.moveInBound( true ) ; }
this.moveToLeadingFullWidth() ;
} ;

@@ -867,2 +1202,6 @@

this.cx ++ ;
var currentLine = this.buffer[ this.cy ] ;
while ( currentLine?.[ this.cx ]?.filler && currentLine?.[ this.cx ]?.width === 0 ) { this.cx ++ ; }
if ( this.forceInBound ) { this.moveInBound( true ) ; }

@@ -895,3 +1234,11 @@ } ;

if ( ! currentLine[ this.cx ] || ( ! currentLine[ this.cx ].filler && ( ! testFn || testFn( currentLine[ this.cx ].char ) ) ) ) { break ; }
if (
! currentLine[ this.cx ]
|| (
! currentLine[ this.cx ].filler
&& ( ! testFn || testFn( currentLine[ this.cx ].char , this.cx , this.cy ) )
)
) {
break ;
}
}

@@ -929,3 +1276,3 @@

|| (
( ! currentLine[ this.cx ].filler || currentLine[ this.cx ].char !== '\n' )
! currentLine[ this.cx ].filler
&& ( ! testFn || testFn( currentLine[ this.cx ].char ) )

@@ -962,3 +1309,2 @@ )

return false ;
} ) ;

@@ -1049,5 +1395,6 @@ } ;

TextBuffer.prototype.insert = function( text , hasMarkup , attr ) {
var lines , index , length , parser ;
var lines , index , length ,
count = 0 ;
if ( ! text ) { return ; }
if ( ! text ) { return count ; }

@@ -1059,6 +1406,10 @@ if ( typeof hasMarkup !== 'boolean' && typeof hasMarkup !== 'string' ) {

parser = ! hasMarkup ? null :
hasMarkup === 'ansi' ? termkit.parseAnsi :
termkit.parseMarkup ;
var legacyColor = false , parser = null ;
switch ( hasMarkup ) {
case 'ansi' : parser = string.ansi.parse ; break ;
case 'legacyAnsi' : parser = string.ansi.parse ; legacyColor = true ; break ;
case true : parser = this.parseMarkup ; break ;
}
lines = text.split( '\n' ) ;

@@ -1072,8 +1423,13 @@ length = lines.length ;

this.inlineInsert( lines[ 0 ] , parser , attr ) ;
count += this.inlineInsert( lines[ 0 ] , parser , attr ) ;
for ( index = 1 ; index < length ; index ++ ) {
this.newLine( true ) ;
this.inlineInsert( lines[ index ] , parser , attr ) ;
count ++ ;
count += this.inlineInsert( lines[ index ] , parser , attr , legacyColor ) ;
}
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return count ;
} ;

@@ -1099,4 +1455,5 @@

// Insert inline chars (no control chars)
TextBuffer.prototype.inlineInsert = function( text , parser , attr ) {
var currentLine , currentLineLength , hasNL , nlCell , tabIndex , fillSize , cells ;
TextBuffer.prototype.inlineInsert = function( text , parser , attr , legacyColor = false ) {
var currentLine , currentLineLength , hasNL , nlCell , tabIndex , fillSize , cells , cellsCharCount ,
count = 0 ;

@@ -1107,3 +1464,4 @@ this.moveForward( undefined , true ) ; // just skip filler char

//cells = string.unicode.toCells( Cell , text , this.tabWidth , this.cx , attr ) ;
cells = this.lineToCells( text , parser , attr , this.cx ) ;
cells = this.lineToCells( text , parser , attr , this.cx , legacyColor ) ;
cellsCharCount = this.getCellsCharCount( cells ) ;

@@ -1114,3 +1472,4 @@ // Is this a new line?

while ( this.buffer.length < this.cy ) {
this.buffer.push( [ new Cell( '\n' , this.defaultAttr ) ] ) ;
this.buffer.push( [ new Cell( '\n' , 1 , this.defaultAttr ) ] ) ;
count ++ ;
}

@@ -1125,3 +1484,4 @@

) {
this.buffer[ this.cy - 1 ].push( new Cell( '\n' , this.defaultAttr ) ) ;
this.buffer[ this.cy - 1 ].push( new Cell( '\n' , 1 , this.defaultAttr ) ) ;
count ++ ;
}

@@ -1139,6 +1499,8 @@

if ( hasNL ) {
currentLine.splice( currentLineLength - 1 , 0 , new Cell( ' ' , this.defaultAttr ) , ... cells ) ;
currentLine.splice( currentLineLength - 1 , 0 , new Cell( ' ' , 1 , this.defaultAttr ) , ... cells ) ;
count += 1 + cellsCharCount ;
}
else {
currentLine.push( ... cells ) ;
count += cellsCharCount ;
}

@@ -1148,2 +1510,3 @@ }

currentLine.splice( this.cx , 0 , ... cells ) ;
count += cellsCharCount ;
}

@@ -1154,9 +1517,21 @@ // this.cx > currentLineLength

nlCell = currentLine.pop() ;
while ( fillSize -- ) { currentLine.push( new Cell( ' ' , this.defaultAttr ) ) ; }
while ( fillSize -- ) {
currentLine.push( new Cell( ' ' , 1 , this.defaultAttr ) ) ;
count ++ ;
}
currentLine.push( ... cells , nlCell ) ;
count += cellsCharCount ;
}
else {
fillSize = this.cx - currentLineLength ;
while ( fillSize -- ) { currentLine.push( new Cell( ' ' , this.defaultAttr ) ) ; }
while ( fillSize -- ) {
currentLine.push( new Cell( ' ' , 1 , this.defaultAttr ) ) ;
count ++ ;
}
currentLine.push( ... cells ) ;
count += cellsCharCount ;
}

@@ -1172,2 +1547,4 @@

if ( tabIndex !== -1 ) { this.reTabLine( tabIndex ) ; }
return count ;
} ;

@@ -1191,7 +1568,6 @@

// /!\ Bug with tabs and count > 1 !!! /!\
// Delete chars
TextBuffer.prototype.delete = function( count ) {
var currentLine , inlineCount ;
TextBuffer.prototype.delete = function( count , getDeleted = false ) {
var currentLine , inlineCount , fillerCount , hasNL , removedCells ,
deleted = getDeleted ? { string: '' , count: 0 } : undefined ;

@@ -1212,5 +1588,8 @@ if ( count === undefined ) { count = 1 ; }

// If we are already at the end of the buffer...
if ( this.cy >= this.buffer.length ||
( this.cy === this.buffer.length - 1 && this.cx >= currentLine.length ) ) {
return ;
if (
this.cy >= this.buffer.length ||
( this.cy === this.buffer.length - 1 && this.cx >= currentLine.length )
) {
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return deleted ;
}

@@ -1224,11 +1603,17 @@

// Compute inline delete
//inlineCount = Math.min( count , currentLine.length - this.cx ) ;
inlineCount = this.countInlineForward( count ) ;
hasNL = currentLine[ currentLine.length - 1 ]?.char === '\n' ;
fillerCount = this.countInlineForwardFiller( count ) ;
inlineCount = Math.min( count + fillerCount , currentLine.length - hasNL - this.cx ) ;
// Apply inline delete
if ( inlineCount > 0 ) {
currentLine.splice( this.cx , inlineCount ) ;
removedCells = currentLine.splice( this.cx , inlineCount ) ;
if ( getDeleted ) {
removedCells = removedCells.filter( cell => ! cell.filler ) ;
deleted.string += removedCells.map( cell => cell.char ).join( '' ) ;
deleted.count += removedCells.length ;
}
}
count -= inlineCount ;
count -= inlineCount - fillerCount ;
}

@@ -1238,3 +1623,9 @@ }

if ( count > 0 ) {
if ( this.joinLine( true ) ) { count -- ; }
if ( this.joinLine( true ) ) {
count -- ;
if ( getDeleted ) {
deleted.string += '\n' ;
deleted.count ++ ;
}
}
}

@@ -1250,2 +1641,6 @@ }

this.reTabLine() ; // Do it every time, before finding a better way to do it
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return deleted ;
} ;

@@ -1255,7 +1650,7 @@

// /!\ Bug with tabs and count > 1 !!! /!\
// Delete backward chars
TextBuffer.prototype.backDelete = function( count ) {
var currentLine , inlineCount , tabIndex ;
TextBuffer.prototype.backDelete = function( count , getDeleted = false ) {
//console.error( ">>> backDelete:" , count ) ;
var currentLine , inlineCount , fillerCount , tabIndex , removedCells ,
deleted = getDeleted ? { string: '' , count: 0 } : undefined ;

@@ -1276,3 +1671,6 @@ if ( count === undefined ) { count = 1 ; }

// If we are already at the begining of the buffer...
if ( this.cy === 0 && this.cx === 0 ) { return ; }
if ( this.cy === 0 && this.cx === 0 ) {
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return deleted ;
}

@@ -1292,11 +1690,18 @@ if ( currentLine ) {

// Compute inline delete
inlineCount = this.countInlineBackward( count ) ;
fillerCount = this.countInlineBackwardFiller( count ) ;
inlineCount = Math.min( count + fillerCount , this.cx ) ;
//console.error( "inlineCount:" , inlineCount , fillerCount , this.cx , this.cx - inlineCount ) ;
// Apply inline delete
if ( inlineCount > 0 ) {
currentLine.splice( this.cx - inlineCount , inlineCount ) ;
removedCells = currentLine.splice( this.cx - inlineCount , inlineCount ) ;
if ( getDeleted ) {
removedCells = removedCells.filter( cell => ! cell.filler ) ;
deleted.string = removedCells.map( cell => cell.char ).join( '' ) + deleted.string ;
deleted.count += removedCells.length ;
}
this.cx -= inlineCount ;
}
count -= inlineCount ;
count -= inlineCount - fillerCount ;
}

@@ -1307,3 +1712,9 @@

this.cx = currentLine ? currentLine.length : 0 ;
if ( this.joinLine( true ) ) { count -- ; }
if ( this.joinLine( true ) ) {
count -- ;
if ( getDeleted ) {
deleted.string = '\n' + deleted.string ;
deleted.count ++ ;
}
}
}

@@ -1319,2 +1730,6 @@ }

this.reTabLine( tabIndex ) ; // Do it every time, before finding a better way to do it
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return deleted ;
} ;

@@ -1325,10 +1740,18 @@

// Fix a backward counter, get an additional count for each null char encountered
TextBuffer.prototype.countInlineBackward = function( count ) {
var c , x ;
TextBuffer.prototype.countInlineBackwardFiller = function( count ) {
var x , cell ,
filler = 0 ;
for ( x = this.cx - 1 , c = 0 ; x >= 0 && c < count ; x -- , c ++ ) {
if ( this.buffer[ this.cy ][ x ] && this.buffer[ this.cy ][ x ].filler ) { count ++ ; }
for ( x = this.cx - 1 ; x >= 0 && count ; x -- ) {
cell = this.buffer[ this.cy ][ x ] ;
if ( cell && cell.filler ) {
filler ++ ;
}
else {
count -- ;
}
}
return c ;
return filler ;
} ;

@@ -1339,10 +1762,19 @@

// Fix a forward counter, get an additional count for each null char encountered
TextBuffer.prototype.countInlineForward = function( count ) {
var c , x , xMax = this.buffer[ this.cy ].length ;
TextBuffer.prototype.countInlineForwardFiller = function( count ) {
var x , cell ,
xMax = this.buffer[ this.cy ].length ,
filler = 0 ;
for ( x = this.cx , c = 0 ; x < xMax && c < count ; x ++ , c ++ ) {
if ( this.buffer[ this.cy ][ x + 1 ] && this.buffer[ this.cy ][ x + 1 ].filler ) { count ++ ; }
for ( x = this.cx ; x < xMax && count ; x ++ ) {
cell = this.buffer[ this.cy ][ x + 1 ] ;
if ( cell && cell.filler ) {
filler ++ ;
}
else {
count -- ;
}
}
return c ;
return filler ;
} ;

@@ -1368,3 +1800,3 @@

currentLine.push( new Cell( '\n' , this.defaultAttr ) ) ;
currentLine.push( new Cell( '\n' , 1 , this.defaultAttr ) ) ;

@@ -1383,2 +1815,4 @@ this.buffer.splice( this.cy + 1 , 0 , nextLine ) ;

if ( tabIndex !== -1 ) { this.reTabLine( tabIndex ) ; }
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
}

@@ -1389,12 +1823,19 @@ } ;

TextBuffer.prototype.joinLine = function( internalCall ) {
var tabIndex , currentLine ,
// If y is specified, we are not joining on current cursor
TextBuffer.prototype.joinLine = function( internalCall , y ) {
var tabIndex , currentLine , x ,
updateCursor = false ,
hasDeleted = false ;
if ( y === undefined ) {
y = this.cy ;
updateCursor = true ;
}
if ( ! internalCall && this.forceInBound ) { this.moveInBound() ; }
if ( this.buffer[ this.cy ] === undefined ) { this.buffer[ this.cy ] = [] ; }
if ( this.buffer[ this.cy + 1 ] === undefined ) { this.buffer[ this.cy + 1 ] = [] ; }
if ( this.buffer[ y ] === undefined ) { this.buffer[ y ] = [] ; }
if ( this.buffer[ y + 1 ] === undefined ) { this.buffer[ y + 1 ] = [] ; }
currentLine = this.buffer[ this.cy ] ;
currentLine = this.buffer[ y ] ;

@@ -1407,7 +1848,8 @@ if ( currentLine.length && currentLine[ currentLine.length - 1 ].char === '\n' ) {

this.cx = currentLine.length ;
x = currentLine.length ;
if ( updateCursor ) { this.cx = x ; }
currentLine.splice( currentLine.length , 0 , ... this.buffer[ this.cy + 1 ] ) ;
currentLine.splice( currentLine.length , 0 , ... this.buffer[ y + 1 ] ) ;
this.buffer.splice( this.cy + 1 , 1 ) ;
this.buffer.splice( y + 1 , 1 ) ;

@@ -1419,4 +1861,6 @@ // Patch tab if needed

tabIndex = this.indexOfCharInLine( currentLine , '\t' , this.cx ) ;
if ( tabIndex !== -1 ) { this.reTabLine( tabIndex ) ; }
tabIndex = this.indexOfCharInLine( currentLine , '\t' , x ) ;
if ( tabIndex !== -1 ) { this.reTabLine( tabIndex , y ) ; }
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
}

@@ -1429,2 +1873,108 @@

// TODOC
// Delete current line
TextBuffer.prototype.deleteLine = function( getDeleted = false ) {
var currentLine , inlineCount , fillerCount , hasNL , removedCells , deleted ;
if ( this.forceInBound ) { this.moveInBound() ; }
if ( this.cy >= this.buffer.length ) { return ; }
if ( getDeleted ) {
deleted = {
count: this.getLineCharCount() ,
string: this.getLineText()
} ;
}
this.buffer.splice( this.cy , 1 ) ;
if ( this.selectionRegion ) { this.updateSelectionFromCells() ; }
return deleted ;
} ;
// TODOC
// Return a region where the searchString is found
TextBuffer.prototype.findNext = function( searchString , startPosition , reverse ) {
var index , startAt , endAt ,
text = this.getText() ,
// /!\ another function MUST BE used once unicode composition will be supported
// It is meant to produce the exact same cell size
size = string.unicode.toArray( searchString ).length ;
reverse = !! reverse ;
if ( reverse ) {
startPosition = startPosition ? startPosition - size : text.length - size ;
}
else {
startPosition = startPosition ?? 0 ;
}
index = reverse ? text.lastIndexOf( searchString , startPosition ) :
text.indexOf( searchString , startPosition ) ;
if ( index === -1 ) { return ; }
startAt = this.offsetToCoordinate( index ) ;
endAt = this.offsetToCoordinate( index + size - 1 ) ;
return {
xmin: startAt.x ,
ymin: startAt.y ,
xmax: endAt.x ,
ymax: endAt.y
} ;
} ;
// TODOC
TextBuffer.prototype.findPrevious = function( searchString , startPosition ) {
return this.findNext( searchString , startPosition , true ) ;
} ;
// TODOC
// Return a region where the regexp match, the region also have a 'match' property with the result of the regexp#exec().
// Can't be reversed due to how regexp works, except by searching for all match beforehand
TextBuffer.prototype.regexpFindNext = function( regexp , startPosition = 0 ) {
var index , startAt , endAt , size , match ,
text = this.getText() ;
if ( typeof regexp === 'string' ) {
regexp = new RegExp( regexp , 'gu' ) ;
}
else {
// Force global and unicode
regexp.global = true ;
regexp.unicode = true ;
}
regexp.lastIndex = startPosition ;
match = regexp.exec( text ) ;
if ( ! match ) { return ; }
// /!\ another function MUST BE used once unicode composition will be supported
// It is meant to produce the exact same cell size
size = string.unicode.toArray( match[ 0 ] ).length ;
startAt = this.offsetToCoordinate( match.index ) ;
endAt = this.offsetToCoordinate( match.index + size - 1 ) ;
return {
xmin: startAt.x ,
ymin: startAt.y ,
xmax: endAt.x ,
ymax: endAt.y ,
match
} ;
} ;
/*

@@ -1505,2 +2055,3 @@ A TextBuffer can only draw to a ScreenBuffer.

voidAttr: this.voidAttr ,
inverseRegion: this.selectionRegion ,
writeAttr:

@@ -1535,3 +2086,6 @@ this.ScreenBuffer === termkit.ScreenBuffer ?

//console.error( "blitter line" , p.srcY ) ;
var srcRShift , srcX , srcXmax , srcExistingXmax , dstOffset , cells , cell , attr , charCode ;
var srcRShift , srcX , srcXmax , srcExistingXmax , dstOffset , cells , cell , attr , char , charCode ,
invRegion = p.context.inverseRegion ,
invXmin = Infinity ,
invXmax = -Infinity ;

@@ -1554,2 +2108,7 @@ //if ( ! global.deb ) { global.deb = [] ; }

if ( invRegion && p.srcY >= invRegion.ymin && p.srcY <= invRegion.ymax ) {
invXmin = p.srcY === invRegion.ymin ? invRegion.xmin : -Infinity ;
invXmax = p.srcY === invRegion.ymax ? invRegion.xmax : Infinity ;
}
// Write existing cells

@@ -1560,17 +2119,23 @@ for ( ; srcX <= srcExistingXmax ; srcX ++ , dstOffset += this.ScreenBuffer.prototype.ITEM_SIZE ) {

// Write the attributes
p.context.writeAttr( p.context.dstBuffer , cell.attr , dstOffset ) ;
if ( p.context.forceChar ) {
// Write the forced character (i.e. hidden)
p.context.dstBuffer.write( p.context.forceChar , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
// Use a forced character (i.e. hidden)
attr = cell.attr ;
char = p.context.forceChar ;
}
else if ( ( charCode = cell.char.charCodeAt( 0 ) ) < 0x20 || charCode === 0x7f ) {
// Replace the control char by a white space
p.context.dstBuffer.write( ' ' , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
}
else {
// Write the character
p.context.dstBuffer.write( cell.char , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
attr =
cell.width === 2 ? cell.attr | this.ScreenBuffer.prototype.LEADING_FULLWIDTH :
cell.width === 0 ? cell.attr | this.ScreenBuffer.prototype.TRAILING_FULLWIDTH :
cell.attr ;
char =
( ( charCode = cell.char.charCodeAt( 0 ) ) < 0x20 || charCode === 0x7f ) ? ' ' :
cell.char ;
}
if ( srcX >= invXmin && srcX <= invXmax ) { attr = this.ScreenBuffer.attrInverse( attr ) ; }
// Write the attributes
p.context.writeAttr( p.context.dstBuffer , attr , dstOffset ) ;
// Write the char
p.context.dstBuffer.write( char , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
}

@@ -1594,13 +2159,14 @@ }

attr =
cell.width === 2 ? cell.attr | this.ScreenBuffer.prototype.LEADING_FULLWIDTH :
cell.width === 0 ? cell.attr | this.ScreenBuffer.prototype.TRAILING_FULLWIDTH :
cell.attr ;
char =
( ( charCode = cell.char.charCodeAt( 0 ) ) < 0x20 || charCode === 0x7f ) ? ' ' :
cell.char ;
// Write the attributes
p.context.writeAttr( p.context.dstBuffer , cell.attr , dstOffset ) ;
if ( ( charCode = cell.char.charCodeAt( 0 ) ) < 0x20 || charCode === 0x7f ) {
// Replace the control char by a white space
p.context.dstBuffer.write( ' ' , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
}
else {
// Write the character
p.context.dstBuffer.write( cell.char , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
}
p.context.writeAttr( p.context.dstBuffer , attr , dstOffset ) ;
// Write the char
p.context.dstBuffer.write( char , dstOffset + this.ScreenBuffer.prototype.ATTR_SIZE , this.ScreenBuffer.prototype.CHAR_SIZE ) ;
}

@@ -1628,12 +2194,21 @@ }

// Naive loading
TextBuffer.prototype.load = function( path , callback ) {
// Using callback is DEPRECATED.
TextBuffer.prototype.load = async function( path , callback ) {
var content ;
this.buffer[ 0 ] = [] ;
this.buffer.length = 1 ;
// Naive file loading, optimization are for later
fs.readFile( path , ( error , data ) => {
if ( error ) { callback( error ) ; return ; }
this.setText( data.toString() ) ;
callback() ;
} ) ;
// Naive file loading, should be optimized later
try {
content = await fs.promises.readFile( path ) ;
}
catch ( error ) {
if ( callback ) { callback( error ) ; return ; }
throw error ;
}
this.setText( content.toString() ) ;
if ( callback ) { callback() ; return ; }
} ;

@@ -1644,8 +2219,14 @@

// Naive saving
TextBuffer.prototype.save = function( path , callback ) {
// Using callback is DEPRECATED.
TextBuffer.prototype.save = async function( path , callback ) {
// Naive file saving, optimization are for later
fs.writeFile( path , this.getText() , ( error ) => {
if ( error ) { callback( error ) ; return ; }
callback() ;
} ) ;
try {
await fs.promises.writeFile( path , this.getText() ) ;
}
catch ( error ) {
if ( callback ) { callback( error ) ; return ; }
throw error ;
}
if ( callback ) { callback() ; return ; }
} ;

@@ -1655,4 +2236,10 @@

TextBuffer.prototype.object2attr = function( attrObject ) {
return this.ScreenBuffer.object2attr( attrObject , this.palette && this.palette.colorNameToIndex ) ;
/* Utilities */
TextBuffer.prototype.object2attr = function( attrObject , colorNameToIndex = this.palette?.colorNameToIndex , legacyColor = false ) {
return this.ScreenBuffer.object2attr( attrObject , colorNameToIndex , legacyColor ) ;
} ;

@@ -1662,4 +2249,20 @@

// TODOC
// A small utility function that returns the coordinate one step backward, if needed it point to the end of the previous line
TextBuffer.prototype.oneStepBackward = function( x = this.cx , y = this.cy ) {
x -- ;
if ( x < 0 ) {
y -- ;
if ( y < 0 ) { return null ; }
x = this.buffer[ y ].length - 1 ;
}
return { x , y } ;
} ;
/* API for the text-machine module */

@@ -1674,5 +2277,5 @@

this.iterate( { finalCall: true } , data => {
data.textBuffer = this ;
this.stateMachine.pushEvent( data.text , data ) ;
this.iterate( { finalCall: true , fillerCopyAttr: true } , context => {
context.textBuffer = this ;
this.stateMachine.pushEvent( context.text , context ) ;
} ) ;

@@ -1689,3 +2292,3 @@ } ;

TextMachineApi.style = ( context , style ) => {
if ( context.x === null ) { return ; } // This is a newline or end of buffer character, there is no style to apply here
if ( ! context || context.x === null ) { return ; } // This is a newline or end of buffer character, there is no style to apply here
if ( ! style.code ) { style.code = context.textBuffer.ScreenBuffer.object2attr( style ) ; } // cache it now

@@ -1698,22 +2301,11 @@

TextMachineApi.startingStyle = ( context , style ) => {
if ( ! context.startingContext || context.startingContext.x === null ) { return ; }
if ( ! style.code ) { style.code = context.textBuffer.ScreenBuffer.object2attr( style ) ; } // cache it now
TextMachineApi.blockStyle = function( startingContext , endingContext , style ) {
if ( ! startingContext || ! endingContext || startingContext.x === null || endingContext.x === null ) { return ; }
if ( ! style.code ) { style.code = startingContext.textBuffer.ScreenBuffer.object2attr( style ) ; } // cache it now
context.textBuffer.setAttrCodeAt( style.code , context.startingContext.x , context.startingContext.y ) ;
} ;
TextMachineApi.openingStyle = TextMachineApi.startingStyle ;
TextMachineApi.blockStyle = function( context , style ) {
if ( context.x === null || ! context.startingContext || context.startingContext.x === null ) { return ; }
if ( ! style.code ) { style.code = context.textBuffer.ScreenBuffer.object2attr( style ) ; } // cache it now
context.textBuffer.setAttrCodeRegion( style.code , {
xmin: context.startingContext.x ,
xmax: context.x ,
ymin: context.startingContext.y ,
ymax: context.y
startingContext.textBuffer.setAttrCodeRegion( style.code , {
xmin: startingContext.x ,
xmax: endingContext.x ,
ymin: startingContext.y ,
ymax: endingContext.y
} ) ;

@@ -1724,10 +2316,10 @@ } ;

TextMachineApi.hint = function( context , hints ) {
var misc ;
TextMachineApi.hint = function( context , buffer , hints ) {
if ( ! context || context.x === null || context.y === null ) { return ; }
if ( hints[ context.buffer ] ) {
misc = context.textBuffer.getMiscAt( context.x , context.y ) ;
if ( misc ) { misc.hint = hints[ context.buffer ] ; }
if ( hints[ buffer ] ) {
let misc_ = context.textBuffer.getMiscAt( context.x , context.y ) ;
if ( misc_ ) { misc_.hint = hints[ buffer ] ; }
}
} ;
/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -31,3 +31,2 @@ The MIT License (MIT)

const termkit = require( '../termkit.js' ) ;
const ScreenBuffer = require( '../ScreenBuffer.js' ) ;

@@ -34,0 +33,0 @@ const Rect = require( '../Rect.js' ) ;

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

/*
Terminal Kit
Copyright (c) 2009 - 2021 Cédric Ronvel
Copyright (c) 2009 - 2022 Cédric Ronvel

@@ -6,0 +6,0 @@ The MIT License (MIT)

{
"name": "terminal-kit",
"version": "1.49.4",
"version": "3.0.1",
"description": "256 colors, keys and mouse, input field, progress bars, screen buffer (including 32-bit composition and image loading), text buffer, and many more... Whether you just need colors and styles, build a simple interactive command line tool or a complexe terminal app: this is the absolute terminal lib for Node.js!",

@@ -10,13 +10,13 @@ "main": "lib/termkit.js",

"engines": {
"node": ">=10.0.0"
"node": ">=16.13.0"
},
"dependencies": {
"@cronvel/get-pixels": "^3.4.0",
"chroma-js": "^2.1.0",
"@cronvel/get-pixels": "^3.4.1",
"chroma-js": "^2.4.2",
"lazyness": "^1.2.0",
"ndarray": "^1.0.19",
"nextgen-events": "^1.3.4",
"seventh": "^0.7.40",
"string-kit": "^0.11.9",
"tree-kit": "^0.7.0"
"nextgen-events": "^1.5.3",
"seventh": "^0.9.2",
"string-kit": "^0.17.10",
"tree-kit": "^0.8.1"
},

@@ -66,3 +66,3 @@ "scripts": {

2009,
2021
2022
],

@@ -69,0 +69,0 @@ "owner": "Cédric Ronvel"

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc