From 3df482a0fcca2f11cce51fc072e6a4dbc861c2a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Fri, 18 Sep 2015 16:36:21 +0200 Subject: Implement console history and enable it with python problems. --- js/codeq/console.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++--- js/codeq/python.js | 3 ++- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/js/codeq/console.js b/js/codeq/console.js index 57d5a07..55e9909 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -10,8 +10,8 @@ '000': { 'ArrowLeft': function () { this.moveLeft(); return false; }, 'ArrowRight': function () { this.moveRight(); return false; }, - 'ArrowUp': noop, - 'ArrowDown': noop, + 'ArrowUp': function () { this.showPreviousHistory(); return false; }, + 'ArrowDown': function () { this.showNextHistory(); return false; }, 'Backspace': function () { this.deleteCharacterLeft(); return false; }, 'Delete': function () { this.deleteCharacterRight(); return false; }, 'End': function () { this.moveToEndOfLine(); return false; }, @@ -168,6 +168,10 @@ jqInput = $(''), // for receiving keypresses, clipboard content inputDisabled = false, // whether to ignore input lineBuffered = true, // whether we are line-buffered or not buffered + autoHistory = (options && options.autoHistory) || false, // whether to auto-decide what goes into the history buffer + history = [], // the list of entered lines, it is only appended + currentHistory = [], // the list of entered lines, some possibly modified (it is copied from history on each new line editing) + currentHistoryIndex = -1, renderSpan = function (lineDescriptor, startCol, length) { var jqLine = lineDescriptor.jqLine, @@ -431,6 +435,20 @@ jqElt.scrollTop(dh); }, + stashCurrentHistory = function () { + var leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, + lineDescriptor = lines[currentRow], + line = lineDescriptor.content.substring(leftmost); + if (currentHistoryIndex < 0) { + currentHistoryIndex = currentHistory.length; + currentHistory.push(line); + } + else { + currentHistory[currentHistoryIndex] = line; + } + return lineDescriptor; + }, + // the handler object that is returned handler = { 'setLineBuffered': function () { lineBuffered = true; }, @@ -735,6 +753,46 @@ jqElt.empty(); jqElt = null; options = null; + }, + + 'addHistory': function (line) { + history.push(line); + }, + + 'currentInput': function () { + var leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0; + return lines[currentRow].content.substring(leftmost); + }, + + 'resetCurrentHistory': function () { + var i; + currentHistory.length = 0; + for (i = 0; i < history.length; i++) currentHistory.push(history[i]); + currentHistoryIndex = -1; + }, + + 'showPreviousHistory': function () { + var leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, + lineDescriptor = stashCurrentHistory(); + if (currentHistoryIndex > 0) { + currentHistoryIndex--; + lineDescriptor.content = lineDescriptor.content.substring(0, leftmost) + currentHistory[currentHistoryIndex]; + currentCol = lineDescriptor.content.length; + lineDescriptor.classNames = mergeClasses(classesBetween(lineDescriptor.classNames, 0, leftmost), makeClassDescriptor('input', leftmost, currentCol - leftmost)); + renderLine(lineDescriptor); + } + }, + + 'showNextHistory': function () { + var leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, + lineDescriptor = stashCurrentHistory(); + if (currentHistoryIndex < (currentHistory.length - 1)) { + currentHistoryIndex++; + lineDescriptor.content = lineDescriptor.content.substring(0, leftmost) + currentHistory[currentHistoryIndex]; + currentCol = lineDescriptor.content.length; + lineDescriptor.classNames = mergeClasses(classesBetween(lineDescriptor.classNames, 0, leftmost), makeClassDescriptor('input', leftmost, currentCol - leftmost)); + renderLine(lineDescriptor); + } } }, @@ -775,7 +833,8 @@ .then(scrollCursorIntoView) // scroll to bottom on input .then((function (cookedLine, cookedLineIndex) {return function () { var thisRow = currentRow, - leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0; + leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, + line; if (cookedLine) handler.insertAtCursor(cookedLine, 'input'); // append what we have to the display if (cookedLineIndex < lastCookedLineIndex) { @@ -791,7 +850,10 @@ 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)); + line = lines[thisRow].content.substring(leftmost); + if (autoHistory) handler.addHistory(line); // auto-history works only in line-buffered mode + handler.resetCurrentHistory(); + return handler.onInput(line); } catch (e) { codeq.log.error('Error while invoking terminal onInput: ' + e, e); diff --git a/js/codeq/python.js b/js/codeq/python.js index a8d4c95..c5f7df6 100644 --- a/js/codeq/python.js +++ b/js/codeq/python.js @@ -225,7 +225,8 @@ var makePythonTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { var terminal = codeq.makeConsole(jqConsole, { - 'greeting': 'CodeQ Python terminal proxy' + 'greeting': 'CodeQ Python terminal proxy', + 'autoHistory': true }), tcs = function terminalCommandSuccess (data) { if (data.code !== 0) { -- cgit v1.2.1