diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index d66fb761f21..d977f5e4188 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -16,12 +16,14 @@
angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $rootScope, $route, $window,
$routeParams, $location, $timeout, $compile,
$http, websocketMsgSrv, baseUrlSrv, ngToast,
- saveAsService, esriLoader) {
+ saveAsService, esriLoader, editorConfigSrv) {
var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_';
$scope.parentNote = null;
$scope.paragraph = null;
$scope.originalText = '';
$scope.editor = null;
+ $scope.defaultEditorConfig = editorConfigSrv.getDefaultEditorSetting();
+ $scope.userEditorConfig = $scope.defaultEditorConfig;
var paragraphScope = $rootScope.$new(true, $rootScope);
@@ -78,13 +80,67 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $r
var angularObjectRegistry = {};
- var editorModes = {
- 'ace/mode/python': /^%(\w*\.)?(pyspark|python)\s*$/,
- 'ace/mode/scala': /^%(\w*\.)?spark\s*$/,
- 'ace/mode/r': /^%(\w*\.)?(r|sparkr|knitr)\s*$/,
- 'ace/mode/sql': /^%(\w*\.)?\wql/,
- 'ace/mode/markdown': /^%md/,
- 'ace/mode/sh': /^%sh/
+ $rootScope.$on('updateEditorSettings', function() {
+ console.log('change to paragraph editor theme', $scope.defaultEditorConfig);
+ $scope.defaultEditorConfig = editorConfigSrv.getDefaultEditorSetting();
+ $scope.userEditorConfig = $scope.defaultEditorConfig;
+ $scope.setParagraphMode(
+ $scope.editor.getSession(),
+ $scope.paragraph.text,
+ {row: 0, column: 0}
+ );
+ });
+
+ $scope.setEditorConfig = function(newValue, oldValue) {
+ if (newValue === undefined && oldValue === undefined) {
+ if ($scope.editor !== null) {
+ $scope.editor.renderer.setShowGutter(false);
+ $scope.editor.setHighlightGutterLine(false);
+ $scope.editor.getSession().setMode('ace/mode/scala');
+ $scope.editor.setHighlightActiveLine(false);
+ $scope.editor.getSession().setTabSize(4);
+ $scope.editor.setTheme('ace/theme/chrome');
+ $scope.editor.setShowFoldWidgets(true);
+ $scope.editor.setOptions({
+ enableBasicAutocompletion: true,
+ enableSnippets: false,
+ enableLiveAutocompletion: false,
+ fontSize: 12
+ });
+
+ $scope.editor.setShowPrintMargin(false);
+ $scope.editor.setPrintMarginColumn(false);
+ }
+ $scope.paragraph.config.editorMode = 'ace/mode/scala';
+ return;
+ }
+
+ var targetEditorConfig = newValue !== undefined ? newValue : oldValue;
+ var isShowLineNumberValue = $scope.paragraph.config.lineNumbers;
+
+ // show line number option precious order (paragraph setting > user theme)
+ if (isShowLineNumberValue === undefined) {
+ isShowLineNumberValue = targetEditorConfig.isShowNumberLine();
+ }
+
+ $scope.editor.renderer.setShowGutter(isShowLineNumberValue);
+ $scope.editor.setHighlightGutterLine(isShowLineNumberValue);
+ $scope.editor.getSession().setMode(targetEditorConfig.getMode());
+ $scope.editor.setHighlightActiveLine(targetEditorConfig.isActiveLine());
+ $scope.editor.getSession().setTabSize(targetEditorConfig.getTabSize());
+ $scope.editor.setTheme(targetEditorConfig.getTheme());
+ $scope.editor.setShowFoldWidgets(true);
+ $scope.editor.setOptions({
+ enableBasicAutocompletion: true,
+ enableSnippets: false,
+ enableLiveAutocompletion: targetEditorConfig.isLiveAutoCompletion(),
+ fontSize: targetEditorConfig.getFontSizeHtmlFormat()
+ });
+ $scope.editor.setShowPrintMargin(targetEditorConfig.isShowPrintMargin());
+ $scope.editor.setPrintMarginColumn(targetEditorConfig.getShowPrintMarginColumn());
+ $scope.paragraph.config.editorMode = targetEditorConfig.getMode();
+
+ $scope.userEditorConfig = targetEditorConfig;
};
// Controller init
@@ -549,18 +605,13 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $r
$scope.editor = _editor;
$scope.editor.on('input', $scope.aceChanged);
if (_editor.container.id !== '{{paragraph.id}}_editor') {
- $scope.editor.renderer.setShowGutter($scope.paragraph.config.lineNumbers);
- $scope.editor.setShowFoldWidgets(false);
- $scope.editor.setHighlightActiveLine(false);
- $scope.editor.setHighlightGutterLine(false);
- $scope.editor.getSession().setUseWrapMode(true);
- $scope.editor.setTheme('ace/theme/chrome');
- $scope.editor.setReadOnly($scope.isRunning());
if ($scope.paragraphFocused) {
$scope.editor.focus();
$scope.goToEnd();
}
+ // set default editor config
+ $scope.setEditorConfig($scope.userEditorConfig, null);
autoAdjustEditorHeight(_editor.container.id);
angular.element(window).resize(function() {
autoAdjustEditorHeight(_editor.container.id);
@@ -583,23 +634,10 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $r
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 tempEditorConfig = editorConfigSrv.findGetEditorConfigFromInterpreterTag(paragraphText);
+ $scope.setEditorConfig(tempEditorConfig, $scope.userEditorConfig);
+ return true;
}
}
};
@@ -633,12 +671,6 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $r
langTools.setCompleters([remoteCompleter, langTools.keyWordCompleter, langTools.snippetCompleter,
langTools.textCompleter]);
- $scope.editor.setOptions({
- enableBasicAutocompletion: true,
- enableSnippets: false,
- enableLiveAutocompletion: false
- });
-
$scope.handleFocus = function(value, isDigestPass) {
$scope.paragraphFocused = value;
if (isDigestPass === false || isDigestPass === undefined) {
@@ -662,7 +694,7 @@ angular.module('zeppelinWebApp').controller('ParagraphCtrl', function($scope, $r
autoAdjustEditorHeight(_editor.container.id);
});
- $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getSession().getValue());
+ $scope.setParagraphMode($scope.editor.getSession(), $scope.editor.getSession().getValue(), {row: 0, column: 0});
// autocomplete on '.'
/*
diff --git a/zeppelin-web/src/components/editor-config/editor.config.service.js b/zeppelin-web/src/components/editor-config/editor.config.service.js
new file mode 100644
index 00000000000..09c86113060
--- /dev/null
+++ b/zeppelin-web/src/components/editor-config/editor.config.service.js
@@ -0,0 +1,318 @@
+/*
+ * Licensed 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.
+ */
+'use strict';
+
+angular.module('zeppelinWebApp').service('editorConfigSrv', function($q) {
+
+ var builtInConfig = {
+ editorSettings: [
+ {
+ userConfig:
+ {
+ modeName: 'Scala Spark',
+ language: 'scala',
+ modeRegex: '^%(spark)(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ },
+ {
+ userConfig:
+ {
+ modeName: 'Python',
+ language: 'python',
+ modeRegex: '^%(pyspark|python)(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ },
+ {
+ userConfig: {
+ modeName: 'R',
+ language: 'r',
+ modeRegex: '^%(r|sparkr|knitr)(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ },
+ {
+ userConfig: {
+ modeName: 'SQL',
+ language: 'sql',
+ modeRegex: '^%(jdbc|sql)(\(.+\))*(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ },
+ {
+ userConfig:
+ {
+ modeName: 'Markdown',
+ language: 'markdown',
+ modeRegex: '^%(md)(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ },
+ {
+ userConfig:
+ {
+ modeName: 'Sh',
+ language: 'sh',
+ modeRegex: '^%(sh)(\ |\n)+.*',
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ }
+ }
+ ]
+ };
+
+ var EditorConfigObject = {
+ userConfig: {},
+ setUserConfig: function(newConfig) {
+ this.userConfig = newConfig;
+ },
+ getUserConfig: function() {
+ return this.userConfig;
+ },
+ getLanguage: function() {
+ return this.userConfig.language;
+ },
+ getModeName: function() {
+ return this.userConfig.modeName;
+ },
+ getMode: function() {
+ return 'ace/mode/' + this.userConfig.language;
+ },
+ getModeRegex: function() {
+ return this.userConfig.modeRegex;
+ },
+ getThemeName: function() {
+ return this.userConfig.setting.theme;
+ },
+ getTheme: function() {
+ return 'ace/theme/' + this.userConfig.setting.theme;
+ },
+ getTabSize: function() {
+ return this.userConfig.setting.tabSize;
+ },
+ getShowPrintMarginColumn: function() {
+ return this.userConfig.setting.showPrintMarginColumn;
+ },
+ getFontFamily: function() {
+ return this.userConfig.setting.fontFamily;
+ },
+ getFontSize: function() {
+ return this.userConfig.setting.fontSize;
+ },
+ getFontSizeHtmlFormat: function() {
+ return this.userConfig.setting.fontSize + 'pt';
+ },
+ isShowNumberLine: function() {
+ return this.userConfig.setting.showLineNumber;
+ },
+ isActiveLine: function() {
+ return this.userConfig.setting.activeLine;
+ },
+ isShowPrintMargin: function() {
+ return this.userConfig.setting.showPrintMargin;
+ },
+ isLiveAutoCompletion: function() {
+ return this.userConfig.setting.liveAutoCompletion;
+ },
+ isCorrectEditorFromInterpreterTag: function(context) {
+ var checkRegex = new RegExp(this.getModeRegex());
+ return checkRegex.test(context);
+ }
+ };
+
+ var themeSupportLists = [
+ {'themeValue': 'chrome'}
+ ];
+
+ var languageSupportLists = [
+ {languageType: 'scala'},
+ {languageType: 'sh'},
+ {languageType: 'java'},
+ {languageType: 'sql'},
+ {languageType: 'r'},
+ {languageType: 'markdown'},
+ {languageType: 'python'},
+ {languageType: 'javascript'},
+ {languageType: 'mysql'},
+ {languageType: 'pgsql'}
+ ];
+
+ var defaultModeValue = 'Scala Spark';
+ var isServerReceivedValue = false;
+ var editorConfigList = [];
+
+ function initializeEditorSettings(userEditorSettings) {
+ return $q(function(success, fail) {
+ if (userEditorSettings.length > 0) {
+ editorConfigList.splice(0, editorConfigList.length);
+ userEditorSettings.map(function(editorConfig) {
+ var configItem = angular.copy(EditorConfigObject);
+ configItem.setUserConfig(editorConfig.userConfig);
+ editorConfigList.push(configItem);
+ });
+ }
+ if (success !== undefined) {
+ success();
+ }
+ });
+ }
+
+ this.initConfig = initializeEditorSettings;
+
+ this.initConfig(builtInConfig.editorSettings);
+
+ this.isServerReceived = function() {
+ return isServerReceivedValue;
+ };
+
+ this.setServerReceived = function(status) {
+ isServerReceivedValue = status;
+ };
+
+ this.getEditorConfigLists = function() {
+ return editorConfigList;
+ };
+
+ this.setEditorConfig = function(index, data) {
+ editorConfigList.splice(index, 1, data);
+ };
+
+ this.getEditorConfig = function(index) {
+ return editorConfigList[index];
+ };
+
+ this.newEditorConfig = function(configName, configRegex) {
+ console.log(configName);
+ var newConfig = {
+ modeName: configName,
+ language: 'scala',
+ modeRegex: configRegex,
+ setting: {
+ theme: 'chrome',
+ tabSize: 4,
+ showLineNumber: false,
+ activeLine: false,
+ liveAutoCompletion: false,
+ showPrintMargin: false,
+ showPrintMarginColumn: 100,
+ fontSize: 10
+ }
+ };
+ var configItem = angular.copy(EditorConfigObject);
+ configItem.setUserConfig(newConfig);
+ console.log(configItem);
+ editorConfigList.push(configItem);
+ return editorConfigList.length - 1;
+ };
+
+ this.removeEditorConfig = function(index) {
+ editorConfigList.splice(index, 1);
+ };
+
+ this.getThemeSupportLists = function() {
+ return angular.copy(themeSupportLists);
+ };
+
+ this.getLanguageSupportLists = function() {
+ return angular.copy(languageSupportLists);
+ };
+
+ this.findGetEditorConfigFromName = function(modeName) {
+ var index = _.findIndex(editorConfigList, function(config) {
+ return config.getModeName() === modeName;
+ });
+ return index < 0 ? undefined : {index: index, data: editorConfigList[index]};
+ };
+
+ this.findGetEditorConfigFromInterpreterTag = function(interpreterTag) {
+ var index = _.findIndex(editorConfigList, function(config) {
+ return config.isCorrectEditorFromInterpreterTag(interpreterTag);
+ });
+ return editorConfigList[index];
+ };
+
+ this.getDefaultModeName = function() {
+ return defaultModeValue;
+ };
+
+ this.getDefaultEditorSetting = function() {
+ var defaultConfigIndex = _.findIndex(editorConfigList, function(config) {
+ if (config === undefined) {
+ return false;
+ }
+ return config.getModeName() === defaultModeValue;
+ });
+
+ if (defaultConfigIndex >= 0) {
+ return editorConfigList[defaultConfigIndex];
+ } else {
+ return editorConfigList ? editorConfigList[0] : undefined;
+ }
+ };
+
+});
diff --git a/zeppelin-web/src/index.html b/zeppelin-web/src/index.html
index 9a8ae6fbb88..c008c5d0299 100644
--- a/zeppelin-web/src/index.html
+++ b/zeppelin-web/src/index.html
@@ -172,6 +172,7 @@
+