Преглед на файлове

HUE-5526 [editor] Add key and mouse bindings to the custom autocompleter

Johan Ahlen преди 9 години
родител
ревизия
9af63550ad

+ 1 - 1
desktop/core/src/desktop/static/desktop/js/autocompleter.js

@@ -34,7 +34,7 @@ var Autocompleter = (function () {
 
     var initializeAutocompleter = function () {
       if (self.snippet.isSqlDialect() && options.useNewAutocompleter) {
-        self.autocompleter = new SqlAutocompleter3({
+        self.autocompleter = new SqlAutocompleter2({
           snippet: self.snippet,
           timeout: self.timeout
         });

+ 0 - 1
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -3327,7 +3327,6 @@
             editor.completers.push(langTools.keyWordCompleter);
             editor.completers.push(snippet.autocompleter);
           } else if (snippet.type() === 'hive' || snippet.type() === 'impala') {
-            editor.completers.push(snippet.autocompleter);
             editor.useHueAutocompleter = true;
           } else {
             editor.completers.push(snippet.autocompleter);

+ 2 - 9
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter3.js

@@ -272,7 +272,7 @@ var SqlAutocompleter3 = (function () {
     self.timeout = options.timeout;
   }
 
-  SqlAutocompleter3.prototype.autocomplete = function (beforeCursor, afterCursor, editor) {
+  SqlAutocompleter3.prototype.autocomplete = function (beforeCursor, afterCursor) {
     var self = this;
     var sourceType = self.snippet.type();
     var parseResult = sql.parseSql(beforeCursor, afterCursor, sourceType, false);
@@ -281,18 +281,11 @@ var SqlAutocompleter3 = (function () {
       console.log(parseResult);
     }
 
-    if (typeof editor !== 'undefined' && editor !== null) {
-      editor.showSpinner();
-    }
-
     return new Suggestions({
       parseResult: parseResult,
       sourceType: sourceType,
       defaultDatabase: parseResult.useDatabase || self.snippet.database(),
-      timeout: self.timeout,
-      callback: function () {
-        editor.hideSpinner();
-      }
+      timeout: self.timeout
     });
   };
 

+ 0 - 12
desktop/libs/notebook/src/notebook/static/notebook/css/notebook.css

@@ -1158,15 +1158,3 @@ h4.header {
   width: 8px!important;
   margin-left: 10px!important;
 }
-
-.hue-ace-autocompleter {
-  position: absolute;
-  z-index: 100000;
-  width: 500px;
-  height: 250px;
-  border: 1px solid #DDD;
-  border-radius: 3px;
-  display: flex;
-  flex-direction: column;
-  background-color: #FFF;
-}

+ 1 - 0
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -64,6 +64,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, ENABLE_
 <script src="${ static('desktop/js/sqlFunctions.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sql.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
+<script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter3.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/autocompleter.js') }"></script>

+ 135 - 4
desktop/libs/notebook/src/notebook/templates/notebook_ko_components.mako

@@ -446,28 +446,159 @@ except ImportError, e:
 </%def>
 
 <%def name="hueAceAutocompleter()">
+  <style>
+    .hue-ace-autocompleter {
+      position: absolute;
+      z-index: 100000;
+      width: 500px;
+      height: 250px;
+      border: 1px solid #DDD;
+      border-radius: 3px;
+      display: flex;
+      flex-direction: column;
+      background-color: #FFF;
+    }
+
+    .autocompleter-header {
+      flex: 1 1 30px;
+      padding: 5px;
+    }
+
+    .autocompleter-list {
+      flex: 1 1 100%;
+      overflow-y: auto;
+      padding: 0 5px;
+    }
+
+    .autocompleter-list > div {
+      height: 19px;
+      clear: both;
+    }
+
+    .autocompleter-list > div.selected {
+      background-color: #F00;
+    }
+
+  </style>
   <script type="text/html" id="hue-ace-autocompleter">
-    <div style="flex: 1 1 30px; padding: 5px;"><div class="pull-right"><label class="checkbox"><input type="checkbox">${ _('Keywords') }</label></div></div>
-    <div style="flex: 1 1 100%; overflow-y: auto; padding: 0 5px;" data-bind="foreach: activeSuggestions">
-      <div style="clear: both;font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;"><div class="pull-left" data-bind="text: value"></div><div class="pull-right" data-bind="text: meta"></div></div>
+    <div class="autocompleter-header"><div class="pull-right">header</div></div>
+    <div class="autocompleter-list" data-bind="foreach: activeSuggestions">
+      <div data-bind="css: { 'selected': $index() === $parent.selectedIndex() }"><div class="pull-left" data-bind="text: value"></div><div class="pull-right" data-bind="text: meta"></div></div>
     </div>
     <!-- /ko -->
   </script>
 
   <script type="text/javascript" charset="utf-8">
     (function () {
+      var aceUtil = ace.require("ace/autocomplete/util");
+      var HashHandler = ace.require("ace/keyboard/hash_handler").HashHandler;
+
       function HueAceAutocompleter (params, element) {
         var self = this;
         var snippet = params.snippet;
         var editor = params.editor;
+
         var autocompleter = new SqlAutocompleter3({ snippet: snippet, timeout: AUTOCOMPLETE_TIMEOUT });
-        self.suggestions = autocompleter.autocomplete(editor.getTextBeforeCursor(), editor.getTextAfterCursor(), editor);
+        self.suggestions = autocompleter.autocomplete(editor.getTextBeforeCursor(), editor.getTextAfterCursor());
         self.activeSuggestions = ko.pureComputed(function () {
           if (self.suggestions.keywords) {
             return self.suggestions.keywords.suggestions();
           }
           return [];
         });
+
+        self.selectedIndex = ko.observable(0);
+
+        var session = editor.getSession();
+        var pos = editor.getCursorPosition();
+
+        var line = session.getLine(pos.row);
+        var prefix = aceUtil.retrievePrecedingIdentifier(line, pos.column);
+
+        self.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
+        self.base.$insertRight = true;
+
+        self.keyboardHandler = new HashHandler();
+        self.keyboardHandler.bindKeys({
+          "Up": function(editor) {
+            if (self.selectedIndex() !== 0) {
+              self.selectedIndex(self.selectedIndex() - 1);
+            }
+          },
+          "Down": function(editor) {
+            if (self.selectedIndex() !== self.activeSuggestions().length) {
+              self.selectedIndex(self.selectedIndex() + 1);
+            }
+          },
+          "Ctrl-Up|Ctrl-Home": function(editor) {
+            console.log('start');
+          },
+          "Ctrl-Down|Ctrl-End": function(editor) {
+            console.log('end');
+          },
+          "Esc": function(editor) {
+            self.destroy();
+          },
+          "Return": function(editor) {
+            editor.execCommand("insertstring", self.activeSuggestions()[self.selectedIndex()].value);
+            editor.renderer.scrollCursorIntoView();
+            self.destroy();
+          },
+          "Shift-Return": function(editor) {
+            console.log('insert deleteSuffix');
+          },
+          "Tab": function(editor) {
+            console.log('insert or down if nothing selected');
+          },
+          "PageUp": function(editor) {
+            console.log('page up');
+          },
+          "PageDown": function(editor) {
+            console.log('page down');
+          }
+        });
+
+        var changeTimeout = -1;
+
+        self.changeListener = function () {
+          window.clearTimeout(changeTimeout);
+          var cursor = editor.selection.lead;
+          if (cursor.row != self.base.row || cursor.column < self.base.column) {
+            self.destroy();
+          } else {
+            changeTimeout = window.setTimeout(self.updateCompletions, 200)
+          }
+        };
+
+        self.blurListener = function () {
+          console.log('blur');
+          //self.destroy();
+        };
+
+        self.mousedownListener = function () {
+          console.log('mousedown');
+        };
+
+        self.mousewheelListener = function () {
+          console.log('mousewheel');
+        };
+
+        this.destroy = function () {
+          self.base.detach();
+          window.clearTimeout(changeTimeout);
+          editor.keyBinding.removeKeyboardHandler(self.keyboardHandler);
+          editor.off("changeSelection", self.changeListener);
+          editor.off("blur", self.blurListener);
+          editor.off("mousedown", self.mousedownListener);
+          editor.off("mousewheel", self.mousewheelListener);
+          $(element).remove();
+        };
+
+        editor.keyBinding.addKeyboardHandler(self.keyboardHandler);
+        editor.on("changeSelection", self.changeListener);
+        editor.on("blur", self.blurListener);
+        editor.on("mousedown", self.mousedownListener);
+        editor.on("mousewheel", self.mousewheelListener);
       }
 
       ko.components.register('hueAceAutocompleter', {