From 6bb35042ef6fb19d9af5ee874de9da2816cbc5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Tue, 15 Sep 2015 18:47:26 +0200 Subject: Augmenting the console: - implemented the support of the leftmostCol, the column from which the editing is allowed, - the onInput() handler can return a Promise, which is then waited on to be resolved before further input is allowed, - pasted multi-line content is split into lines, and processed line-by-line as if a single line was pasted multiple times. --- js/codeq/comms.js | 4 +- js/codeq/console.js | 120 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 75 insertions(+), 49 deletions(-) (limited to 'js') diff --git a/js/codeq/comms.js b/js/codeq/comms.js index de6f918..db9b7b5 100644 --- a/js/codeq/comms.js +++ b/js/codeq/comms.js @@ -86,13 +86,13 @@ event = m.event; if (typeof event !== 'string') { - codeq.log.warn('Incoming message without a TID and with no event name, dropping it on the floor: ' + data); + codeq.log.info('Incoming message without a TID and with no event name, dropping it on the floor: ' + data); return; } handlers = requestHandlers[event]; if (!handlers) { - codeq.log.warn('Incoming event message cannot be handled: no handler registered for ' + event); + codeq.log.info('Incoming event message cannot be handled: no handler registered for ' + event); return; } diff --git a/js/codeq/console.js b/js/codeq/console.js index ddf4ce6..41aae40 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -263,11 +263,12 @@ handler = { 'setLineBuffered': function () { lineBuffered = true; }, 'setNotBuffered': function () { lineBuffered = false; }, - 'onInput': false, // the caller should assign a function here, that takes input as parameter + 'onInput': false, // the caller should assign a function here, that takes input as parameter, and optionally returns a promise which is then waited to be resolved before further input is accepted 'onKeypress': false, // same, but it takes a keycode, and returns a keycode 'inputEnable': function () { inputDisabled = false; }, 'inputDisable': function () { inputDisabled = true; }, 'keyMaps': {}, // will be filled in later + 'leftmostCol': 0, // the column from where editing is possible; it is not possible to delete or change a character to the left of this column 'reflow': function () { var startRow, endRow, i, lineDescriptor; @@ -463,7 +464,8 @@ }, 'moveLeft': function () { - if (currentCol > 0) { + var leftmost = typeof this.leftmostCol === 'number' && this.leftmostCol || 0; + if (currentCol > leftmost) { currentCol--; renderLine(lines[currentRow]); } @@ -479,8 +481,9 @@ 'deleteCharacterLeft': function () { var lineDescriptor = lines[currentRow], - content = lineDescriptor.content; - if ((currentCol > 0) && (currentCol <= content.length)) { + content = lineDescriptor.content, + leftmost = typeof this.leftmostCol === 'number' && this.leftmostCol || 0; + if ((currentCol > leftmost) && (currentCol <= content.length)) { currentCol--; lineDescriptor.content = content.substring(0, currentCol) + content.substring(currentCol + 1); renderLine(lineDescriptor); @@ -547,65 +550,88 @@ } }, + internallyDisabled = false, + handleInput = function (chars) { - var cookedChars = chars, // default - startingRow = currentRow, - dh, i; + var isPastedFromClipboard = clipboardPasteInProgress || !aKeyIsDown, + newLines = chars.split('\n'), + N = newLines.length, + lastLineIndex = N - 1, + i, promise; - if (inputDisabled) { + if (inputDisabled || internallyDisabled) { // flatly ignore clipboardPasteInProgress = false; return; } - // first cook the input - if (typeof handler.onKeypress === 'function') { - try { - cookedChars = handler.onKeypress(chars, clipboardPasteInProgress || !aKeyIsDown); - } - catch (e) { - // TODO: log error - } - } + internallyDisabled = true; + promise = Q(); - if (!cookedChars) { - // nothing to append - clipboardPasteInProgress = false; - return; - } + 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 this.leftmostCol === 'number' && this.leftmostCol || 0, + dh; - // now serve the cooking - handler.insertAtCursor(cookedChars, 'input'); // append what we have to the display - if (typeof handler.onInput === 'function') { // now tell the owner what we've done - if (lineBuffered) { - if (currentRow !== startingRow) { - // in line-buffered mode emit each line separately, except for the last (current) line - for (i = startingRow; i < lines.length; i++) { + // first cook the input + if (typeof handler.onKeypress === 'function') { + // only invoke the handler if the newLine is not an empty string, otherwise cookedChars = '' try { - handler.onInput(lines[i].content); + cookedChars = cookedChars && handler.onKeypress(cookedChars, isPastedFromClipboard); } catch (e) { - // TODO: log error + codeq.log.error('Error during invocation of terminal onKeypress: ' + e, e); } } - } - } - else { - try { - handler.onInput(cookedChars); - } - catch (e) { - // TODO: log error - } - } + + if (!cookedChars) { + // nothing to append + return; + } + + // 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 + try { + return handler.onInput(lines[thisRow].content.substring(leftmost)); + } + 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)) + .fail(function (e) { + codeq.log.error('Error in handleInput loop: ' + e, e); + }); } - clipboardPasteInProgress = false; + promise.fin(function () { + internallyDisabled = false; + }).done(); - // scroll to bottom on input - dh = jqContent.height() - jqElt.height(); - if (dh > 0) - jqElt.scrollTop(dh); + clipboardPasteInProgress = false; }, clipboardPasteInProgress = false, // whether the previous keydown was a CTRL+V or shift+insert @@ -646,7 +672,7 @@ jqInput.on('keydown', function (evt) { var modifiers = ['' + (0 + evt.shiftKey), '' + (0 + (evt.ctrlKey || evt.metaKey)), '' + (0 + evt.altKey)].join(''), handlersForModifiers = handler.keyMaps[modifiers], - acceptKeydown = !inputDisabled, // the default value + acceptKeydown = !(inputDisabled || internallyDisabled), // the default value eventInfo = processKeyboardEvent(evt), handlerForKeydown = handlersForModifiers && handlersForModifiers[eventInfo.code]; -- cgit v1.2.1 From 3c02044761366fe474c7bf8cb5ba7307960c788c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Tue, 15 Sep 2015 20:06:01 +0200 Subject: Prolog handler now uses CodeQ terminal. --- js/prolog.js | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- js/python.js | 9 ++-- 2 files changed, 140 insertions(+), 9 deletions(-) (limited to 'js') diff --git a/js/prolog.js b/js/prolog.js index 7ea8ce3..cc46736 100644 --- a/js/prolog.js +++ b/js/prolog.js @@ -6,7 +6,7 @@ // a constant var firstCharacterPos = {'line': 0, 'ch': 0}; - var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { +/* var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { var promptMode = true, // default: query composition; alternative: query result browsing tcs = function terminalCommandSuccess (data) { var t, lines, i; @@ -82,6 +82,85 @@ }); return {}; + };*/ + + var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { + var promptMode = true, // default: query composition; alternative: query result browsing + terminal = codeq.makeConsole(jqConsole, { + 'greeting': 'CodeQ Prolog terminal proxy' + }), + tcs = function terminalCommandSuccess (data) { + var t, lines, i; + if (data.code === 0) { + t = data.terminal; + terminal.append(t.messages.join('\n') + '\n', 'output'); + promptMode = !t.have_more; + } + else { + terminal.error(data.message + '\n', 'error'); + promptMode = true; + } + if (promptMode) { + terminal.setLineBuffered(); + terminal.append('?- ', 'output'); + } + }, + tcf = function terminalCommandFailed (error) { + promptMode = true; + terminal.setLineBuffered(); + terminal.append(error + '\n', 'error'); + terminal.append('?- ', 'output'); + }; + + terminal.onKeypress = function (c) { + if (promptMode) return c; // query composition: return the character unchanged + switch (c) { + case ' ': + case ';': + case '\n': + return ';'; // show next answer on space, semicolon or enter + default: + return '.'; // everything else: stop searching for answers + } + }; + + terminal.onInput = function (command) { + if (promptMode) { + promptMode = false; + terminal.setNotBuffered(); + return codeq.comms.sendQuery({ + 'problem_id': problem_id, + 'step': 'run', + 'program': editor.getDoc().getValue(), + 'query': command, + 'trace': activityHandler.addAndPurge({'typ': 'slv', 'qry': command}) + }, problem_id).then(tcs, tcf); + } + else { + if (command == ';') { + // show next answer + return codeq.comms.sendQuery({ + 'problem_id': problem_id, + 'step': 'next', + 'trace': activityHandler.addAndPurge({'typ': 'nxt'}) + }, problem_id).then(tcs, tcf); + } + else { + // stop searching for answers + return codeq.comms.sendQuery({ + 'problem_id': problem_id, + 'step': 'end', + 'trace': activityHandler.addAndPurge({'typ': 'stp'}) + }, problem_id).then(tcs, tcf); + } + + } + }; + + terminal.leftmostCol = 3; + terminal.append('?- ', 'output'); + + return terminal; }; var makeActivityHandler = function (editor, problem_id) { @@ -296,6 +375,7 @@ var handler = { destroy: function () { + terminal.destroy(); jqDescription.empty(); jqEditor.empty(); // TODO: perhaps you do not want to "free" the editor, just empty it jqConsole.empty(); // TODO: the same with the console @@ -370,7 +450,7 @@ }); $('#btn_code_hint').on('click', function () { // handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); - jqConsole.echo('?- hint.'); +/* jqConsole.echo('?- hint.'); jqConsole.pause(); var doc = editor.getDoc(); codeq.comms.sendHint({ @@ -389,10 +469,35 @@ jqConsole.resume(); jqConsole.exception(error); } - ).done(); + ).done();*/ + + terminal.append('hint.\n', 'input'); + terminal.inputDisable(); + var doc = editor.getDoc(); + codeq.comms.sendHint({ + 'language': 'prolog', + 'program': editor.getDoc().getValue(), + 'problem_id': problem.id + }) + .then( + function hintSuccess(data) { + if (data.code === 0) + handler.processServerHints(data.hints); + else + terminal.append(data.message + '\n', 'error'); + }, + function hintFailed (error) { + terminal.append(error + '\n', 'error'); + } + ) + .fin(function () { + terminal.inputEnable(); + terminal.append('?- ', 'output'); + }) + .done(); }); $('#btn_code_test').on('click', function () { - jqConsole.echo('?- test.'); +/* jqConsole.echo('?- test.'); jqConsole.pause(); var doc = editor.getDoc(); codeq.comms.sendTest({ @@ -411,7 +516,32 @@ jqConsole.resume(); jqConsole.exception(error); } - ).done(); + ).done();*/ + + terminal.append('test.\n', 'input'); + terminal.inputDisable(); + var doc = editor.getDoc(); + codeq.comms.sendTest({ + 'language': 'prolog', + 'program': editor.getDoc().getValue(), + 'problem_id': problem.id + }) + .then( + function testSuccess(data) { + if (data.code === 0) + handler.processServerHints(data.hints); + else + terminal.append(data.message + '\n', 'error'); + }, + function testFailed (error) { + terminal.append(error + '\n', 'error'); + } + ) + .fin(function () { + terminal.inputEnable(); + terminal.append('?- ', 'output'); + }) + .done(); }); return handler; diff --git a/js/python.js b/js/python.js index d16cc72..82423c6 100644 --- a/js/python.js +++ b/js/python.js @@ -48,11 +48,11 @@ return terminal; }; - var makeActivityHandler = function (editor) { + var makeActivityHandler = function (editor, problem_id) { var lastActivityMillis = Date.now(), deltaActivityMillis = function deltaActivityMillisFunc () { var now = Date.now(), - dt = Math.max(0, Math.min(30000, now - lastActivityMillis)); // 0 sec <= dt <= 30 sec + dt = now - lastActivityMillis; lastActivityMillis = now; return dt; }, @@ -62,7 +62,7 @@ var promise; ts = null; if (queue.length === 0) return Q(true); - promise = codeq.comms.sendActivity(queue, editor.getDoc().getValue()); + promise = codeq.comms.sendActivity(queue, editor.getDoc().getValue(), problem_id); queue.length = 0; return promise; }, @@ -111,7 +111,7 @@ jqConsole = $('#console'), jqHints = $('#info'), editor = CodeMirror(jqEditor[0], { cursorHeight: 0.85, lineNumbers: true, matchBrackets: true, mode: 'python' }), - activityHandler = makeActivityHandler(editor), + activityHandler = makeActivityHandler(editor, problem.id), terminal = makePythonTerminalHandler(jqConsole, editor, problem.id, activityHandler), /** Object. */ @@ -248,6 +248,7 @@ var handler = { destroy: function () { + terminal.destroy(); jqDescription.empty(); jqEditor.empty(); // TODO: perhaps you do not want to "free" the editor, just empty it jqConsole.empty(); // TODO: the same with the console -- cgit v1.2.1 From e481326ffd15c7dd7f9878cc9f4f94b41021ac1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Tue, 15 Sep 2015 20:19:59 +0200 Subject: Bugfix: leftmostCol was not correctly referenced. --- js/codeq/console.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/codeq/console.js b/js/codeq/console.js index 41aae40..90b66cd 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -573,7 +573,7 @@ .then((function (newLine, lineIndex) {return function () { var cookedChars = lineIndex < lastLineIndex ? newLine + '\n' : newLine, // default thisRow = currentRow, - leftmost = typeof this.leftmostCol === 'number' && this.leftmostCol || 0, + leftmost = typeof handler.leftmostCol === 'number' && handler.leftmostCol || 0, dh; // first cook the input -- cgit v1.2.1 From fc502942d67e9d9854a2ef5a67dcadd831a75b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Tue, 15 Sep 2015 20:20:33 +0200 Subject: A few terminal newline fixes for Prolog. --- js/prolog.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'js') diff --git a/js/prolog.js b/js/prolog.js index cc46736..730e740 100644 --- a/js/prolog.js +++ b/js/prolog.js @@ -93,16 +93,16 @@ var t, lines, i; if (data.code === 0) { t = data.terminal; - terminal.append(t.messages.join('\n') + '\n', 'output'); + terminal.append(t.messages.join('\n'), 'output'); promptMode = !t.have_more; } else { - terminal.error(data.message + '\n', 'error'); + terminal.error(data.message, 'error'); promptMode = true; } if (promptMode) { terminal.setLineBuffered(); - terminal.append('?- ', 'output'); + terminal.append('\n?- ', 'output'); } }, tcf = function terminalCommandFailed (error) { @@ -137,6 +137,7 @@ }, problem_id).then(tcs, tcf); } else { + terminal.append('\n'); if (command == ';') { // show next answer return codeq.comms.sendQuery({ -- cgit v1.2.1 From d10866be04d45fc73eddce0ec7005161e69e97a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Wed, 16 Sep 2015 11:37:52 +0200 Subject: Removed the "run" and "break" buttons. Removed commented-out code from prolog and python handlers. --- js/prolog.js | 154 ++--------------------------------------------------------- js/python.js | 18 +------ 2 files changed, 4 insertions(+), 168 deletions(-) (limited to 'js') diff --git a/js/prolog.js b/js/prolog.js index 730e740..ebce9bf 100644 --- a/js/prolog.js +++ b/js/prolog.js @@ -6,84 +6,6 @@ // a constant var firstCharacterPos = {'line': 0, 'ch': 0}; -/* var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { - var promptMode = true, // default: query composition; alternative: query result browsing - tcs = function terminalCommandSuccess (data) { - var t, lines, i; - terminal.resume(); - if (data.code === 0) { - t = data.terminal; - lines = t.messages; - for (i = 0; i < lines.length; i++) { - terminal.echo(lines[i]); - } - promptMode = !t.have_more; - } - else { - terminal.error(data.message); - promptMode = true; - } - }, - tcf = function terminalCommandFailed (error) { - terminal.resume(); - terminal.exception(error); - promptMode = true; - }, - terminal = jqConsole.terminal(function (command, terminal) { - if (promptMode) { - terminal.pause(); - codeq.comms.sendQuery({ - 'problem_id': problem_id, - 'step': 'run', - 'program': editor.getDoc().getValue(), - 'query': command, - 'trace': activityHandler.addAndPurge({'typ': 'slv', 'qry': command}) - }, problem_id).then(tcs, tcf).done(); - } - else { - // not in prompt mode -- we should never land here, but handle it anyway - codeq.comms.sendQuery({ - 'problem_id': problem_id, - 'step': 'end', - 'trace': activityHandler.addAndPurge({'typ': 'stp'}) - }, problem_id).then(tcs, tcf).done(); - } - }, { - 'history': true, - 'prompt': '?- ', - 'greetings': 'CodeQ prolog terminal proxy', - 'exit': false, - 'clear': false, - 'keypress': function (event, terminal) { - if (promptMode) return true; - setTimeout(function () { - terminal.echo(''); // send newline after semicolon or full-stop - terminal.pause(); - }, 0); - if ((event.which == 32) || (event.which == 59) || (event.which == 110)) { - // space or semicolon or n -> show next answer - event.which = 59; // semicolon - codeq.comms.sendQuery({ - 'problem_id': problem_id, - 'step': 'next', - 'trace': activityHandler.addAndPurge({'typ': 'nxt'}) - }, problem_id).then(tcs, tcf).done(); - } - else { - // everything else: stop searching for answers - event.which = 46; // full stop - codeq.comms.sendQuery({ - 'problem_id': problem_id, - 'step': 'end', - 'trace': activityHandler.addAndPurge({'typ': 'stp'}) - }, problem_id).then(tcs, tcf).done(); - } - } - }); - - return {}; - };*/ - var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) { var promptMode = true, // default: query composition; alternative: query result browsing terminal = codeq.makeConsole(jqConsole, { @@ -188,16 +110,11 @@ }; return { - "trace": function (trace) { + 'queueTrace': function (trace) { trace['dt'] = deltaActivityMillis(); - return trace; - }, - 'queue': function (trace) { queue.push(trace); - if (ts === null) setTimeout(timer, 10000); // flush every 10 seconds - }, - 'queueTrace': function (trace) { - this.queue(this.trace(trace)); + if (ts === null) ts = setTimeout(timer, 10000); // flush every 10 seconds + return this; }, 'flush': flush, 'addAndPurge': function (trace) { @@ -228,21 +145,7 @@ jqHints = $('#info'), editor = CodeMirror(jqEditor[0], { cursorHeight: 0.85, lineNumbers: true, matchBrackets: true }), activityHandler = makeActivityHandler(editor, problem.id), -/* controller = jqConsole.console({ - promptLabel: '?- ', - commandValidate: function (line) { - return !!line; - }, - commandHandle: function (line) { - return [{msg:'Not implemented.', className:'console-response'}]; - }, - autofocus: false, - animateScroll: false, - promptHistory: false, - welcomeMessage: 'Prolog REPL.' - }),*/ terminal = makePrologTerminalHandler(jqConsole, editor, problem.id, activityHandler), - /** Object. */ hintDefs = problem.hint, hintCounter = 0, // for generating unique class-names hintCleaners = [], @@ -441,37 +344,7 @@ // $(jqButtons.get(1)).on('click', function () { handler.processServerHints([{id:'popup_unknown', start: 20, end: 26}]); }); // $(jqButtons.get(2)).on('click', function () { handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); }); - $('#btn_code_run').on('click', function () { - var doc = editor.getDoc(); -// codeq.comms.sendActivity({'typ': 'slv', 'dt': dt, 'qry': }); -// handler.processServerHints([{id:'list_empty'}]); - }); - $('#btn_code_break').on('click', function () { -// handler.processServerHints([{id:'popup_unknown', start: 20, end: 26}]); - }); $('#btn_code_hint').on('click', function () { -// handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); -/* jqConsole.echo('?- hint.'); - jqConsole.pause(); - var doc = editor.getDoc(); - codeq.comms.sendHint({ - 'language': 'prolog', - 'program': editor.getDoc().getValue(), - 'problem_id': problem.id - }).then( - function hintSuccess(data) { - jqConsole.resume(); - if (data.code === 0) - handler.processServerHints(data.hints); - else - jqConsole.error(data.message); - }, - function hintFailed (error) { - jqConsole.resume(); - jqConsole.exception(error); - } - ).done();*/ - terminal.append('hint.\n', 'input'); terminal.inputDisable(); var doc = editor.getDoc(); @@ -498,27 +371,6 @@ .done(); }); $('#btn_code_test').on('click', function () { -/* jqConsole.echo('?- test.'); - jqConsole.pause(); - var doc = editor.getDoc(); - codeq.comms.sendTest({ - 'language': 'prolog', - 'program': editor.getDoc().getValue(), - 'problem_id': problem.id - }).then( - function testSuccess(data) { - jqConsole.resume(); - if (data.code === 0) - handler.processServerHints(data.hints); - else - jqConsole.error(data.message); - }, - function testFailed (error) { - jqConsole.resume(); - jqConsole.exception(error); - } - ).done();*/ - terminal.append('test.\n', 'input'); terminal.inputDisable(); var doc = editor.getDoc(); diff --git a/js/python.js b/js/python.js index 82423c6..11e8a2b 100644 --- a/js/python.js +++ b/js/python.js @@ -72,17 +72,11 @@ }; return { - "trace": function (trace) { + 'queueTrace': function (trace) { trace['dt'] = deltaActivityMillis(); - return trace; - }, - 'queue': function (trace) { queue.push(trace); if (ts === null) setTimeout(timer, 10000); // flush every 10 seconds }, - 'queueTrace': function (trace) { - this.queue(this.trace(trace)); - }, 'flush': flush, 'addAndPurge': function (trace) { var accumulatedTrace = queue; @@ -113,8 +107,6 @@ editor = CodeMirror(jqEditor[0], { cursorHeight: 0.85, lineNumbers: true, matchBrackets: true, mode: 'python' }), activityHandler = makeActivityHandler(editor, problem.id), terminal = makePythonTerminalHandler(jqConsole, editor, problem.id, activityHandler), - - /** Object. */ hintDefs = problem.hint, hintCounter = 0, // for generating unique class-names hintCleaners = [], @@ -313,14 +305,6 @@ // $(jqButtons.get(1)).on('click', function () { handler.processServerHints([{id:'popup_unknown', start: 20, end: 26}]); }); // $(jqButtons.get(2)).on('click', function () { handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); }); - $('#btn_code_run').on('click', function () { - var doc = editor.getDoc(); -// codeq.comms.sendActivity({'typ': 'slv', 'dt': dt, 'qry': }); -// handler.processServerHints([{id:'list_empty'}]); - }); - $('#btn_code_break').on('click', function () { -// handler.processServerHints([{id:'popup_unknown', start: 20, end: 26}]); - }); $('#btn_code_hint').on('click', function () { // handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); terminal.append('>>> hint\n'); -- cgit v1.2.1 From c2b7956557835b1a232a84bdb262a700924a1538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Wed, 16 Sep 2015 13:18:49 +0200 Subject: Bugfix: console must not collapse spaces. --- js/codeq/console.js | 2 +- js/prolog.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/codeq/console.js b/js/codeq/console.js index 90b66cd..99c1550 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -176,7 +176,7 @@ jq1, jq2, jqCursor; if (!jqLine) { - jqLine = $('
'); + jqLine = $('
');
                     if (lineDescriptor.row == 0) {
                         jqContent.prepend(jqLine);
                     }
diff --git a/js/prolog.js b/js/prolog.js
index ebce9bf..2868830 100644
--- a/js/prolog.js
+++ b/js/prolog.js
@@ -19,12 +19,12 @@
                     promptMode = !t.have_more;
                 }
                 else {
-                    terminal.error(data.message, 'error');
+                    terminal.append(data.message, 'error');
                     promptMode = true;
                 }
                 if (promptMode) {
                     terminal.setLineBuffered();
-                    terminal.append('\n?- ', 'output');
+                    terminal.append('.\n?- ', 'output');
                 }
             },
             tcf = function terminalCommandFailed (error) {
@@ -59,7 +59,7 @@
                 }, problem_id).then(tcs, tcf);
             }
             else {
-                terminal.append('\n');
+                terminal.append('\n', 'input');
                 if (command == ';') {
                     // show next answer
                     return codeq.comms.sendQuery({
-- 
cgit v1.2.1


From 0eec2bd8f8fd8669682cf618bf22983a36f828a9 Mon Sep 17 00:00:00 2001
From: Timotej Lazar 
Date: Wed, 16 Sep 2015 16:17:52 +0200
Subject: Implement async. comm. with Python interpreter

---
 js/python.js | 60 ++++++++++++++++++++++++++----------------------------------
 1 file changed, 26 insertions(+), 34 deletions(-)

(limited to 'js')

diff --git a/js/python.js b/js/python.js
index 11e8a2b..7d7458e 100644
--- a/js/python.js
+++ b/js/python.js
@@ -8,42 +8,31 @@
 
     var makePythonTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) {
         var terminal = codeq.makeConsole(jqConsole, {
-            'greeting': 'CodeQ Python terminal proxy'
-        });
+                'greeting': 'CodeQ Python terminal proxy'
+            }),
+            tcs = function terminalCommandSuccess (data) {
+                if (data.code !== 0) {
+                    terminal.append(data.message, 'error');
+                }
+            },
+            tcf = function terminalCommandFailed (error) {
+                terminal.append(error + '\n', 'error');
+            };
+
         terminal.onInput = function (text) {
-            if (!text)
-                return;
-            codeq.comms.sendPush({
+            return codeq.comms.sendPush({
                 'text': text + '\n'
-            }).then(
-                function pushSuccess (data) {
-                    if (data.code !== 0)
-                        terminal.append('error: ' + data.message);
-                },
-                function pushFailed (error) {
-                    terminal.append('exception: '+ error);
-                }
-            ).done();
+            }).then(tcs, tcf);
         };
 
-        var interval_id = setInterval(function () {
-            codeq.comms.sendPull({}).then(
-                function pullSuccess (data) {
-                    if (data.code === 0) {
-                        t = data.terminal;
-                        if (!t.text)
-                            return;
-                        terminal.append(t.text);
-                    }
-                    else {
-                        terminal.append('error: ' + data.message);
-                    }
-                },
-                function pullFailed (error) {
-                    terminal.append('exception: '+ error);
-                }
-            ).done();
-        }, 200);
+        codeq.comms.on('terminal_output', function (data) {
+            var text = data.text;
+            terminal.append(text, 'output');
+            lines = text.split('\n');
+            terminal.leftmostCol = lines[lines.length-1].length;
+        });
+
+        terminal.leftmostCol = 1;
 
         return terminal;
     };
@@ -307,7 +296,6 @@
 
         $('#btn_code_hint').on('click', function () {
 //            handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]);
-            terminal.append('>>> hint\n');
             var doc = editor.getDoc();
             codeq.comms.sendHint({
                 'language': 'python',
@@ -326,7 +314,6 @@
             ).done();
         });
         $('#btn_code_test').on('click', function () {
-            terminal.append('>>> test\n');
             var doc = editor.getDoc();
             codeq.comms.sendTest({
                 'language': 'python',
@@ -345,6 +332,11 @@
             ).done();
         });
 
+        // TODO first line of interpreter output is buffered without this, why?
+        codeq.comms.sendPush({
+            'text': ''
+        });
+
         return handler;
     };
 })();
-- 
cgit v1.2.1