Browse Source

HUE-1063 [beeswax] SQL autocomplete and syntax highlighting

Changed jQuery linedtextarea with CodeMirror
Created autocomplete and syntax hightlighting for HiveQL
Enrico Berti 12 years ago
parent
commit
1b015a171f

+ 155 - 160
apps/beeswax/src/beeswax/templates/execute.mako

@@ -33,7 +33,7 @@
         </div>
     % endif
 
-    <textarea class="span11" tabindex="1" placeholder="${_('Example: SELECT * FROM tablename')}" name="${form.query["query"].html_name}" id="queryField">${extract_field_data(form.query["query"]) or ''}</textarea>
+    <textarea class="hide" tabindex="1" name="${form.query["query"].html_name}" id="queryField">${extract_field_data(form.query["query"]) or ''}</textarea>
 
     <div id="validationResults">
     % if len(form.query["query"].errors):
@@ -344,8 +344,13 @@ ${layout.menubar(section='query')}
     </div>
 </div>
 
-<link rel="stylesheet" href="/static/ext/css/jquery-linedtextarea.css" type="text/css" media="screen" title="no title" charset="utf-8" />
-<script src="/static/ext/js/jquery/plugins/jquery-linedtextarea.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/codemirror-3.11.js"></script>
+<link rel="stylesheet" href="/static/ext/css/codemirror.css">
+<script src="/static/js/Source/jHue/codemirror-hql.js"></script>
+<script src="/static/js/Source/jHue/codemirror-hql-hint.js"></script>
+<script src="/static/ext/js/codemirror-show-hint.js"></script>
+
+<link rel="stylesheet" href="/static/ext/css/codemirror-show-hint.css">
 
 <style>
   h1 {
@@ -390,32 +395,16 @@ ${layout.menubar(section='query')}
     border-radius: 0 3px 3px 0;
   }
 
-  .linedwrap {
-    margin-top: 20px;
-    margin-bottom: 10px;
-    -webkit-border-radius: 4px;
-    -moz-border-radius: 4px;
-    border-radius: 4px;
-    background-color: #ffffff;
-    border: 1px solid #cccccc;
-    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-    -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-    -o-transition: border linear 0.2s, box-shadow linear 0.2s;
-    transition: border linear 0.2s, box-shadow linear 0.2s;
+  .CodeMirror {
+    border: 1px solid #eee;
+    margin-bottom: 20px;
   }
 
-  .linedtextarea textarea {
-    -webkit-box-shadow: none;
-    -moz-box-shadow: none;
-    box-shadow: none;
-  }
-
-  .linedwrap .codelines .lineselect {
+  .editorError {
     color: #B94A48;
     background-color: #F2DEDE;
+    padding: 4px;
+    font-size: 11px;
   }
 
 </style>
@@ -425,128 +414,114 @@ ${layout.menubar(section='query')}
 
 <script type="text/javascript" charset="utf-8">
     $(document).ready(function(){
-        $("*[rel=tooltip]").tooltip({
-            placement: 'bottom'
-        });
-
-        $("a[data-form-prefix]").each(function(){
-            var _prefix = $(this).attr("data-form-prefix");
-            var _nextID = 0;
-            if ($("."+_prefix+"Field").length){
-                _nextID= ($("."+_prefix+"Field").last().attr("name").substr(_prefix.length+1).split("-")[0]*1)+1;
-            }
-            $("<input>").attr("type","hidden").attr("name",_prefix+"-next_form_id").attr("value",_nextID).appendTo($("#advancedSettingsForm"));
-            $("."+_prefix+"Delete").click(function(e){
-                e.preventDefault();
-                $("input[name="+_prefix+"-add]").attr("value","");
-                $("<input>").attr("type","hidden").attr("name", $(this).attr("name")).attr("value","True").appendTo($("#advancedSettingsForm"));
-                checkAndSubmit();
-            });
-        });
 
-        $("a[data-form-prefix]").click(function(){
-            var _prefix = $(this).attr("data-form-prefix");
-            $("<input>").attr("type","hidden").attr("name",_prefix+"-add").attr("value","True").appendTo($("#advancedSettingsForm"));
-            checkAndSubmit();
-        });
+      var queryPlaceholder = "${_('Example: SELECT * FROM tablename')}";
 
-        $(".file_resourcesField").each(function(){
-            var self = $(this);
-            self.after(getFileBrowseButton(self));
-        });
+      $("*[rel=tooltip]").tooltip({
+        placement: 'bottom'
+      });
 
-        function getFileBrowseButton(inputElement) {
-            return $("<button>").addClass("btn").addClass("fileChooserBtn").text("..").click(function(e){
-                e.preventDefault();
-                $("#filechooser").jHueFileChooser({
-                    initialPath: inputElement.val(),
-                    onFileChoose: function(filePath) {
-                        inputElement.val(filePath);
-                        $("#chooseFile").modal("hide");
-                    },
-                    createFolder: false
-                });
-                $("#chooseFile").modal("show");
-            })
+      $("a[data-form-prefix]").each(function () {
+        var _prefix = $(this).attr("data-form-prefix");
+        var _nextID = 0;
+        if ($("." + _prefix + "Field").length) {
+          _nextID = ($("." + _prefix + "Field").last().attr("name").substr(_prefix.length + 1).split("-")[0] * 1) + 1;
         }
-
-        $("#id_query-database").change(function(){
-             $.cookie("hueBeeswaxLastDatabase", $(this).val(), {expires: 90});
+        $("<input>").attr("type", "hidden").attr("name", _prefix + "-next_form_id").attr("value", _nextID).appendTo($("#advancedSettingsForm"));
+        $("." + _prefix + "Delete").click(function (e) {
+          e.preventDefault();
+          $("input[name=" + _prefix + "-add]").attr("value", "");
+          $("<input>").attr("type", "hidden").attr("name", $(this).attr("name")).attr("value", "True").appendTo($("#advancedSettingsForm"));
+          checkAndSubmit();
         });
+      });
 
-        ## If no particular query is loaded
-        % if design is None or design.id is None:
-            if ($.cookie("hueBeeswaxLastDatabase") != null) {
-                $("#id_query-database").val($.cookie("hueBeeswaxLastDatabase"));
-            }
-        % endif
+      $("a[data-form-prefix]").click(function () {
+        var _prefix = $(this).attr("data-form-prefix");
+        $("<input>").attr("type", "hidden").attr("name", _prefix + "-add").attr("value", "True").appendTo($("#advancedSettingsForm"));
+        checkAndSubmit();
+      });
 
-        var executeQuery = function(){
-            $("<input>").attr("type","hidden").attr("name","button-submit").attr("value","Execute").appendTo($("#advancedSettingsForm"));
-            checkAndSubmit();
-        }
+      $(".file_resourcesField").each(function () {
+        var self = $(this);
+        self.after(getFileBrowseButton(self));
+      });
 
-        $("#executeQuery").click(executeQuery);
-        $("#executeQuery").tooltip({
-            title: '${_("Press \"tab\", then \"enter\".")}'
-        });
-        $("#executeQuery").keyup(function(event){
-            if(event.keyCode == 13){
-                executeQuery();
-            }
-        });
+      function getFileBrowseButton(inputElement) {
+        return $("<button>").addClass("btn").addClass("fileChooserBtn").text("..").click(function (e) {
+          e.preventDefault();
+          $("#filechooser").jHueFileChooser({
+            initialPath: inputElement.val(),
+            onFileChoose: function (filePath) {
+              inputElement.val(filePath);
+              $("#chooseFile").modal("hide");
+            },
+            createFolder: false
+          });
+          $("#chooseFile").modal("show");
+        })
+      }
 
-        % if app_name == 'impala':
-        $("#downloadQuery").click(function(){
-            $("<input>").attr("type", "hidden").attr("name", "button-submit").attr("value", "Execute").appendTo($("#advancedSettingsForm"));
-            $("<input>").attr("type", "hidden").attr("name", "download").attr("value", "true").appendTo($("#advancedSettingsForm"));
-            checkAndSubmit();
-        });
-        % endif
+      $("#id_query-database").change(function () {
+        $.cookie("hueBeeswaxLastDatabase", $(this).val(), {expires: 90});
+      });
 
-        $("#saveQuery").click(function(){
-            $("<input>").attr("type","hidden").attr("name","saveform-name")
-                .attr("value", "${extract_field_data(form.saveform["name"])}").appendTo($("#advancedSettingsForm"));
-            $("<input>").attr("type","hidden").attr("name","saveform-desc")
-                .attr("value", "${extract_field_data(form.saveform["desc"])}").appendTo($("#advancedSettingsForm"));
-            $("<input>").attr("type","hidden").attr("name","saveform-save").attr("value","Save").appendTo($("#advancedSettingsForm"));
-            checkAndSubmit();
-        });
+      ## If no particular query is loaded
+      % if design is None or design.id is None:
+        if ($.cookie("hueBeeswaxLastDatabase") != null) {
+          $("#id_query-database").val($.cookie("hueBeeswaxLastDatabase"));
+        }
+      % endif
 
-        $("#saveQueryAs").click(function(){
-            $("<input>").attr("type","hidden").attr("name","saveform-saveas").attr("value","Save As...").appendTo($("#advancedSettingsForm"));
-            $("#saveAs").modal("show");
-        });
+      var executeQuery = function () {
+        $("<input>").attr("type", "hidden").attr("name", "button-submit").attr("value", "Execute").appendTo($("#advancedSettingsForm"));
+        checkAndSubmit();
+      }
 
-        $("#saveAsNameBtn").click(function(){
-             $("<input>").attr("type","hidden").attr("name","saveform-name")
-                 .attr("value", $("input[name=saveform-name]").val()).appendTo($("#advancedSettingsForm"));
-             $("<input>").attr("type","hidden").attr("name","saveform-desc")
-                 .attr("value", $("input[name=saveform-desc]").val()).appendTo($("#advancedSettingsForm"));
+      $("#executeQuery").click(executeQuery);
+      $("#executeQuery").tooltip({
+        title: '${_("Press \"tab\", then \"enter\".")}'
+      });
+      $("#executeQuery").keyup(function (event) {
+        if (event.keyCode == 13) {
+          executeQuery();
+        }
+      });
 
-            checkAndSubmit();
+      % if app_name == 'impala':
+        $("#downloadQuery").click(function () {
+          $("<input>").attr("type", "hidden").attr("name", "button-submit").attr("value", "Execute").appendTo($("#advancedSettingsForm"));
+          $("<input>").attr("type", "hidden").attr("name", "download").attr("value", "true").appendTo($("#advancedSettingsForm"));
+          checkAndSubmit();
         });
+      % endif
 
-        $("#explainQuery").click(function(){
-            $("<input>").attr("type","hidden").attr("name","button-explain").attr("value","Explain").appendTo($("#advancedSettingsForm"));
-            checkAndSubmit();
-        });
+      $("#saveQuery").click(function () {
+        $("<input>").attr("type", "hidden").attr("name", "saveform-name")
+                .attr("value", "${extract_field_data(form.saveform["name"])}").appendTo($("#advancedSettingsForm"));
+        $("<input>").attr("type", "hidden").attr("name", "saveform-desc")
+                .attr("value", "${extract_field_data(form.saveform["desc"])}").appendTo($("#advancedSettingsForm"));
+        $("<input>").attr("type", "hidden").attr("name", "saveform-save").attr("value", "Save").appendTo($("#advancedSettingsForm"));
+        checkAndSubmit();
+      });
 
-        $("#queryField").change(function(){
-            $(".query").val($(this).val());
-        });
+      $("#saveQueryAs").click(function () {
+        $("<input>").attr("type", "hidden").attr("name", "saveform-saveas").attr("value", "Save As...").appendTo($("#advancedSettingsForm"));
+        $("#saveAs").modal("show");
+      });
 
-        $("#queryField").focus(function(){
-            $(this).removeClass("fieldError");
-            $("#validationResults").empty();
-        });
+      $("#saveAsNameBtn").click(function () {
+        $("<input>").attr("type", "hidden").attr("name", "saveform-name")
+                .attr("value", $("input[name=saveform-name]").val()).appendTo($("#advancedSettingsForm"));
+        $("<input>").attr("type", "hidden").attr("name", "saveform-desc")
+                .attr("value", $("input[name=saveform-desc]").val()).appendTo($("#advancedSettingsForm"));
+        checkAndSubmit();
+      });
 
-        var selectedLine = -1;
-        if ($(".queryErrorMessage")){
-          var err = $(".queryErrorMessage").text().toLowerCase();
-          var firstPos = err.indexOf("line");
-          selectedLine = $.trim(err.substring(err.indexOf(" ", firstPos), err.indexOf(":", firstPos)))*1;
-        }
+      $("#explainQuery").click(function () {
+        $("<input>").attr("type", "hidden").attr("name", "button-explain").attr("value", "Explain").appendTo($("#advancedSettingsForm"));
+        checkAndSubmit();
+      });
 
       initQueryField();
 
@@ -559,12 +534,7 @@ ${layout.menubar(section='query')}
         resizeTimeout = window.setTimeout(function () {
           // prevents endless loop in IE8
           if (winWidth != $(window).width() || winHeight != $(window).height()) {
-            $("#queryField").unbind();
-            $("#queryField").data("scroll", $("#queryField").scrollTop());
-            $("#queryField").insertBefore($(".linedwrap"));
-            $("#queryField").css("width", "");
-            $(".linedwrap").remove();
-            initQueryField();
+            codeMirror.setSize("95%", $(window).height() - 270 - $("#queryPane .alert-error").outerHeight() - $(".nav-tabs").outerHeight());
             winWidth = $(window).width();
             winHeight = $(window).height();
           }
@@ -572,42 +542,67 @@ ${layout.menubar(section='query')}
       });
 
       function initQueryField() {
-        var _height = 100;
-        $("#querySide").children().not(".tab-content").each(function () {
-          _height += $(this).outerHeight();
-        });
-        $("#queryPane").children().not("textarea").each(function () {
-          _height += $(this).outerHeight();
-        });
-        var _newHeight = $(window).height() - $("#querySide").offset().top - _height;
-        if (_newHeight < 300) {
-          _newHeight = 300;
+        if ($("#queryField").val() == "") {
+          $("#queryField").val(queryPlaceholder);
         }
-        $("#queryField").height(_newHeight);
-        if (selectedLine > -1) {
-          $("#queryField").linedtextarea({
-            selectedLine: selectedLine
-          });
+      }
+
+      var queryEditor = $("#queryField")[0];
+
+      CodeMirror.commands.autocomplete = function (cm) {
+        CodeMirror.showHint(cm, CodeMirror.hiveQLHint);
+      }
+      var codeMirror = CodeMirror(function (elt) {
+        queryEditor.parentNode.replaceChild(elt, queryEditor);
+      }, {
+        value: queryEditor.value,
+        readOnly: false,
+        lineNumbers: true,
+        mode: "text/x-hiveql",
+        extraKeys: {
+          "Shift-Space": "autocomplete",
+          Tab: function (cm) {
+            $("#executeQuery").focus();
+          }
         }
-        else {
-          $("#queryField").linedtextarea();
+      });
+
+      var selectedLine = -1;
+      var errorWidget = null;
+      if ($(".queryErrorMessage").length > 0) {
+        var err = $(".queryErrorMessage").text().toLowerCase();
+        var firstPos = err.indexOf("line");
+        selectedLine = $.trim(err.substring(err.indexOf(" ", firstPos), err.indexOf(":", firstPos))) * 1;
+        errorWidget = codeMirror.addLineWidget(selectedLine - 1, $("<div>").addClass("editorError").html("<i class='icon-exclamation-sign'></i> " + err)[0], {coverGutter: true, noHScroll: true})
+      }
+
+      codeMirror.setSize("95%", $(window).height() - 270 - $("#queryPane .alert-error").outerHeight() - $(".nav-tabs").outerHeight());
+
+      codeMirror.on("focus", function () {
+        if (codeMirror.getValue() == queryPlaceholder) {
+          codeMirror.setValue("");
         }
-        $("#queryField").width($("#queryField").width() - 4); // fixes zooms problems
-        if ($("#queryField").data("scroll")) {
-          $("#queryField").scrollTop($("#queryField").data("scroll"));
+        if (errorWidget) {
+          errorWidget.clear();
         }
-      }
+        $("#validationResults").empty();
+      });
+
+      codeMirror.on("change", function () {
+        $(".query").val(codeMirror.getValue());
+      });
+
 
       function getHighlightedQuery() {
-        var selection = $("#queryField").getSelection();
-        if (selection) {
-            return selection.text;
+        var selection = codeMirror.getSelection();
+        if (selection != "") {
+          return selection;
         }
         return null;
       }
 
       function checkAndSubmit() {
-        var query = getHighlightedQuery() || $("#queryField").val();
+        var query = getHighlightedQuery() || codeMirror.getValue();
         $(".query").val(query);
         $("#advancedSettingsForm").submit();
       }

+ 1 - 1
apps/pig/src/pig/templates/app.mako

@@ -263,7 +263,7 @@ ${ commonheader(_('Pig'), "pig", user, "100px") | n,unicode }
 <link rel="stylesheet" href="/static/ext/css/codemirror.css">
 <script src="/static/ext/js/codemirror-pig.js"></script>
 <script src="/static/ext/js/codemirror-show-hint.js"></script>
-<script src="/static/ext/js/codemirror-pig-hint.js"></script>
+<script src="/static/js/Source/jHue/codemirror-pig-hint.js"></script>
 <link rel="stylesheet" href="/static/ext/css/codemirror-show-hint.css">
 
 

+ 0 - 68
desktop/core/static/ext/css/jquery-linedtextarea.css

@@ -1,68 +0,0 @@
-/**
- * jQuery Lined Textarea Plugin
- *   http://alan.blog-city.com/jquerylinedtextarea.htm
- *
- * Copyright (c) 2010 Alan Williamson
- *
- * Released under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- * 
- * Usage:
- *   Displays a line number count column to the left of the textarea
- *   
- *   Class up your textarea with a given class, or target it directly
- *   with JQuery Selectors
- *   
- *   $(".lined").linedtextarea({
- *   	selectedLine: 10,
- *    selectedClass: 'lineselect'
- *   });
- *
- */
-
-.linedwrap {
-  border: 1px solid #c0c0c0;
-  padding: 3px;
-}
-
-.linedtextarea {
-  padding: 0px;
-  margin: 0px;
-}
-
-.linedtextarea textarea, .linedwrap .codelines .lineno {
-  font-size: 10pt;
-  font-family: monospace;
-  line-height: normal !important;
-}
-
-.linedtextarea textarea {
-  padding-right: 0.3em;
-  padding-top: 0.3em;
-  border: 0;
-}
-
-.linedwrap .lines {
-  margin-top: 0px;
-  width: 50px;
-  float: left;
-  overflow: hidden;
-  border-right: 1px solid #c0c0c0;
-  margin-right: 10px;
-}
-
-.linedwrap .codelines {
-  padding-top: 5px;
-}
-
-.linedwrap .codelines .lineno {
-  color: #AAAAAA;
-  padding-right: 0.5em;
-  padding-top: 0.0em;
-  text-align: right;
-  white-space: nowrap;
-}
-
-.linedwrap .codelines .lineselect {
-  color: red;
-}

+ 0 - 113
desktop/core/static/ext/js/codemirror-pig-hint.js

@@ -1,113 +0,0 @@
-(function () {
-  function forEach(arr, f) {
-    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
-  }
-  
-  function arrayContains(arr, item) {
-    if (!Array.prototype.indexOf) {
-      var i = arr.length;
-      while (i--) {
-        if (arr[i] === item) {
-          return true;
-        }
-      }
-      return false;
-    }
-    return arr.indexOf(item) != -1;
-  }
-
-  function scriptHint(editor, _keywords, getToken) {
-    // Find the token at the cursor
-    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
-    // If it's not a 'word-style' token, ignore the token.
-
-    if (!/^[\w$_]*$/.test(token.string)) {
-        token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
-                         className: token.string == ":" ? "pig-type" : null};
-    }
-      
-    if (!context) var context = [];
-    context.push(tprop);
-    
-    var completionList = getCompletions(token, context); 
-    completionList = completionList.sort();
-    //prevent autocomplete for last word, instead show dropdown with one word
-    if(completionList.length == 1) {
-      completionList.push(" ");
-    }
-
-    return {list: completionList,
-            from: CodeMirror.Pos(cur.line, token.start),
-            to: CodeMirror.Pos(cur.line, token.end)};
-  }
-  
-  CodeMirror.pigHint = function(editor) {
-    return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
-  };
- 
-  var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
-  + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
-  + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
-  + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " 
-  + "NEQ MATCHES TRUE FALSE";
-  var pigKeywordsU = pigKeywords.split(" ");
-  var pigKeywordsL = pigKeywords.toLowerCase().split(" ");
-  
-  var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP";
-  var pigTypesU = pigTypes.split(" ");
-  var pigTypesL = pigTypes.toLowerCase().split(" ");
-  
-  var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL " 
-  + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
-  + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
-  + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
-  + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
-  + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
-  + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA  "
-  + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
-  + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
-  + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER";  
-  var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" ");  
-  var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" ");   
-  var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs "
-  + "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax "
-  + "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum "
-  + "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker "
-  + "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize "
-  + "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax "
-  + "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" ");
-                    
-  function getCompletions(token, context) {
-    var found = [], start = token.string;
-    function maybeAdd(str) {
-      if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
-    }
-    
-    function gatherCompletions(obj) {
-      if(obj == ":") {
-        forEach(pigTypesL, maybeAdd);
-      }
-      else {
-        forEach(pigBuiltinsU, maybeAdd);
-        forEach(pigBuiltinsL, maybeAdd);
-        forEach(pigBuiltinsC, maybeAdd);
-        forEach(pigTypesU, maybeAdd);
-        forEach(pigTypesL, maybeAdd);
-        forEach(pigKeywordsU, maybeAdd);
-        forEach(pigKeywordsL, maybeAdd);
-      }
-    }
-
-    if (context) {
-      // If this is a property, see if it belongs to some object we can
-      // find in the current environment.
-      var obj = context.pop(), base;
-      base = obj.string;
-
-      while (base != null && context.length)
-        base = base[context.pop().string];
-      if (base != null) gatherCompletions(base);
-    }
-    return found;
-  }
-})();

+ 0 - 126
desktop/core/static/ext/js/jquery/plugins/jquery-linedtextarea.js

@@ -1,126 +0,0 @@
-/**
- * jQuery Lined Textarea Plugin
- *   http://alan.blog-city.com/jquerylinedtextarea.htm
- *
- * Copyright (c) 2010 Alan Williamson
- *
- * Version:
- *    $Id: jquery-linedtextarea.js 464 2010-01-08 10:36:33Z alan $
- *
- * Released under the MIT License:
- *    http://www.opensource.org/licenses/mit-license.php
- *
- * Usage:
- *   Displays a line number count column to the left of the textarea
- *
- *   Class up your textarea with a given class, or target it directly
- *   with JQuery Selectors
- *
- *   $(".lined").linedtextarea({
- *   	selectedLine: 10,
- *    selectedClass: 'lineselect'
- *   });
- *
- * History:
- *   - 2010.01.08: Fixed a Google Chrome layout problem
- *   - 2010.01.07: Refactored code for speed/readability; Fixed horizontal sizing
- *   - 2010.01.06: Initial Release
- *
- */
-(function ($) {
-
-  $.fn.linedtextarea = function (options) {
-
-    // Get the Options
-    var opts = $.extend({}, $.fn.linedtextarea.defaults, options);
-
-
-    /*
-     * Helper function to make sure the line numbers are always
-     * kept up to the current system
-     */
-    var fillOutLines = function (codeLines, h, lineNo) {
-      while ((codeLines.height() - h ) <= 0) {
-        if (lineNo == opts.selectedLine)
-          codeLines.append("<div class='lineno lineselect'>" + lineNo + "</div>");
-        else
-          codeLines.append("<div class='lineno'>" + lineNo + "</div>");
-
-        lineNo++;
-      }
-      return lineNo;
-    };
-
-
-    /*
-     * Iterate through each of the elements are to be applied to
-     */
-    return this.each(function () {
-      var lineNo = 1;
-      var textarea = $(this);
-
-      /* Turn off the wrapping of as we don't want to screw up the line numbers */
-      textarea.attr("wrap", "off");
-      textarea.css({resize:'none'});
-      var originalTextAreaWidth = textarea.outerWidth();
-
-      /* Wrap the text area in the elements we need */
-      textarea.wrap("<div class='linedtextarea'></div>");
-      var linedTextAreaDiv = textarea.parent().wrap("<div class='linedwrap' style='width:" + originalTextAreaWidth + "px'></div>");
-      var linedWrapDiv = linedTextAreaDiv.parent();
-
-      linedWrapDiv.prepend("<div class='lines' style='width:50px'></div>");
-
-      var linesDiv = linedWrapDiv.find(".lines");
-      linesDiv.height(textarea.height() + 6);
-
-
-      /* Draw the number bar; filling it out where necessary */
-      linesDiv.append("<div class='codelines'></div>");
-      var codeLinesDiv = linesDiv.find(".codelines");
-      lineNo = fillOutLines(codeLinesDiv, linesDiv.height(), 1);
-
-
-      /* Set the width */
-      var sidebarWidth = linesDiv.outerWidth();
-      var paddingHorizontal = parseInt(linedWrapDiv.css("border-left-width")) + parseInt(linedWrapDiv.css("border-right-width")) + parseInt(linedWrapDiv.css("padding-left")) + parseInt(linedWrapDiv.css("padding-right"));
-      var linedWrapDivNewWidth = originalTextAreaWidth - paddingHorizontal;
-      var textareaNewWidth = originalTextAreaWidth - sidebarWidth - paddingHorizontal - 20;
-
-      textarea.width(textareaNewWidth);
-      linedWrapDiv.width(linedWrapDivNewWidth);
-
-
-      /* React to the scroll event */
-      textarea.scroll(function (tn) {
-        var domTextArea = $(this)[0];
-        var scrollTop = domTextArea.scrollTop;
-        var clientHeight = domTextArea.clientHeight;
-        codeLinesDiv.css({'margin-top':(-1 * scrollTop) + "px"});
-        lineNo = fillOutLines(codeLinesDiv, scrollTop + clientHeight, lineNo);
-      });
-
-
-      /* Should the textarea get resized outside of our control */
-      textarea.resize(function (tn) {
-        var domTextArea = $(this)[0];
-        linesDiv.height(domTextArea.clientHeight + 6);
-      });
-
-      /* Move the textarea to the selected line */
-      if (opts.selectedLine != -1 && !isNaN(opts.selectedLine)) {
-        var fontSize = parseInt(textarea.height() / (lineNo - 2));
-        var position = parseInt(fontSize * opts.selectedLine) - (textarea.height() / 2);
-        textarea[0].scrollTop = position;
-      }
-
-
-    });
-  };
-
-  // default options
-  $.fn.linedtextarea.defaults = {
-    selectedLine:-1,
-    selectedClass:'lineselect'
-  };
-})(jQuery);

+ 111 - 0
desktop/core/static/js/Source/jHue/codemirror-hql-hint.js

@@ -0,0 +1,111 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+(function () {
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, _keywords, getToken) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    // If it's not a 'word-style' token, ignore the token.
+
+    if (!/^[\w$_]*$/.test(token.string)) {
+      token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+        className: token.string == ":" ? "hiveql-type" : null};
+    }
+
+    if (!context) var context = [];
+    context.push(tprop);
+
+    var completionList = getCompletions(token, context);
+    completionList = completionList.sort();
+    //prevent autocomplete for last word, instead show dropdown with one word
+    if (completionList.length == 1) {
+      completionList.push(" ");
+    }
+
+    return {list: completionList,
+      from: CodeMirror.Pos(cur.line, token.start),
+      to: CodeMirror.Pos(cur.line, token.end)};
+  }
+
+  CodeMirror.hiveQLHint = function (editor) {
+    return scriptHint(editor, hiveQLKeywordsU, function (e, cur) {
+      return e.getTokenAt(cur);
+    });
+  };
+
+  var hiveQLKeywords = "ADD AFTER ALL ALTER AND ARCHIVE AS ASC BETWEEN BUCKET BUCKETS BY CASCADE CHANGE CLI CLUSTER CLUSTERED COALESCE COLLECTION COLUMN COLUMNS COMMENT CREATE CROSS DATA DATABASE DATABASES DBPROPERTIES DEFERRED DELIMITED DEPENDENCY DESC DESCRIBE DIRECTORY DISABLE DISTINCT DISTRIBUTE DOT DROP ENABLE ESCAPED EXISTS EXPLAIN EXPORT EXTENDED EXTERNAL FIELDS FILEFORMAT FIRST FORMAT FORMATTED FROM FULL FUNCTION FUNCTIONS GRANT GROUP HAVING IDXPROPERTIES IF IGNORE IMPORT IN INDEX INDEXES INPATH INSERT INTO IS ITEMS JOIN KEYS LATERAL LEFT LIKE LIMIT LINES LOAD LOCAL LOCATION LOCKS MAP MAPJOIN MSCK NOT OF OFFLINE ON OPTION ORDER OUT OUTER OVERWRITE PARTITION PARTITIONED PARTITIONS PERCENT PRIVILEGES PROTECTION REBUILD RECORDREADER RECOVER REDUCE REGEXP RENAME REPAIR REPLACE RESTRICT REVOKE RIGHT RLIKE ROLE ROW SCHEMA SCHEMAS SELECT SEMI SEPARATED SERDE SERDEPROPERTIES SET SHOW SKEWED SORT SORTED STORED SUM TABLE TABLES TABLESAMPLE TBLPROPERTIES TEMPORARY TERMINATED TO TOUCH TRANSFORM TRUNCATE UNARCHIVE UNION US USER USING VIEW WHERE WITH";
+  var hiveQLKeywordsU = hiveQLKeywords.split(" ");
+  var hiveQLKeywordsL = hiveQLKeywords.toLowerCase().split(" ");
+
+  var hiveQLTypes = "TINYINT SMALLINT INT BIGINT BOOLEAN FLOAT DOUBLE STRING BINARY TIMESTAMP DECIMAL ARRAY MAP STRUCT UNIONTYPE DELIMITED SERDE SEQUENCEFILE TEXTFILE RCFILE INPUTFORMAT OUTPUTFORMAT";
+  var hiveQLTypesU = hiveQLTypes.split(" ");
+  var hiveQLTypesL = hiveQLTypes.toLowerCase().split(" ");
+
+  var hiveQLBuiltins = "ROUND FLOOR CEIL CEILING RAND EXP LN LOG10 LOG2 LOG POW POWER SQRT BIN HEX UNHEX CONV ABS PMOD SIN ASIN COS ACOS TAN ATAN DEGREES RADIANS POSITIVE NEGATIVE SIGN E PI SIZE MAP_KEYS MAP_VALUES ARRAY_CONTAINS SORT_ARRAY BINARY CAST FROM_UNIXTIME UNIX_TIMESTAMP TO_DATE YEAR MONTH DAY HOUR MINUTE SECOND WEEKOFYEAR DATEDIFF DATE_ADD DATE_SUB FROM_UTC_TIMESTAMP TO_UTC_TIMESTAMP ASCII CONCAT CONTEXT_NGRAMS CONCAT_WS FIND_IN_SET FORMAT_NUMBER GET_JSON_OBJECT IN_FILE INSTR LENGTH LOCATE LOWER LCASE LPAD LTRIM NGRAMS PARSE_URL PRINTF REGEXP_EXTRACT REGEXP_REPLACE REPEAT REVERSE RPAD RTRIM SENTENCES SPACE SPLIT STR_TO_MAP SUBSTR SUBSTRING TRANSLATE TRIM UPPER UCASE JAVA_METHOD REFLECT XPATH XPATH_SHORT XPATH_INT XPATH_LONG XPATH_FLOAT XPATH_DOUBLE XPATH_NUMBER XPATH_STRING COUNT SUM AVG MIN MAX VARIANCE VAR_SAMP STDEV_POP STDEV_SAMP COVAR_POP COVAR_SAMP CORR PERCENTILE PERCENTILE_APPROX HISTOGRAM_NUMERIC COLLECT_SET INLINE EXPLODE JSON_TUPLE PARSE_URL_TUPLE GET_JSON_OBJECT";
+  var hiveQLBuiltinsU = hiveQLBuiltins.split(" ").join("() ").split(" ");
+  var hiveQLBuiltinsL = hiveQLBuiltins.toLowerCase().split(" ").join("() ").split(" ");
+
+  function getCompletions(token, context) {
+    var found = [], start = token.string;
+
+    function maybeAdd(str) {
+      if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+
+    function gatherCompletions(obj) {
+      if (obj == ":") {
+        forEach(hiveQLTypesL, maybeAdd);
+      }
+      else {
+        forEach(hiveQLBuiltinsU, maybeAdd);
+        forEach(hiveQLBuiltinsL, maybeAdd);
+        forEach(hiveQLTypesU, maybeAdd);
+        forEach(hiveQLTypesL, maybeAdd);
+        forEach(hiveQLKeywordsU, maybeAdd);
+        forEach(hiveQLKeywordsL, maybeAdd);
+      }
+    }
+
+    if (context) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+      base = obj.string;
+
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    }
+    return found;
+  }
+})();

File diff suppressed because it is too large
+ 245 - 0
desktop/core/static/js/Source/jHue/codemirror-hql.js


+ 132 - 0
desktop/core/static/js/Source/jHue/codemirror-pig-hint.js

@@ -0,0 +1,132 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+(function () {
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, _keywords, getToken) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    // If it's not a 'word-style' token, ignore the token.
+
+    if (!/^[\w$_]*$/.test(token.string)) {
+      token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+        className: token.string == ":" ? "pig-type" : null};
+    }
+
+    if (!context) var context = [];
+    context.push(tprop);
+
+    var completionList = getCompletions(token, context);
+    completionList = completionList.sort();
+    //prevent autocomplete for last word, instead show dropdown with one word
+    if (completionList.length == 1) {
+      completionList.push(" ");
+    }
+
+    return {list: completionList,
+      from: CodeMirror.Pos(cur.line, token.start),
+      to: CodeMirror.Pos(cur.line, token.end)};
+  }
+
+  CodeMirror.pigHint = function (editor) {
+    return scriptHint(editor, pigKeywordsU, function (e, cur) {
+      return e.getTokenAt(cur);
+    });
+  };
+
+  var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
+      + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
+      + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
+      + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
+      + "NEQ MATCHES TRUE FALSE";
+  var pigKeywordsU = pigKeywords.split(" ");
+  var pigKeywordsL = pigKeywords.toLowerCase().split(" ");
+
+  var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP";
+  var pigTypesU = pigTypes.split(" ");
+  var pigTypesL = pigTypes.toLowerCase().split(" ");
+
+  var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
+      + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
+      + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
+      + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
+      + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
+      + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
+      + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA  "
+      + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
+      + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
+      + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER";
+  var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" ");
+  var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" ");
+  var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs "
+      + "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax "
+      + "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum "
+      + "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker "
+      + "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize "
+      + "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax "
+      + "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" ");
+
+  function getCompletions(token, context) {
+    var found = [], start = token.string;
+
+    function maybeAdd(str) {
+      if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+
+    function gatherCompletions(obj) {
+      if (obj == ":") {
+        forEach(pigTypesL, maybeAdd);
+      }
+      else {
+        forEach(pigBuiltinsU, maybeAdd);
+        forEach(pigBuiltinsL, maybeAdd);
+        forEach(pigBuiltinsC, maybeAdd);
+        forEach(pigTypesU, maybeAdd);
+        forEach(pigTypesL, maybeAdd);
+        forEach(pigKeywordsU, maybeAdd);
+        forEach(pigKeywordsL, maybeAdd);
+      }
+    }
+
+    if (context) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+      base = obj.string;
+
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    }
+    return found;
+  }
+})();

Some files were not shown because too many files changed in this diff