mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 09:35:37 -05:00
600 lines
26 KiB
TypeScript
600 lines
26 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { Registry } from 'vs/platform/registry/common/platform';
|
|
import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor';
|
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
|
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
|
import { IConfigurationRegistry, Extensions as ConfigExtensions, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry';
|
|
import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
|
import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
|
|
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
|
import { ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey';
|
|
|
|
import { QueryEditor } from 'sql/workbench/contrib/query/browser/queryEditor';
|
|
import { QueryResultsEditor } from 'sql/workbench/contrib/query/browser/queryResultsEditor';
|
|
import { QueryResultsInput } from 'sql/workbench/common/editor/query/queryResultsInput';
|
|
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
|
import {
|
|
RunQueryKeyboardAction, RunCurrentQueryKeyboardAction, CancelQueryKeyboardAction, RefreshIntellisenseKeyboardAction, ToggleQueryResultsKeyboardAction,
|
|
RunQueryShortcutAction, ToggleActualPlanKeyboardAction, CopyQueryWithResultsKeyboardAction, FocusOnCurrentQueryKeyboardAction, ParseSyntaxAction, ToggleFocusBetweenQueryEditorAndResultsAction, EstimatedExecutionPlanKeyboardAction
|
|
} from 'sql/workbench/contrib/query/browser/keyboardQueryActions';
|
|
import * as gridActions from 'sql/workbench/contrib/editData/browser/gridActions';
|
|
import * as gridCommands from 'sql/workbench/contrib/editData/browser/gridCommands';
|
|
import { localize } from 'vs/nls';
|
|
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
|
|
|
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
|
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions, QueryResultSelectionSummaryStatusBarContribution } from 'sql/workbench/contrib/query/browser/statusBarItems';
|
|
import { SqlFlavorStatusbarItem, ChangeFlavorAction } from 'sql/workbench/contrib/query/browser/flavorStatus';
|
|
import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor';
|
|
import { FileQueryEditorInput } from 'sql/workbench/contrib/query/browser/fileQueryEditorInput';
|
|
import { FileQueryEditorSerializer, QueryEditorLanguageAssociation, UntitledQueryEditorSerializer } from 'sql/workbench/contrib/query/browser/queryEditorFactory';
|
|
import { UntitledQueryEditorInput } from 'sql/base/query/browser/untitledQueryEditorInput';
|
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/services/languageAssociation/common/languageAssociation';
|
|
import { NewQueryTask, OE_NEW_QUERY_ACTION_ID, DE_NEW_QUERY_COMMAND_ID, CATEGORIES, ParseSyntaxCommandId } from 'sql/workbench/contrib/query/browser/queryActions';
|
|
import { TreeNodeContextKey } from 'sql/workbench/services/objectExplorer/common/treeNodeContextKey';
|
|
import { MssqlNodeContext } from 'sql/workbench/services/objectExplorer/browser/mssqlNodeContext';
|
|
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
|
import { ManageActionContext } from 'sql/workbench/browser/actions';
|
|
import { ItemContextKey } from 'sql/workbench/contrib/dashboard/browser/widgets/explorer/explorerContext';
|
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
|
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
|
import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput';
|
|
import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService';
|
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
|
import { ILogService } from 'vs/platform/log/common/log';
|
|
import { ILanguageService } from 'vs/editor/common/languages/language';
|
|
|
|
export const QueryEditorVisibleCondition = ContextKeyExpr.has(queryContext.queryEditorVisibleId);
|
|
export const ResultsGridFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsGridFocussedId));
|
|
export const ResultsMessagesFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsMessagesFocussedId));
|
|
|
|
Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory)
|
|
.registerEditorSerializer(FileQueryEditorInput.ID, FileQueryEditorSerializer);
|
|
|
|
Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory)
|
|
.registerEditorSerializer(UntitledQueryEditorInput.ID, UntitledQueryEditorSerializer);
|
|
|
|
Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations)
|
|
.registerLanguageAssociation(QueryEditorLanguageAssociation.languages, QueryEditorLanguageAssociation, QueryEditorLanguageAssociation.isDefault);
|
|
|
|
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane)
|
|
.registerEditorPane(EditorPaneDescriptor.create(QueryResultsEditor, QueryResultsEditor.ID, localize('queryResultsEditor.name', "Query Results")), [new SyncDescriptor(QueryResultsInput)]);
|
|
|
|
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane)
|
|
.registerEditorPane(EditorPaneDescriptor.create(QueryEditor, QueryEditor.ID, QueryEditor.LABEL), [new SyncDescriptor(FileQueryEditorInput), new SyncDescriptor(UntitledQueryEditorInput)]);
|
|
|
|
const actionRegistry = <IWorkbenchActionRegistry>Registry.as(ActionExtensions.WorkbenchActions);
|
|
|
|
new NewQueryTask().registerTask();
|
|
|
|
MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, {
|
|
group: '0_query',
|
|
order: 1,
|
|
command: {
|
|
id: OE_NEW_QUERY_ACTION_ID,
|
|
title: localize('newQuery', "New Query")
|
|
},
|
|
when: ContextKeyExpr.and(TreeNodeContextKey.Status.notEqualsTo('Unavailable'), TreeNodeContextKey.IsQueryProvider.isEqualTo(true), ContextKeyExpr.or(TreeNodeContextKey.NodeType.isEqualTo('Server'), TreeNodeContextKey.NodeType.isEqualTo('Database')))
|
|
});
|
|
|
|
// New Query
|
|
MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, {
|
|
group: '0_query',
|
|
order: 1,
|
|
command: {
|
|
id: DE_NEW_QUERY_COMMAND_ID,
|
|
title: localize('newQuery', "New Query")
|
|
},
|
|
when: ContextKeyExpr.and(MssqlNodeContext.IsDatabaseOrServer, MssqlNodeContext.IsQueryProvider)
|
|
});
|
|
|
|
const ExplorerNewQueryActionID = 'explorer.query';
|
|
CommandsRegistry.registerCommand(ExplorerNewQueryActionID, (accessor, context: ManageActionContext) => {
|
|
const commandService = accessor.get(ICommandService);
|
|
return commandService.executeCommand(NewQueryTask.ID, context.profile);
|
|
});
|
|
|
|
MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, {
|
|
command: {
|
|
id: ExplorerNewQueryActionID,
|
|
title: NewQueryTask.LABEL
|
|
},
|
|
when: ItemContextKey.ItemType.isEqualTo('database'),
|
|
order: 1
|
|
});
|
|
|
|
// Query Actions
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
RunQueryKeyboardAction,
|
|
RunQueryKeyboardAction.ID,
|
|
RunQueryKeyboardAction.LABEL,
|
|
{ primary: KeyCode.F5 }
|
|
),
|
|
RunQueryKeyboardAction.LABEL
|
|
);
|
|
|
|
// Only show Run Query if the active editor is a query editor.
|
|
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
|
command: { id: RunQueryKeyboardAction.ID, title: RunQueryKeyboardAction.LABEL },
|
|
group: 'query',
|
|
when: ContextKeyEqualsExpr.create('activeEditor', 'workbench.editor.queryEditor')
|
|
});
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
RunCurrentQueryKeyboardAction,
|
|
RunCurrentQueryKeyboardAction.ID,
|
|
RunCurrentQueryKeyboardAction.LABEL,
|
|
{ primary: KeyMod.CtrlCmd | KeyCode.F5 }
|
|
),
|
|
RunCurrentQueryKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
EstimatedExecutionPlanKeyboardAction,
|
|
EstimatedExecutionPlanKeyboardAction.ID,
|
|
EstimatedExecutionPlanKeyboardAction.LABEL,
|
|
{ primary: KeyMod.CtrlCmd | KeyCode.KeyL }
|
|
),
|
|
EstimatedExecutionPlanKeyboardAction.LABEL,
|
|
CATEGORIES.ExecutionPlan.value
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
ToggleActualPlanKeyboardAction,
|
|
ToggleActualPlanKeyboardAction.ID,
|
|
ToggleActualPlanKeyboardAction.LABEL,
|
|
{ primary: KeyMod.CtrlCmd | KeyCode.KeyM }
|
|
),
|
|
ToggleActualPlanKeyboardAction.LABEL,
|
|
CATEGORIES.ExecutionPlan.value
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
CopyQueryWithResultsKeyboardAction,
|
|
CopyQueryWithResultsKeyboardAction.ID,
|
|
CopyQueryWithResultsKeyboardAction.LABEL,
|
|
{ primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyV) }
|
|
),
|
|
CopyQueryWithResultsKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
CancelQueryKeyboardAction,
|
|
CancelQueryKeyboardAction.ID,
|
|
CancelQueryKeyboardAction.LABEL,
|
|
{ primary: KeyMod.Alt | KeyCode.PauseBreak }
|
|
),
|
|
CancelQueryKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
RefreshIntellisenseKeyboardAction,
|
|
RefreshIntellisenseKeyboardAction.ID,
|
|
RefreshIntellisenseKeyboardAction.LABEL
|
|
),
|
|
RefreshIntellisenseKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
FocusOnCurrentQueryKeyboardAction,
|
|
FocusOnCurrentQueryKeyboardAction.ID,
|
|
FocusOnCurrentQueryKeyboardAction.LABEL,
|
|
{ primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO }
|
|
),
|
|
FocusOnCurrentQueryKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
ParseSyntaxAction,
|
|
ParseSyntaxCommandId,
|
|
ParseSyntaxAction.LABEL,
|
|
{ primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KeyP }
|
|
),
|
|
ParseSyntaxAction.LABEL
|
|
);
|
|
|
|
// Grid actions
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
ToggleQueryResultsKeyboardAction,
|
|
ToggleQueryResultsKeyboardAction.ID,
|
|
ToggleQueryResultsKeyboardAction.LABEL,
|
|
{ primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KeyR },
|
|
QueryEditorVisibleCondition
|
|
),
|
|
ToggleQueryResultsKeyboardAction.LABEL
|
|
);
|
|
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
ToggleFocusBetweenQueryEditorAndResultsAction,
|
|
ToggleFocusBetweenQueryEditorAndResultsAction.ID,
|
|
ToggleFocusBetweenQueryEditorAndResultsAction.LABEL,
|
|
{ primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KeyF },
|
|
QueryEditorVisibleCondition
|
|
),
|
|
ToggleFocusBetweenQueryEditorAndResultsAction.LABEL
|
|
);
|
|
|
|
// Register Flavor Action
|
|
actionRegistry.registerWorkbenchAction(
|
|
SyncActionDescriptor.create(
|
|
ChangeFlavorAction,
|
|
ChangeFlavorAction.ID,
|
|
ChangeFlavorAction.LABEL
|
|
),
|
|
'Change Language Flavor'
|
|
);
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_COPY_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyMod.CtrlCmd | KeyCode.KeyC,
|
|
handler: gridCommands.copySelection
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.MESSAGES_SELECTALL_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsMessagesFocusCondition,
|
|
primary: KeyMod.CtrlCmd | KeyCode.KeyA,
|
|
handler: gridCommands.selectAllMessages
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SELECTALL_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyMod.CtrlCmd | KeyCode.KeyA,
|
|
handler: gridCommands.selectAll
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.MESSAGES_COPY_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsMessagesFocusCondition,
|
|
primary: KeyMod.CtrlCmd | KeyCode.KeyC,
|
|
handler: gridCommands.copyMessagesSelection
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SAVECSV_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyC),
|
|
handler: gridCommands.saveAsCsv
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SAVEJSON_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyJ),
|
|
handler: gridCommands.saveAsJson
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SAVEMARKDOWN_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyM),
|
|
handler: gridCommands.saveAsMarkdown
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SAVEEXCEL_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyE),
|
|
handler: gridCommands.saveAsExcel
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_SAVEXML_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyX),
|
|
handler: gridCommands.saveAsXml
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_VIEWASCHART_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyV),
|
|
handler: gridCommands.viewAsChart
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GRID_GOTONEXTGRID_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: ResultsGridFocusCondition,
|
|
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyR, KeyMod.CtrlCmd | KeyCode.KeyN),
|
|
handler: gridCommands.goToNextGrid
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.TOGGLERESULTS_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: QueryEditorVisibleCondition,
|
|
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyR,
|
|
handler: gridCommands.toggleResultsPane
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.TOGGLEMESSAGES_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: QueryEditorVisibleCondition,
|
|
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyY,
|
|
handler: gridCommands.toggleMessagePane
|
|
});
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: gridActions.GOTONEXTQUERYOUTPUTTAB_ID,
|
|
weight: KeybindingWeight.EditorContrib,
|
|
when: QueryEditorVisibleCondition,
|
|
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyP,
|
|
handler: gridCommands.goToNextQueryOutputTab
|
|
});
|
|
|
|
export const queryEditorConfigurationBaseNode = Object.freeze<IConfigurationNode>({
|
|
id: 'queryEditor',
|
|
order: 5,
|
|
type: 'object',
|
|
title: localize('queryEditorConfigurationTitle', "Query Editor"),
|
|
});
|
|
|
|
// Intellisense and other configuration options
|
|
const queryEditorConfiguration: IConfigurationNode = {
|
|
...queryEditorConfigurationBaseNode,
|
|
properties: {
|
|
'queryEditor.results.saveAsCsv.includeHeaders': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.saveAsCsv.includeHeaders', "When true, column headers are included when saving results as CSV"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.saveAsCsv.delimiter': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsCsv.delimiter', "The custom delimiter to use between values when saving as CSV"),
|
|
'default': ','
|
|
},
|
|
'queryEditor.results.saveAsCsv.lineSeperator': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsCsv.lineSeperator', "Character(s) used for seperating rows when saving results as CSV"),
|
|
'default': null
|
|
},
|
|
'queryEditor.results.saveAsCsv.textIdentifier': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsCsv.textIdentifier', "Character used for enclosing text fields when saving results as CSV"),
|
|
'default': '\"'
|
|
},
|
|
'queryEditor.results.saveAsExcel.includeHeaders': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.saveAsExcel.includeHeaders', "When true, column headers are included when saving results as an Excel file"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.saveAsCsv.encoding': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsCsv.encoding', "File encoding used when saving results as CSV"),
|
|
'default': 'utf-8'
|
|
},
|
|
'queryEditor.results.saveAsMarkdown.encoding': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsMarkdown.encoding', "File encoding used when saving results as Markdown"),
|
|
'default': 'utf-8'
|
|
},
|
|
'queryEditor.results.saveAsMarkdown.includeHeaders': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.saveAsMarkdown.includeHeaders', "When true, column headers are included when saving results as a Markdown file"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.saveAsMarkdown.lineSeparator': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsMarkdown.lineSeparator', "Character(s) to use to separate lines when exporting to Markdown, defaults to system line endings"),
|
|
'default': null
|
|
},
|
|
'queryEditor.results.saveAsXml.formatted': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.saveAsXml.formatted', "When true, XML output will be formatted when saving results as XML"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.saveAsXml.encoding': {
|
|
'type': 'string',
|
|
'description': localize('queryEditor.results.saveAsXml.encoding', "File encoding used when saving results as XML"),
|
|
'default': 'utf-8'
|
|
},
|
|
'queryEditor.results.streaming': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.streaming', "Enable results streaming; contains few minor visual issues"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.copyIncludeHeaders': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.copyIncludeHeaders', "Configuration options for copying results from the Results View"),
|
|
'default': false
|
|
},
|
|
'queryEditor.results.copyRemoveNewLine': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.copyRemoveNewLine', "Configuration options for copying multi-line results from the Results View"),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.inMemoryDataProcessingThreshold': {
|
|
'type': 'number',
|
|
'default': 5000,
|
|
'description': localize('queryEditor.inMemoryDataProcessingThreshold', "Controls the max number of rows allowed to do filtering and sorting in memory. If the number is exceeded, sorting and filtering will be disabled. Warning: Increasing this may impact performance.")
|
|
},
|
|
'queryEditor.results.openAfterSave': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.openAfterSave', "Whether to open the file in Azure Data Studio after the result is saved."),
|
|
'default': true
|
|
},
|
|
'queryEditor.results.showActionBar': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.results.showActionBar', "Whether to show the action bar in the query results view"),
|
|
'default': true
|
|
},
|
|
'queryEditor.messages.showBatchTime': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.messages.showBatchTime', "Should execution time be shown for individual batches"),
|
|
'default': false
|
|
},
|
|
'queryEditor.messages.wordwrap': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.messages.wordwrap', "Word wrap messages"),
|
|
'default': true
|
|
},
|
|
'queryEditor.chart.defaultChartType': {
|
|
'type': 'string',
|
|
'enum': ['bar', 'doughnut', 'horizontalBar', 'line', 'pie', 'scatter', 'timeSeries'],
|
|
'default': 'horizontalBar',
|
|
'description': localize('queryEditor.chart.defaultChartType', "The default chart type to use when opening Chart Viewer from a Query Results")
|
|
},
|
|
'queryEditor.tabColorMode': {
|
|
'type': 'string',
|
|
'enum': ['off', 'border', 'fill'],
|
|
'enumDescriptions': [
|
|
localize('queryEditor.tabColorMode.off', "Tab coloring will be disabled"),
|
|
localize('queryEditor.tabColorMode.border', "The top border of each editor tab will be colored to match the relevant server group"),
|
|
localize('queryEditor.tabColorMode.fill', "Each editor tab's background color will match the relevant server group"),
|
|
],
|
|
'default': 'off',
|
|
'description': localize('queryEditor.tabColorMode', "Controls how to color tabs based on the server group of their active connection")
|
|
},
|
|
'queryEditor.showConnectionInfoInTitle': {
|
|
'type': 'boolean',
|
|
'description': localize('queryEditor.showConnectionInfoInTitle', "Controls whether to show the connection info for a tab in the title."),
|
|
'default': true
|
|
},
|
|
'queryEditor.promptToSaveGeneratedFiles': {
|
|
'type': 'boolean',
|
|
'default': false,
|
|
'description': localize('queryEditor.promptToSaveGeneratedFiles', "Prompt to save generated SQL files")
|
|
}
|
|
}
|
|
};
|
|
|
|
// Setup keybindings
|
|
const initialShortcuts = [
|
|
{ name: 'sp_help', primary: KeyMod.Alt + KeyCode.F2 },
|
|
// Note: using Ctrl+Shift+N since Ctrl+N is used for "open editor at index" by default. This means it's different from SSMS
|
|
{ name: 'sp_who', primary: KeyMod.WinCtrl + KeyMod.Shift + KeyCode.Digit1 },
|
|
{ name: 'sp_lock', primary: KeyMod.WinCtrl + KeyMod.Shift + KeyCode.Digit2 }
|
|
];
|
|
|
|
const shortCutConfiguration: IConfigurationNode = {
|
|
...queryEditorConfigurationBaseNode,
|
|
properties: {}
|
|
};
|
|
|
|
for (let i = 0; i < 9; i++) {
|
|
const queryIndex = i + 1;
|
|
let settingKey = `sql.query.shortcut${queryIndex}`;
|
|
let defaultVal = i < initialShortcuts.length ? initialShortcuts[i].name : '';
|
|
let defaultPrimary = i < initialShortcuts.length ? initialShortcuts[i].primary : null;
|
|
|
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
id: `workbench.action.query.shortcut${queryIndex}`,
|
|
weight: KeybindingWeight.WorkbenchContrib,
|
|
when: QueryEditorVisibleCondition,
|
|
primary: defaultPrimary,
|
|
handler: accessor => {
|
|
accessor.get(IInstantiationService).createInstance(RunQueryShortcutAction).run(queryIndex);
|
|
}
|
|
});
|
|
shortCutConfiguration.properties[settingKey] = {
|
|
'type': 'string',
|
|
'default': defaultVal,
|
|
'description': localize('queryShortcutDescription',
|
|
"Set keybinding workbench.action.query.shortcut{0} to run the shortcut text as a procedure call or query execution. Any selected text in the query editor will be passed as a parameter at the end of your query, or you can reference it with {arg}",
|
|
queryIndex)
|
|
};
|
|
}
|
|
|
|
// Register the query-related configuration options
|
|
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
|
|
configurationRegistry.registerConfiguration(queryEditorConfiguration);
|
|
configurationRegistry.registerConfiguration(shortCutConfiguration);
|
|
|
|
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
|
|
|
workbenchRegistry.registerWorkbenchContribution(TimeElapsedStatusBarContributions, LifecyclePhase.Restored);
|
|
workbenchRegistry.registerWorkbenchContribution(RowCountStatusBarContributions, LifecyclePhase.Restored);
|
|
workbenchRegistry.registerWorkbenchContribution(QueryStatusStatusBarContributions, LifecyclePhase.Restored);
|
|
workbenchRegistry.registerWorkbenchContribution(SqlFlavorStatusbarItem, LifecyclePhase.Restored);
|
|
workbenchRegistry.registerWorkbenchContribution(QueryResultSelectionSummaryStatusBarContribution, LifecyclePhase.Restored);
|
|
|
|
const languageAssociationRegistry = Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations);
|
|
|
|
export class QueryEditorOverrideContribution extends Disposable implements IWorkbenchContribution {
|
|
private _registeredOverrides = new DisposableStore();
|
|
|
|
constructor(
|
|
@ILogService private _logService: ILogService,
|
|
@IEditorService private _editorService: IEditorService,
|
|
@IEditorResolverService private _editorResolverService: IEditorResolverService,
|
|
@ILanguageService private _languageService: ILanguageService
|
|
) {
|
|
super();
|
|
this.registerEditorOverrides();
|
|
// Refresh the editor overrides whenever the languages change so we ensure we always have
|
|
// the latest up to date list of extensions for each language
|
|
this._languageService.onDidChange(() => {
|
|
this.registerEditorOverrides();
|
|
});
|
|
}
|
|
|
|
private registerEditorOverrides(): void {
|
|
this._registeredOverrides.clear();
|
|
// List of language IDs to associate the query editor for. These are case sensitive.
|
|
QueryEditorLanguageAssociation.languages.map(lang => {
|
|
const langExtensions = this._languageService.getExtensions(lang);
|
|
if (langExtensions.length === 0) {
|
|
return;
|
|
}
|
|
// Create the selector from the list of all the language extensions we want to associate with the
|
|
// query editor (filtering out any languages which didn't have any extensions registered yet)
|
|
const selector = `*{${langExtensions.join(',')}}`;
|
|
this._registeredOverrides.add(this._editorResolverService.registerEditor(
|
|
selector,
|
|
{
|
|
id: QueryEditor.ID,
|
|
label: QueryEditor.LABEL,
|
|
priority: RegisteredEditorPriority.builtin
|
|
},
|
|
{
|
|
// Fall back to using the normal text based diff editor - we don't want the query bar and related items showing up in the diff editor
|
|
// canHandleDiff: () => false
|
|
},
|
|
{
|
|
createEditorInput: async (editorInput, group) => {
|
|
const fileInput = await this._editorService.createEditorInput(editorInput) as FileEditorInput;
|
|
const langAssociation = languageAssociationRegistry.getAssociationForLanguage(lang);
|
|
const queryEditorInput = langAssociation?.syncConvertInput?.(fileInput);
|
|
if (!queryEditorInput) {
|
|
this._logService.warn('Unable to create input for resolving editor ', editorInput.resource);
|
|
return undefined;
|
|
}
|
|
return { editor: queryEditorInput, options: editorInput.options, group: group };
|
|
}
|
|
}
|
|
));
|
|
});
|
|
}
|
|
}
|
|
workbenchRegistry.registerWorkbenchContribution(QueryEditorOverrideContribution, LifecyclePhase.Starting);
|