Skip to content

Commit 9c3bb24

Browse files
committed
feat: add multiline editing
Signed-off-by: Snehil Shah <snehilshah.989@gmail.com>
1 parent b4c12b7 commit 9c3bb24

File tree

5 files changed

+450
-13
lines changed

5 files changed

+450
-13
lines changed

lib/node_modules/@stdlib/repl/lib/completer_preview.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ setNonEnumerableReadOnly( PreviewCompleter.prototype, 'onKeypress', function onK
246246
* @type {Function}
247247
* @param {string} data - input data
248248
* @param {(Object|void)} key - key object
249-
* @returns {void}
249+
* @returns {boolean} boolean indicating whether the preview was auto-completed
250250
*/
251251
setNonEnumerableReadOnly( PreviewCompleter.prototype, 'beforeKeypress', function beforeKeypress( data, key ) {
252252
if ( !this._enabled ) {
@@ -273,7 +273,9 @@ setNonEnumerableReadOnly( PreviewCompleter.prototype, 'beforeKeypress', function
273273
debug( 'Completion preview accepted. Performing auto-completion...' );
274274
this._rli.write( this._preview );
275275
this._preview = '';
276+
return true;
276277
}
278+
return false;
277279
});
278280

279281

lib/node_modules/@stdlib/repl/lib/main.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ var inputPrompt = require( './input_prompt.js' );
6363
var OutputStream = require( './output_stream.js' );
6464
var processLine = require( './process_line.js' );
6565
var completerFactory = require( './completer.js' );
66+
var MultilineHandler = require( './multiline_handler.js' );
6667
var PreviewCompleter = require( './completer_preview.js' );
6768
var AutoCloser = require( './auto_close_pairs.js' );
6869
var SyntaxHighlighter = require( './syntax_highlighter.js' );
@@ -241,6 +242,9 @@ function REPL( options ) {
241242
setNonEnumerable( this, '_multiline', {} );
242243
setNonEnumerable( this._multiline, 'active', false );
243244
setNonEnumerable( this._multiline, 'mode', 'incomplete_expression' );
245+
setNonEnumerable( this._multiline, 'line', 0 );
246+
setNonEnumerable( this._multiline, 'lines', [] );
247+
setNonEnumerable( this._multiline, 'buffer', '' );
244248

245249
// Initialize an internal flag indicating whether the REPL has been closed:
246250
setNonEnumerable( this, '_closed', false );
@@ -273,6 +277,9 @@ function REPL( options ) {
273277
'completer': this._completer
274278
}));
275279

280+
// Initialize a multiline handler:
281+
setNonEnumerableReadOnly( this, '_multilineHandler', new MultilineHandler( this, this._rli._ttyWrite ) );
282+
276283
// Create a new auto-closer:
277284
setNonEnumerableReadOnly( this, '_autoCloser', new AutoCloser( this._rli, this._settings.autoClosePairs, this._settings.autoDeletePairs ) );
278285

@@ -337,12 +344,20 @@ function REPL( options ) {
337344
* @param {(Object|void)} key - key object
338345
*/
339346
function beforeKeypress( data, key ) {
347+
var completed;
348+
340349
if ( self._ostream.isPaging ) {
341350
self._ostream.beforeKeypress( data, key );
342351
return;
343352
}
344353
self._autoCloser.beforeKeypress( data, key );
345-
self._previewCompleter.beforeKeypress( data, key );
354+
completed = self._previewCompleter.beforeKeypress( data, key );
355+
356+
// If completion was auto-completed, don't trigger multiline keybindings to avoid double operations...
357+
if ( !completed && self._multiline.active ) {
358+
self._multilineHandler.beforeKeypress( data, key );
359+
return;
360+
}
346361
self._ttyWrite.call( self._rli, data, key );
347362
}
348363

@@ -366,6 +381,7 @@ function REPL( options ) {
366381
if ( autoClosed ) {
367382
self._previewCompleter.clear();
368383
}
384+
self._multilineHandler.onKeypress( data, key );
369385
self._syntaxHighlighter.onKeypress();
370386
self._previewCompleter.onKeypress( data, key );
371387
}
@@ -508,6 +524,19 @@ setNonEnumerableReadOnly( REPL.prototype, '_prompt', function prompt() {
508524
return inputPrompt( this._inputPrompt, this._count );
509525
});
510526

527+
/**
528+
* Returns the height of the current input.
529+
*
530+
* @private
531+
* @name _inputHeight
532+
* @memberof REPL.prototype
533+
* @type {Function}
534+
* @returns {number} input rows
535+
*/
536+
setNonEnumerableReadOnly( REPL.prototype, '_inputHeight', function inputHeight() {
537+
return this._multiline.lines.length;
538+
});
539+
511540
/**
512541
* Returns the REPL viewport.
513542
*

0 commit comments

Comments
 (0)