diff --git a/docs/development/writing_zeppelin_interpreter.md b/docs/development/writing_zeppelin_interpreter.md index f4c0bc939da..f62e97e792b 100644 --- a/docs/development/writing_zeppelin_interpreter.md +++ b/docs/development/writing_zeppelin_interpreter.md @@ -116,7 +116,8 @@ Here is an example of `interpreter-setting.json` on your own interpreter. }, "editor": { "language": "your-syntax-highlight-language", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { @@ -170,6 +171,19 @@ If your interpreter uses mark-up language such as markdown or HTML, set `editOnD "editOnDblClick": false } ``` + +### Completion key (Optional) +By default, `Ctrl+dot(.)` brings autocompletion list in the editor. +Through `completionKey`, each interpreter can configure autocompletion key. +Currently `TAB` is only available option. + +``` +"editor": { + "completionKey": "TAB" +} +``` + + ## Install your interpreter binary Once you have built your interpreter, you can place it under the interpreter directory with all its dependencies. diff --git a/python/src/main/resources/interpreter-setting.json b/python/src/main/resources/interpreter-setting.json index bc1a746efd4..d6b35380385 100644 --- a/python/src/main/resources/interpreter-setting.json +++ b/python/src/main/resources/interpreter-setting.json @@ -44,7 +44,8 @@ }, "editor": { "language": "python", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { @@ -55,7 +56,8 @@ }, "editor":{ "language": "sql", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { diff --git a/r/src/main/resources/interpreter-setting.json b/r/src/main/resources/interpreter-setting.json index b7dcaf7fafc..c5997a3441c 100644 --- a/r/src/main/resources/interpreter-setting.json +++ b/r/src/main/resources/interpreter-setting.json @@ -24,6 +24,11 @@ "defaultValue": "60", "type": "number" } + }, + "editor": { + "language": "r", + "editOnDblClick": false, + "completionKey": "TAB" } }, { diff --git a/spark/src/main/resources/interpreter-setting.json b/spark/src/main/resources/interpreter-setting.json index 7c13c49a16c..4aeda6c9df6 100644 --- a/spark/src/main/resources/interpreter-setting.json +++ b/spark/src/main/resources/interpreter-setting.json @@ -71,7 +71,8 @@ }, "editor": { "language": "scala", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { @@ -110,7 +111,8 @@ }, "editor": { "language": "sql", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { @@ -135,7 +137,8 @@ }, "editor": { "language": "scala", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { @@ -160,7 +163,8 @@ }, "editor": { "language": "python", - "editOnDblClick": false + "editOnDblClick": false, + "completionKey": "TAB" } }, { diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index edc808f212b..7d95d3b3200 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -185,6 +185,11 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca } } + const isTabCompletion = function() { + const completionKey = $scope.paragraph.config.editorSetting.completionKey + return completionKey === 'TAB' + } + $scope.$on('updateParagraphOutput', function (event, data) { if ($scope.paragraph.id === data.paragraphId) { if (!$scope.paragraph.results) { @@ -851,6 +856,33 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca // autocomplete on 'ctrl+.' $scope.editor.commands.bindKey('ctrl-.', 'startAutocomplete') + // Show autocomplete on tab + $scope.editor.commands.addCommand({ + name: 'tabAutocomplete', + bindKey: { + win: 'tab', + mac: 'tab', + sender: 'editor|cli' + }, + exec: function(env, args, request) { + let iCursor = $scope.editor.getCursorPosition() + let currentLine = $scope.editor.session.getLine(iCursor.row) + let isAllTabs = currentLine.substring(0, iCursor.column - 1).split('').every(function(char) { + return (char === '\t' || char === ' ') + }) + + // If user has pressed tab on first line char or if isTabCompletion() is false, keep existing behavior + // If user has pressed tab anywhere in between and editor mode is not %md, show autocomplete + if (!isAllTabs && iCursor.column && isTabCompletion()) { + $scope.editor.execCommand('startAutocomplete') + } else { + ace.config.loadModule('ace/ext/language_tools', function () { + $scope.editor.insertSnippet('\t') + }) + } + } + }) + let keyBindingEditorFocusAction = function (scrollValue) { let numRows = $scope.editor.getSession().getLength() let currentRow = $scope.editor.getCursorPosition().row