gethue
Version:
Hue is an Open source SQL Query Editor for Databases/Warehouses
121 lines (105 loc) • 4.44 kB
JavaScript
// 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.
import huePubSub from '../../../utils/huePubSub';
import { ACTIVE_STATEMENT_CHANGED_EVENT } from '../../../ko/bindings/ace/aceLocationHandler';
import AceAnchoredRange from '../../../ko/bindings/ace/aceAnchoredRange';
import { EXECUTABLE_UPDATED_TOPIC } from '../../../apps/editor/execution/events';
// TODO: depends on Ace
const LINE_BREAK_REGEX = /(\r\n)|(\n)|(\r)/g;
const LEADING_WHITE_SPACE_REGEX = /^\s+/;
const ACTIVE_CSS = 'ace-active-gutter-decoration';
const COMPLETED_CSS = 'ace-completed-gutter-decoration';
const EXECUTING_CSS = 'ace-executing-gutter-decoration';
const FAILED_CSS = 'ace-failed-gutter-decoration';
const FAILED_MARKER_CSS = 'ace-failed-marker';
const getLeadingEmptyLineCount = parsedStatement => {
let leadingEmptyLineCount = 0;
const leadingWhiteSpace = parsedStatement.statement.match(LEADING_WHITE_SPACE_REGEX);
if (leadingWhiteSpace) {
const lineBreakMatch = leadingWhiteSpace[0].match(LINE_BREAK_REGEX);
if (lineBreakMatch) {
leadingEmptyLineCount = lineBreakMatch.length;
}
}
return leadingEmptyLineCount;
};
export default class AceGutterHandler {
constructor(options) {
this.editor = options.editor;
this.editorId = options.editorId;
this.executor = options.executor;
this.disposals = [];
const activeStatementAnchor = new AceAnchoredRange(this.editor);
activeStatementAnchor.addGutterCss(ACTIVE_CSS);
const changedSubscription = huePubSub.subscribe(
ACTIVE_STATEMENT_CHANGED_EVENT,
statementDetails => {
if (statementDetails.id !== this.editorId || !statementDetails.activeStatement) {
return;
}
const leadingEmptyLineCount = getLeadingEmptyLineCount(statementDetails.activeStatement);
activeStatementAnchor.move(
statementDetails.activeStatement.location,
leadingEmptyLineCount
);
}
);
this.disposals.push(() => {
changedSubscription.remove();
activeStatementAnchor.dispose();
});
if (this.executor) {
const executableSub = huePubSub.subscribe(EXECUTABLE_UPDATED_TOPIC, executable => {
if (executable.executor === this.executor) {
if (executable.lost) {
if (executable.observerState.aceAnchor) {
executable.observerState.aceAnchor.dispose();
delete executable.observerState.aceAnchor;
}
return;
}
const statement = executable.parsedStatement;
if (!executable.observerState.aceAnchor) {
executable.observerState.aceAnchor = new AceAnchoredRange(this.editor);
}
const leadingEmptyLineCount = getLeadingEmptyLineCount(statement);
executable.observerState.aceAnchor.move(statement.location, leadingEmptyLineCount);
const anchoredRange = executable.observerState.aceAnchor;
anchoredRange.removeGutterCss(COMPLETED_CSS);
anchoredRange.removeGutterCss(EXECUTING_CSS);
anchoredRange.removeGutterCss(FAILED_CSS);
anchoredRange.removeMarkerCss(FAILED_MARKER_CSS);
if (executable.isRunning()) {
anchoredRange.addGutterCss(EXECUTING_CSS);
} else if (executable.isSuccess()) {
anchoredRange.addGutterCss(COMPLETED_CSS);
} else if (executable.isFailed()) {
anchoredRange.addMarkerCss(FAILED_MARKER_CSS);
anchoredRange.addGutterCss(FAILED_CSS);
}
}
});
this.disposals.push(() => {
executableSub.remove();
});
}
}
dispose() {
while (this.disposals.length) {
this.disposals.pop()();
}
}
}