diff --git a/web/app/sketcher/sketcher-app.js b/web/app/sketcher/sketcher-app.js index eb9109b3..e2ea5fb1 100644 --- a/web/app/sketcher/sketcher-app.js +++ b/web/app/sketcher/sketcher-app.js @@ -1,5 +1,6 @@ import {Viewer} from './viewer2d.js' import * as ui from '../ui/ui' +import {Terminal} from '../ui/terminal' import {IO, BBox} from './io' import {AddDimTool, AddCircleDimTool, HDimension, VDimension, Dimension, DiameterDimension} from './shapes/dim' import {AddPointTool, AddSegmentTool} from './shapes/segment' @@ -46,7 +47,7 @@ function App2D() { $('.coordinates-info').text(coord.x.toFixed(3) + " : " + coord.y.toFixed(3)); }); this.terminalHandeler = null; - this.terminal = new ui.Terminal(this.commandsWin, (command) => this.handleTerminalInput(command), () => this.getAllCommandList()); + this.terminal = new Terminal(this.commandsWin, (command) => this.handleTerminalInput(command), () => this.getAllCommandList()); this.bindToolsToTerminal(); @@ -367,7 +368,6 @@ App2D.prototype.getSketchId = function() { }; App2D.prototype.bindToolsToTerminal = function() { - }; App2D.STATIC_COMMANDS = { @@ -391,7 +391,7 @@ App2D.prototype.handleTerminalInput = function(commandStr) { if (cmd) { return cmd(this); } - let actionId = this.commands[cmd]; + let actionId = this.commands[commandStr]; if (actionId) { this.actions[actionId].action(); } else { diff --git a/web/app/ui/terminal.js b/web/app/ui/terminal.js new file mode 100644 index 00000000..ab10d5a1 --- /dev/null +++ b/web/app/ui/terminal.js @@ -0,0 +1,87 @@ +export function Terminal(win, commandProcessor, variantsSupplier) { + this.win = win; + this.out = win.root.find('.terminal-output'); + const input = win.root.find('.terminal-input input'); + + win.onShowCallback = function() { + input.focus(); + }; + this.history = []; + this.historyPointer = 0; + const setHistory = () => { + if (this.history.length == 0) return; + input.val(this.history[this.historyPointer]); + }; + + + input.keydown((e) => { + function consumeEvent() { + e.preventDefault(); + e.stopPropagation(); + } + if (e.keyCode == 9) { + const text = input.val(); + let variants = variantsSupplier().filter(v => v.startsWith(text)); + variants.sort(); + if (variants.length == 0) { + } else { + const shared = sharedStartOfSortedArray(variants); + if (shared.length != text.length) { + input.val(shared); + } else { + let autocompleteArea = this.out.find('.autocomplete-area'); + if (autocompleteArea.length == 0) { + autocompleteArea = $('
', {'class': 'terminal-commandText autocomplete-area'}); + this.out.append(autocompleteArea); + } + let more = ''; + const limit = 20; + if (variants.length > limit) { + more = '... and ' + (variants.length - limit) + ' more'; + variants = variants.slice(0,limit); + } + autocompleteArea.text(variants.join(' ') + more); + } + } + consumeEvent(); + } else if (e.keyCode == 38) { + this.historyPointer = Math.max(this.historyPointer - 1, 0); + setHistory(); + consumeEvent(); + } else if (e.keyCode == 40) { + if (this.historyPointer != this.history.length) { + this.historyPointer = Math.min(this.historyPointer + 1, this.history.length - 1); + setHistory(); + } + consumeEvent(); + } + }); + + input.keyup((e) => { + if(e.keyCode == 13) { + const command = input.val(); + this.out.find('.autocomplete-area').remove(); + input.val(''); + this.out.append($('
', {text: '> '+command, 'class': 'terminal-commandText'})); + if (command != null && command.trim().length != 0) { + const result = commandProcessor(command); + this.print(result); + if (this.history.length == 0 || command != this.history[this.history.length - 1]) { + this.history.push(command); + } + this.historyPointer = this.history.length; + } + this.out.parent().scrollTop(this.out.height()); + } + }); +} + +Terminal.prototype.print = function(text) { + this.win.root.find('.terminal-output').append($('
', {text, 'class': 'terminal-commandResult'})); +}; + +function sharedStartOfSortedArray(array){ + var a1= array[0], a2= array[array.length-1], L= a1.length, i= 0; + while(i { - if (this.history.length == 0) return; - input.val(this.history[this.historyPointer]); - }; - - - input.keydown((e) => { - function consumeEvent() { - e.preventDefault(); - e.stopPropagation(); - } - if (e.keyCode == 9) { - const text = input.val(); - let variants = variantsSupplier().filter(v => v.startsWith(text)); - variants.sort(); - if (variants.length == 0) { - } else { - const shared = sharedStartOfSortedArray(variants); - if (shared.length != text.length) { - input.val(shared); - } else { - let autocompleteArea = this.out.find('.autocomplete-area'); - if (autocompleteArea.length == 0) { - autocompleteArea = $('
', {'class': 'terminal-commandText autocomplete-area'}); - this.out.append(autocompleteArea); - } - let more = ''; - const limit = 20; - if (variants.length > limit) { - more = '... and ' + (variants.length - limit) + ' more'; - variants = variants.slice(0,limit); - } - autocompleteArea.text(variants.join(' ') + more); - } - } - consumeEvent(); - } else if (e.keyCode == 38) { - this.historyPointer = Math.max(this.historyPointer - 1, 0); - setHistory(); - consumeEvent(); - } else if (e.keyCode == 40) { - if (this.historyPointer != this.history.length) { - this.historyPointer = Math.min(this.historyPointer + 1, this.history.length - 1); - setHistory(); - } - consumeEvent(); - } - }); - - input.keyup((e) => { - if(e.keyCode == 13) { - const command = input.val(); - this.out.find('.autocomplete-area').remove(); - input.val(''); - this.out.append($('
', {text: '> '+command, 'class': 'terminal-commandText'})); - if (command != null && command.trim().length != 0) { - const result = commandProcessor(command); - this.print(result); - if (this.history.length == 0 || command != this.history[this.history.length - 1]) { - this.history.push(command); - } - this.historyPointer = this.history.length; - } - this.out.parent().scrollTop(this.out.height()); - } - }); -} - -Terminal.prototype.print = function(text) { - this.win.root.find('.terminal-output').append($('
', {text, 'class': 'terminal-commandResult'})); -}; - -export { WinManager, Window, List, Dock, Terminal, dockBtn, faBtn, openWin, closeWin, bindOpening, createActionsWinBuilder, DIRECTIONS }; \ No newline at end of file +export { WinManager, Window, List, Dock, dockBtn, faBtn, openWin, closeWin, bindOpening, createActionsWinBuilder, DIRECTIONS }; \ No newline at end of file