From 39e46e2c483e1e669508ac35245263e499e6e575 Mon Sep 17 00:00:00 2001 From: Alan Bernstein Date: Thu, 18 May 2017 18:30:25 -0500 Subject: [PATCH] Factor out autocompleter --- webui/assets/main.js | 119 ++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 53 deletions(-) diff --git a/webui/assets/main.js b/webui/assets/main.js index 3969ed650..eea168185 100644 --- a/webui/assets/main.js +++ b/webui/assets/main.js @@ -1,8 +1,9 @@ class REPL { - constructor(input, output, button) { + constructor(input, output, button, completer) { this.input = input this.output = output this.button = button + this.completer = completer this.history = [] this.history_index = 0 this.history_buffer = '' @@ -16,21 +17,6 @@ class REPL { UP_ARROW: 38, DOWN_ARROW: 40 } - var keywords = { - // keyword: length of substring that comes after cursor - "SetBit()": 1, - "ClearBit()": 1, - "SetRowAttrs()": 1, - "SetColumnAttrs()": 1, - "Bitmap()": 1, - "Union()": 1, - "Intersect()": 1, - "Difference()": 1, - "Count()": 1, - "Range()": 1, - "TopN()": 1, - "frame=": 0, - } this.input.addEventListener("keydown", function(e) { if (e.keyCode == keys.UP_ARROW) { @@ -70,42 +56,7 @@ class REPL { } if (e.keyCode == keys.TAB) { e.preventDefault() - - // extract word fragment ending at cursor. a word fragment: - // - starts with last nonalpha character before cursor (or beginning of string) - // - ends at cursor - var word_start = repl.input.selectionEnd-1 - while(word_start>0) { - var c = repl.input.value.charCodeAt(word_start) - if(!((c>64 && c<91) || (c>96 && c<123))) { - word_start++ - break - } - word_start-- - } - var input_word = repl.input.value.substring(word_start, repl.input.selectionEnd) - - // check for keyword match and insert if exactly one match - var matches = [] - for(var keyword in keywords) { - if(keyword.startsWith(input_word)){ - matches.push(keyword) - } - } - if(matches.length > 1) { - // display in some dynamic element - } - - if(matches.length == 1) { - var cursor_pos = repl.input.selectionEnd - var completion = matches[0].substring(input_word.length) - var before = repl.input.value.substring(0, cursor_pos) - var after = repl.input.value.substring(cursor_pos) - repl.input.value = before + completion + after - var new_pos = cursor_pos + completion.length - keywords[matches[0]] - repl.input.setSelectionRange(new_pos, new_pos) - } - + repl.completer.complete() } }) repl.button.onclick = function() { @@ -451,11 +402,73 @@ Date.prototype.timeNow = function () { populate_version() + +class Autocompleter { + constructor(input) { + this.input = input + this.keyword_map = this.static_keywords + } + + get static_keywords() { + return { + // keyword: length of substring that comes after cursor + "SetBit()": 1, + "ClearBit()": 1, + "SetRowAttrs()": 1, + "SetColumnAttrs()": 1, + "Bitmap()": 1, + "Union()": 1, + "Intersect()": 1, + "Difference()": 1, + "Count()": 1, + "Range()": 1, + "TopN()": 1, + "frame=": 0, + } + } + + complete() { + var completer = this + // extract word fragment ending at cursor. a word fragment: + // - starts with last nonalpha character before cursor (or beginning of string) + // - ends at cursor + var word_start = completer.input.selectionEnd-1 + while(word_start>0) { + var c = completer.input.value.charCodeAt(word_start) + if(!((c>64 && c<91) || (c>96 && c<123))) { + word_start++ + break + } + word_start-- + } + var input_word = completer.input.value.substring(word_start, completer.input.selectionEnd) + + // check for keyword match and insert if exactly one match + var matches = [] + for(var keyword in this.keyword_map) { + if(keyword.startsWith(input_word)){ + matches.push(keyword) + } + } + + if(matches.length == 1) { + var cursor_pos = completer.input.selectionEnd + var completion = matches[0].substring(input_word.length) + var before = completer.input.value.substring(0, cursor_pos) + var after = completer.input.value.substring(cursor_pos) + completer.input.value = before + completion + after + var new_pos = cursor_pos + completion.length - this.keyword_map[matches[0]] + completer.input.setSelectionRange(new_pos, new_pos) + } + } +} + var input = document.getElementById('query') var output = document.getElementById('outputs') var button = document.getElementById('query-btn') -repl = new REPL(input, output, button) +autocompleter = new Autocompleter(input) +repl = new REPL(input, output, button, autocompleter) repl.populate_index_dropdown() repl.bind_events()