From 6ac071053a9c8c77d796875c0e84871d6e71f75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Thu, 17 Sep 2015 14:44:22 +0200 Subject: Fix handling of "enter" in the console: the current line must be processed in its entirety, not split at the cursor. --- js/codeq/console.js | 107 +++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/js/codeq/console.js b/js/codeq/console.js index 9331bc1..d49cd19 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -418,6 +418,12 @@ return result; }, + scrollCursorIntoView = function () { + var dh = jqContent.height() - jqElt.height(); + if (dh > 0) + jqElt.scrollTop(dh); + }, + // the handler object that is returned handler = { 'setLineBuffered': function () { lineBuffered = true; }, @@ -729,10 +735,8 @@ handleInput = function (chars) { var isPastedFromClipboard = clipboardPasteInProgress || !aKeyIsDown, - newLines = chars.split('\n'), - N = newLines.length, - lastLineIndex = N - 1, - i, promise; + cookedChars = chars, // the default + cookedPromise, cookedLines, lastCookedLineIndex, i; if (inputDisabled || internallyDisabled) { // flatly ignore @@ -741,69 +745,70 @@ } internallyDisabled = true; - promise = Q(); + cookedPromise = Q(); - for (i = 0; i < N; i++) { - promise = promise - .then((function (newLine, lineIndex) {return function () { - var cookedChars = lineIndex < lastLineIndex ? newLine + '\n' : newLine, // default - thisRow = currentRow, - leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, - dh; - - // first cook the input - if (typeof handler.onKeypress === 'function') { - // only invoke the handler if the newLine is not an empty string, otherwise cookedChars = '' - try { - cookedChars = cookedChars && handler.onKeypress(cookedChars, isPastedFromClipboard); - } - catch (e) { - codeq.log.error('Error during invocation of terminal onKeypress: ' + e, e); - } - } + // first cook the input + if (typeof handler.onKeypress === 'function') { + // only invoke the handler if the newLine is not an empty string, otherwise cookedChars = '' + try { + cookedChars = cookedChars && handler.onKeypress(cookedChars, isPastedFromClipboard); + } + catch (e) { + codeq.log.error('Error during invocation of terminal onKeypress: ' + e, e); + } + } - if (!cookedChars) { - // nothing to append - return; - } + if (typeof cookedChars !== 'string') cookedLines = ['']; + else cookedLines = cookedChars.split('\n'); + lastCookedLineIndex = cookedLines.length - 1; + + // now serve the cooking + for (i = 0; i <= lastCookedLineIndex; i++) { + cookedPromise = cookedPromise + .then(scrollCursorIntoView) // scroll to bottom on input + .then((function (cookedLine, cookedLineIndex) {return function () { + var thisRow = currentRow, + leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0; + + if (cookedLine) handler.insertAtCursor(cookedLine, 'input'); // append what we have to the display + if (cookedLineIndex < lastCookedLineIndex) { + // press on "enter" must be simulated -> jump to the start of the next line, which is first added + currentRow++; + currentCol = 0; + handler.insertRow(currentRow, '', 'input', true); + handler.reflow(currentRow - 1); // the previous line must be rendered without a cursor, and the new line must be rendered completely + } - // now serve the cooking - handler.insertAtCursor(cookedChars, 'input'); // append what we have to the display - // scroll to bottom on input - dh = jqContent.height() - jqElt.height(); - if (dh > 0) - jqElt.scrollTop(dh); - - if (typeof handler.onInput === 'function') { // now tell the owner what we've done - if (lineBuffered) { - if (thisRow < currentRow) { - // in line-buffered mode emit each line separately, except for the last (current) line + if (typeof handler.onInput === 'function') { // now tell the owner what we've done + if (lineBuffered) { + if (thisRow < currentRow) { + // in line-buffered mode emit each line separately, except for the last (current) line + try { + return handler.onInput(lines[thisRow].content.substring(leftmost)); + } + catch (e) { + codeq.log.error('Error while invoking terminal onInput: ' + e, e); + } + } + } + else if (cookedLine) { try { - return handler.onInput(lines[thisRow].content.substring(leftmost)); + return handler.onInput(cookedLine); } catch (e) { codeq.log.error('Error while invoking terminal onInput: ' + e, e); } } } - else if (cookedChars) { - try { - return handler.onInput(cookedChars); - } - catch (e) { - codeq.log.error('Error while invoking terminal onInput: ' + e, e); - } - } - } - - };})(newLines[i], i)) + };})(cookedLines[i], i)) .fail(function (e) { codeq.log.error('Error in handleInput loop: ' + e, e); }); } - promise.fin(function () { + cookedPromise.fin(function () { internallyDisabled = false; + scrollCursorIntoView(); }).done(); clipboardPasteInProgress = false; -- cgit v1.2.1