Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master b4b4f5521 -> eebae39a2


ZEPPELIN-219: Paragaph mode auto-detection - initial impl

Here are the mode autodetection rules (and optimizations):
- Evaluates the editor mode on each `aceChange` event.
- (Optimization 1) Evaluates the mode only if the cursor is within the first 30 
characters of the buffer.
- (Optimization 2) Sets the mode (e.g. `session.setMode(new mode)` ) only if 
the new mode differs from the previous one.

Also the mode tag detection structure is refactored to bring together the 
interpreter tag test and the mode reference. The convention looks like this:
```javascript
  var editorModes = [
     [<Your Mode 1 Reg Expression Test>, <ACE Mode 1>],
     ......
     [<Your Mode N Reg Expression Test>, <ACE Mode N>]
  ];
```
For example:
```javascript
  var editorModes = [
     [/^%spark/, 'ace/mode/scala'],
     [/^%(\w*\.)?\wql/, 'ace/mode/sql'],
     [/^%md/, 'ace/mode/markdown'],
     [/^%sh/, 'ace/mode/sh']
  ];
```

Author: Damien Corneau <[email protected]>
Author: tzolov <[email protected]>

Closes #206 from tzolov/ZEPPELIN-219 and squashes the following commits:

fda3f5e [Damien Corneau] Improve loop performances
153f327 [Damien Corneau] Change setParagraphMode function
ea76881 [tzolov] ZEPPELIN-219: Add paragraph text as setPargraphMode() argument
aab3b7c [tzolov] ZEPPELIN-219: Paragaph mode auto-detection - initial impl


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/eebae39a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/eebae39a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/eebae39a

Branch: refs/heads/master
Commit: eebae39a226c4a62823623889a3535d1e0f83668
Parents: b4b4f55
Author: Damien Corneau <[email protected]>
Authored: Thu Aug 27 12:40:12 2015 +0900
Committer: Lee moon soo <[email protected]>
Committed: Wed Sep 9 07:33:15 2015 -0700

----------------------------------------------------------------------
 .../src/app/notebook/notebook.controller.js     |   2 +-
 .../notebook/paragraph/paragraph.controller.js  | 105 +++++++++++--------
 .../websocketEvents/websocketMsg.service.js     |   2 +-
 3 files changed, 65 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/eebae39a/zeppelin-web/src/app/notebook/notebook.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js 
b/zeppelin-web/src/app/notebook/notebook.controller.js
index d5f3024..196ccd3 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -160,7 +160,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', 
function($scope, $ro
   $scope.startSaveTimer = function() {
     $scope.killSaveTimer();
     $scope.isNoteDirty = true;
-    console.log('startSaveTimer called ' + $scope.note.id);
+    //console.log('startSaveTimer called ' + $scope.note.id);
     $scope.saveTimer = $timeout(function(){
       $scope.saveNote();
     }, 10000);

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/eebae39a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js 
b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index be4578b..c1cd48b 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -22,8 +22,12 @@ angular.module('zeppelinWebApp')
   $scope.paragraph = null;
   $scope.editor = null;
 
-  var editorMode = {scala: 'ace/mode/scala', sql: 'ace/mode/sql', markdown: 
'ace/mode/markdown', 
-                 sh: 'ace/mode/sh'};
+  var editorModes = {
+    'ace/mode/scala': /^%spark/,
+    'ace/mode/sql': /^%(\w*\.)?\wql/,
+    'ace/mode/markdown': /^%md/,
+    'ace/mode/sh': /^%sh/
+  };
 
   // Controller init
   $scope.init = function(newParagraph) {
@@ -420,8 +424,13 @@ angular.module('zeppelinWebApp')
   };
 
   $scope.aceChanged = function() {
+
     $scope.dirtyText = $scope.editor.getSession().getValue();
     $scope.startSaveTimer();
+
+    $timeout(function() {
+      $scope.setParagraphMode($scope.editor.getSession(), $scope.dirtyText, 
$scope.editor.getCursorPosition());
+    });
   };
 
   $scope.aceLoaded = function(_editor) {
@@ -448,54 +457,66 @@ angular.module('zeppelinWebApp')
         // not applying emacs key binding while the binding override Ctrl-v. 
default behavior of paste text on windows.
       }
 
-      var sqlModeTest = /^%(\w*\.)?\wql/;
-
-      $scope.setParagraphMode = function(session, paragraphText) {
-        if (sqlModeTest.test(String(paragraphText))) {
-          session.setMode(editorMode.sql);
-        } else if ( String(paragraphText).startsWith('%md')) {
-          session.setMode(editorMode.markdown);
-        } else if ( String(paragraphText).startsWith('%sh')) {
-          session.setMode(editorMode.sh);
-        } else {
-          session.setMode(editorMode.scala);
+      $scope.setParagraphMode = function(session, paragraphText, pos) {
+        // Evaluate the mode only if the first 30 characters of the paragraph 
have been modified or the the position is undefined.
+        if ( (typeof pos === 'undefined') || (pos.row === 0 && pos.column < 
30)) {
+          // If paragraph loading, use config value if exists
+          if ((typeof pos === 'undefined') && 
$scope.paragraph.config.editorMode) {
+            session.setMode($scope.paragraph.config.editorMode);
+          } else {
+            // Defaults to spark mode
+            var newMode = 'ace/mode/scala';
+            // Test first against current mode
+            var oldMode = session.getMode().$id;
+            if (!editorModes[oldMode] || 
!editorModes[oldMode].test(paragraphText)) {
+              for (var key in editorModes) {
+                if (key !== oldMode) {
+                  if (editorModes[key].test(paragraphText)){
+                    $scope.paragraph.config.editorMode = key;
+                    session.setMode(key);
+                    return true;
+                  }
+                }
+              }
+              $scope.paragraph.config.editorMode = newMode;
+              session.setMode(newMode);
+            }
+          }
         }
       };
 
       var remoteCompleter = {
-          getCompletions : function(editor, session, pos, prefix, callback) {
-              if (!$scope.editor.isFocused() ){ return;}
-
-              pos = session.getTextRange(new Range(0, 0, pos.row, 
pos.column)).length;
-              var buf = session.getValue();
-
-              // ensure the correct mode is set
-              $scope.setParagraphMode(session, buf);
-              websocketMsgSrv.completion($scope.paragraph.id, buf, pos);
-
-              $scope.$on('completionList', function(event, data) {
-                  if (data.completions) {
-                      var completions = [];
-                      for (var c in data.completions) {
-                          var v = data.completions[c];
-                          completions.push({
-                              name:v,
-                              value:v,
-                              score:300
-                          });
-                      }
-                      callback(null, completions);
-                  }
-              });
-          }
+        getCompletions : function(editor, session, pos, prefix, callback) {
+          if (!$scope.editor.isFocused() ){ return;}
+
+          pos = session.getTextRange(new Range(0, 0, pos.row, 
pos.column)).length;
+          var buf = session.getValue();
+
+          websocketMsgSrv.completion($scope.paragraph.id, buf, pos);
+
+          $scope.$on('completionList', function(event, data) {
+            if (data.completions) {
+              var completions = [];
+              for (var c in data.completions) {
+                var v = data.completions[c];
+                completions.push({
+                  name:v,
+                  value:v,
+                  score:300
+                });
+              }
+              callback(null, completions);
+            }
+          });
+        }
       };
 
       langTools.setCompleters([remoteCompleter, langTools.keyWordCompleter, 
langTools.snippetCompleter, langTools.textCompleter]);
 
       $scope.editor.setOptions({
-          enableBasicAutocompletion: true,
-          enableSnippets: false,
-          enableLiveAutocompletion:false
+        enableBasicAutocompletion: true,
+        enableSnippets: false,
+        enableLiveAutocompletion:false
       });
 
       $scope.handleFocus = function(value) {
@@ -590,7 +611,7 @@ angular.module('zeppelinWebApp')
 
   $scope.getProgress = function() {
     return ($scope.currentProgress) ? $scope.currentProgress : 0;
-  };                                           
+  };
 
   $scope.getExecutionTime = function() {
     var pdata = $scope.paragraph;

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/eebae39a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
----------------------------------------------------------------------
diff --git 
a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js 
b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
index 1323462..e74cfd0 100644
--- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
+++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
@@ -29,7 +29,7 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', 
function($rootScope,
       websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}});
     },
 
-       cloneNotebook: function(noteIdToClone, newNoteName ) {
+    cloneNotebook: function(noteIdToClone, newNoteName ) {
       websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: 
noteIdToClone, name: newNoteName}});
     },
     getNotebookList: function() {

Reply via email to