mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Improve cell language detection and add support for language magics (#4081)
* Move to using notebook language by default, with override in cell * Update cell language on kernel change * Tweak language logic so that it prefers code mirror mode, then falls back since this was failing some notebooks * Add new package.json contribution to define language magics. These result in cell language changing. Language is cleared out on removing the language magic * Added support for executing Python, R and Java in the SQL Kernel to prove this out. It converts to the sp_execute_external_script format TODO in future PR: * Need to hook up completion item support for magics (issue #4078) * Should add indicator at the bottom of a cell when an alternate language has been detected (issue #4079) * On executing Python, R or Java, should add some output showing the generated code (issue #4080)
This commit is contained in:
@@ -6,7 +6,6 @@ import 'vs/css!./code';
|
||||
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, Output, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
|
||||
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
import { QueryTextEditor } from 'sql/parts/modelComponents/queryTextEditor';
|
||||
import { CellToggleMoreActions } from 'sql/parts/notebook/cellToggleMoreActions';
|
||||
@@ -26,12 +25,12 @@ import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorIn
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Emitter, debounceEvent } from 'vs/base/common/event';
|
||||
import { CellTypes } from 'sql/parts/notebook/models/contracts';
|
||||
import { OVERRIDE_EDITOR_THEMING_SETTING } from 'sql/workbench/services/notebook/common/notebookService';
|
||||
import * as notebookUtils from 'sql/parts/notebook/notebookUtils';
|
||||
|
||||
export const CODE_SELECTOR: string = 'code-component';
|
||||
const MARKDOWN_CLASS = 'markdown';
|
||||
@@ -61,6 +60,12 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange
|
||||
|
||||
@Input() set model(value: NotebookModel) {
|
||||
this._model = value;
|
||||
this._register(value.kernelChanged(() => {
|
||||
// On kernel change, need to reevaluate the language for each cell
|
||||
// Refresh based on the cell magic (since this is kernel-dependent) and then update using notebook language
|
||||
this.checkForLanguageMagics();
|
||||
this.updateLanguageMode();
|
||||
}));
|
||||
}
|
||||
|
||||
@Input() set activeCellId(value: string) {
|
||||
@@ -88,21 +93,17 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange
|
||||
private _layoutEmitter = new Emitter<void>();
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||
@Inject(IModelService) private _modelService: IModelService,
|
||||
@Inject(IModeService) private _modeService: IModeService,
|
||||
@Inject(IContextMenuService) private contextMenuService: IContextMenuService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(INotificationService) private notificationService: INotificationService,
|
||||
@Inject(IConfigurationService) private _configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this._cellToggleMoreActions = this._instantiationService.createInstance(CellToggleMoreActions);
|
||||
debounceEvent(this._layoutEmitter.event, (l, e) => e, 250, /*leading=*/false)
|
||||
(() => this.layout());
|
||||
this._register(debounceEvent(this._layoutEmitter.event, (l, e) => e, 250, /*leading=*/false)
|
||||
(() => this.layout()));
|
||||
|
||||
}
|
||||
|
||||
@@ -180,6 +181,7 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange
|
||||
this._editor.setHeightToScrollHeight();
|
||||
this.cellModel.source = this._editorModel.getValue();
|
||||
this.onContentChanged.emit();
|
||||
this.checkForLanguageMagics();
|
||||
// TODO see if there's a better way to handle reassessing size.
|
||||
setTimeout(() => this._layoutEmitter.fire(), 250);
|
||||
}));
|
||||
@@ -220,7 +222,31 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange
|
||||
}
|
||||
}
|
||||
|
||||
private updateLanguageMode() {
|
||||
private checkForLanguageMagics(): void {
|
||||
try {
|
||||
if (!this.cellModel || this.cellModel.cellType !== CellTypes.Code) {
|
||||
return;
|
||||
}
|
||||
if (this._editorModel && this._editor && this._editorModel.getLineCount() > 1) {
|
||||
// Only try to match once we've typed past the first line
|
||||
let magicName = notebookUtils.tryMatchCellMagic(this._editorModel.getLineContent(1));
|
||||
if (magicName) {
|
||||
let kernelName = this._model.clientSession && this._model.clientSession.kernel ? this._model.clientSession.kernel.name : undefined;
|
||||
let magic = this._model.notebookOptions.cellMagicMapper.toLanguageMagic(magicName, kernelName);
|
||||
if (magic && this.cellModel.language !== magic.language) {
|
||||
this.cellModel.setOverrideLanguage(magic.language);
|
||||
this.updateLanguageMode();
|
||||
}
|
||||
} else {
|
||||
this.cellModel.setOverrideLanguage(undefined);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// No-op for now. Should we log?
|
||||
}
|
||||
}
|
||||
|
||||
private updateLanguageMode(): void {
|
||||
if (this._editorModel && this._editor) {
|
||||
this._modeService.getOrCreateMode(this.cellModel.language).then((modeValue) => {
|
||||
this._modelService.setMode(this._editorModel, modeValue);
|
||||
|
||||
Reference in New Issue
Block a user