|
|
@@ -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', {
|