From aab3b7cf9ec1e15fab66aec150c065834a79aba8 Mon Sep 17 00:00:00 2001 From: tzolov Date: Wed, 12 Aug 2015 23:34:50 +0200 Subject: [PATCH 1/4] ZEPPELIN-219: Paragaph mode auto-detection - initial impl --- .../paragraph/paragraph.controller.js | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index be4578bbb4d..428e826cee7 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 = [ + [/^%spark/, 'ace/mode/scala'], + [/^%(\w*\.)?\wql/, 'ace/mode/sql'], + [/^%md/, 'ace/mode/markdown'], + [/^%sh/, 'ace/mode/sh'] + ]; // Controller init $scope.init = function(newParagraph) { @@ -422,6 +426,9 @@ angular.module('zeppelinWebApp') $scope.aceChanged = function() { $scope.dirtyText = $scope.editor.getSession().getValue(); $scope.startSaveTimer(); + $timeout(function() { + $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getCursorPosition()); + }); }; $scope.aceLoaded = function(_editor) { @@ -448,18 +455,25 @@ 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, pos) { + var paragraphText = session.getValue(); - $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); - } + // Evaluate the mode only if the change is at the beging of the paragraph + if (pos.row === 0 && pos.column < 30) { + var newMode = editorModes[0][1]; + + for (var i = 0, len = editorModes.length; i < len; i++ ) { + var modeElement = editorModes[i]; + if (modeElement[0].test(paragraphText)) { + newMode = modeElement[1]; + break; + } + } + + if (String(newMode).localeCompare(String(session.getMode().$id)) !== 0) { + session.setMode(newMode); + } + } }; var remoteCompleter = { @@ -469,8 +483,6 @@ angular.module('zeppelinWebApp') 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) { @@ -522,7 +534,7 @@ angular.module('zeppelinWebApp') $scope.editor.resize(); }); - $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getSession().getValue()); + $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getCursorPosition()); $scope.editor.commands.addCommand({ name: 'run', From ea76881d776768e1f0cb737b299e90c5ba50ddde Mon Sep 17 00:00:00 2001 From: tzolov Date: Thu, 13 Aug 2015 09:36:24 +0200 Subject: [PATCH 2/4] ZEPPELIN-219: Add paragraph text as setPargraphMode() argument --- .../paragraph/paragraph.controller.js | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 428e826cee7..cb315037dcc 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -424,10 +424,12 @@ angular.module('zeppelinWebApp') }; $scope.aceChanged = function() { + $scope.dirtyText = $scope.editor.getSession().getValue(); $scope.startSaveTimer(); + $timeout(function() { - $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getCursorPosition()); + $scope.setParagraphMode($scope.editor.getSession(), $scope.dirtyText, $scope.editor.getCursorPosition()); }); }; @@ -455,25 +457,28 @@ angular.module('zeppelinWebApp') // not applying emacs key binding while the binding override Ctrl-v. default behavior of paste text on windows. } - $scope.setParagraphMode = function(session, pos) { - var paragraphText = session.getValue(); + $scope.setParagraphMode = function(session, paragraphText, pos) { - // Evaluate the mode only if the change is at the beging of the paragraph - if (pos.row === 0 && pos.column < 30) { - var newMode = editorModes[0][1]; + // 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)) { - for (var i = 0, len = editorModes.length; i < len; i++ ) { - var modeElement = editorModes[i]; - if (modeElement[0].test(paragraphText)) { - newMode = modeElement[1]; - break; - } - } + // Defaults to spark mode (ditorModes[0][1] == %spark). + var newMode = editorModes[0][1]; - if (String(newMode).localeCompare(String(session.getMode().$id)) !== 0) { - session.setMode(newMode); - } + for (var i = 0, len = editorModes.length; i < len; i++) { + var modeElement = editorModes[i]; + if (modeElement[0].test(paragraphText)){ + newMode = modeElement[1]; + break; + } } + + // Update to the new mode only if it differs from the existing one. + var oldMode = session.getMode().$id; + if (String(newMode).localeCompare(String(oldMode)) !== 0) { + session.setMode(newMode); + } + } }; var remoteCompleter = { @@ -534,7 +539,7 @@ angular.module('zeppelinWebApp') $scope.editor.resize(); }); - $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getCursorPosition()); + $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getSession().getValue()); $scope.editor.commands.addCommand({ name: 'run', From 153f3273ab6a164ba9d92d0eafd39ded34bf269b Mon Sep 17 00:00:00 2001 From: Damien Corneau Date: Wed, 26 Aug 2015 17:31:27 +0900 Subject: [PATCH 3/4] Change setParagraphMode function --- .../src/app/notebook/notebook.controller.js | 2 +- .../paragraph/paragraph.controller.js | 99 ++++++++++--------- .../websocketEvents/websocketMsg.service.js | 2 +- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index d5f30241d5e..196ccd3634b 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); diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index cb315037dcc..065b84db7f0 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -23,10 +23,10 @@ angular.module('zeppelinWebApp') $scope.editor = null; var editorModes = [ - [/^%spark/, 'ace/mode/scala'], - [/^%(\w*\.)?\wql/, 'ace/mode/sql'], - [/^%md/, 'ace/mode/markdown'], - [/^%sh/, 'ace/mode/sh'] + [/^%spark/, 'ace/mode/scala'], + [/^%(\w*\.)?\wql/, 'ace/mode/sql'], + [/^%md/, 'ace/mode/markdown'], + [/^%sh/, 'ace/mode/sh'] ]; // Controller init @@ -458,61 +458,66 @@ angular.module('zeppelinWebApp') } $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. + // 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)) { - // Defaults to spark mode (ditorModes[0][1] == %spark). - var newMode = editorModes[0][1]; - - for (var i = 0, len = editorModes.length; i < len; i++) { - var modeElement = editorModes[i]; - if (modeElement[0].test(paragraphText)){ - newMode = modeElement[1]; - break; + // If paragraph loading, use config value if exists + if ((typeof pos === 'undefined') && $scope.paragraph.config.editorMode) { + session.setMode($scope.paragraph.config.editorMode); + } else { + // Test first against current mode + var oldMode = session.getMode().$id; + if (!oldMode.test(paragraphText)) { + // Defaults to spark mode (editorModes[0][1] == %spark). + var newMode = editorModes[0][1]; + + for (var i = 0, len = editorModes.length; i < len; i++) { + var modeElement = editorModes[i]; + if (modeElement[0].test(paragraphText)){ + newMode = modeElement[1]; + break; + } + } + // set the newMode in the paragraph config + $scope.paragraph.config.editorMode = newMode; + session.setMode(newMode); } } - - // Update to the new mode only if it differs from the existing one. - var oldMode = session.getMode().$id; - if (String(newMode).localeCompare(String(oldMode)) !== 0) { - 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(); - - 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) { @@ -607,7 +612,7 @@ angular.module('zeppelinWebApp') $scope.getProgress = function() { return ($scope.currentProgress) ? $scope.currentProgress : 0; - }; + }; $scope.getExecutionTime = function() { var pdata = $scope.paragraph; diff --git a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js index 13234626db9..e74cfd04926 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() { From fda3f5e525682e28dfac5117aeb005f2f9829782 Mon Sep 17 00:00:00 2001 From: Damien Corneau Date: Thu, 27 Aug 2015 12:40:12 +0900 Subject: [PATCH 4/4] Improve loop performances --- .../paragraph/paragraph.controller.js | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 065b84db7f0..c1cd48b40a6 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -22,12 +22,12 @@ angular.module('zeppelinWebApp') $scope.paragraph = null; $scope.editor = null; - var editorModes = [ - [/^%spark/, 'ace/mode/scala'], - [/^%(\w*\.)?\wql/, 'ace/mode/sql'], - [/^%md/, '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) { @@ -460,25 +460,24 @@ angular.module('zeppelinWebApp') $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 (!oldMode.test(paragraphText)) { - // Defaults to spark mode (editorModes[0][1] == %spark). - var newMode = editorModes[0][1]; - - for (var i = 0, len = editorModes.length; i < len; i++) { - var modeElement = editorModes[i]; - if (modeElement[0].test(paragraphText)){ - newMode = modeElement[1]; - break; + 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; + } } } - // set the newMode in the paragraph config $scope.paragraph.config.editorMode = newMode; session.setMode(newMode); }