Skip to content

Commit

Permalink
Enable tab to complete (fixes #14)
Browse files Browse the repository at this point in the history
  • Loading branch information
abhinavpappu committed Jun 18, 2021
1 parent d553a96 commit 722574d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
46 changes: 27 additions & 19 deletions src/editor/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
<textarea
class="input"
v-model="inputValue"
@input="onTextInput"
@input="handleInputChange"
@keydown.right.stop.prevent="moveCursor(1, $event.shiftKey)"
@keydown.left.stop.prevent="moveCursor(-1, $event.shiftKey)"
@keydown.up.stop.prevent="moveLine(-1, $event.shiftKey)"
@keydown.down.stop.prevent="moveLine(1, $event.shiftKey)"
@keydown.tab.stop.prevent="insertTextAtCursor('\t')"
@keydown.tab.stop.prevent="handleTextInput('\t')"
@keydown.ctrl="specialKey"
@keydown.meta="specialKey"
@blur="hideCursor = true"
Expand Down Expand Up @@ -73,7 +73,7 @@ export default {
},
hideCursor: true,
cursorCallback: false,
inputValue: ' ',
inputValue: ' ', // the two spaces are used to detect backspace and delete
selectionStart: 0,
selectionEnd: 0,
selectionAllowed: false,
Expand Down Expand Up @@ -195,27 +195,13 @@ export default {
this.inputValue = ' ';
this.$nextTick(() => this.$refs.input.setSelectionRange(1, 1));
},
onTextInput() {
handleInputChange() {
const { input } = this.$refs;
let value = this.inputValue;
if (value.length >= 3 && input.selectionStart === value.length - 1) {
value = value.slice(1, value.length - 1);
this.deleteSelection();
const { line, char } = this.position;
if (value === '\n') {
if (this.autocompleteVisible) { // if autocomplete visible, pressing enter will select suggestion instead
this.autocompleteStatement();
value = '';
} else {
// keep indentation when adding lines
value += this.indentation[line];
if (this.text[this.cursor - 1] === '{') value += ' '; // extra indent if {
}
}
if (value === '}' && this.lines[line].slice(0, char).match(/^ +$/)) { // dedent if }
this.deleteTextAtCursor(this.cursor - 2);
}
this.insertTextAtCursor(value);
this.handleTextInput(value);
} else if (value.length === 1) {
if (input.selectionStart === 0) {
this.backspace();
Expand All @@ -227,6 +213,28 @@ export default {
this.onCursorUpdate(this.updateAutocomplete);
},
handleTextInput(value) {
const { line, char } = this.position;
// if autocomplete visible, pressing enter or tab will select suggestion instead
if (this.autocompleteVisible && ['\n', '\t'].includes(value)) {
this.autocompleteStatement();
value = '';
}
// keep indentation when adding lines
if (value === '\n') {
value += this.indentation[line];
if (this.text[this.cursor - 1] === '{') value += ' '; // extra indent if {
}
// dedent if "}" (with checking to make sure only spaces precede cursor on that line, and at least 2)
if (value === '}' && this.lines[line].slice(0, char).match(/^ +$/)) {
this.deleteTextAtCursor(this.cursor - 2);
}
this.insertTextAtCursor(value);
},
insertText(text, location, save = true) {
let newText = text;
const specialCharacters = {
Expand Down
4 changes: 4 additions & 0 deletions src/eval.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ export default (code, $_add = {}) => {
const globals = Object.getOwnPropertyNames(window);
globals.splice(globals.indexOf('eval'), 1);

// to avoid "SyntaxError: Unexpected token 'import'" when trying to do "var import = undefined"
// since `import` is reserved keyword, but this is fine since `import` isn't allowed in `eval` anyway
globals.splice(globals.indexOf('import'), 1);

let removeGlobals = '';
globals.forEach(property => {
removeGlobals += `var ${property} = undefined;`;
Expand Down

0 comments on commit 722574d

Please sign in to comment.