mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 18:22:34 -05:00
Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998 (#7880)
* Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998 * fix pipelines * fix strict-null-checks * add missing files
This commit is contained in:
@@ -35,7 +35,7 @@ const CONTEXT_ACCESSIBILITY_WIDGET_VISIBLE = new RawContextKey<boolean>('accessi
|
||||
|
||||
class AccessibilityHelpController extends Disposable implements IEditorContribution {
|
||||
|
||||
private static readonly ID = 'editor.contrib.accessibilityHelpController';
|
||||
public static readonly ID = 'editor.contrib.accessibilityHelpController';
|
||||
|
||||
public static get(editor: ICodeEditor): AccessibilityHelpController {
|
||||
return editor.getContribution<AccessibilityHelpController>(AccessibilityHelpController.ID);
|
||||
@@ -54,10 +54,6 @@ class AccessibilityHelpController extends Disposable implements IEditorContribut
|
||||
this._widget = this._register(instantiationService.createInstance(AccessibilityHelpWidget, this._editor));
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return AccessibilityHelpController.ID;
|
||||
}
|
||||
|
||||
public show(): void {
|
||||
this._widget.show();
|
||||
}
|
||||
@@ -299,7 +295,7 @@ class ShowAccessibilityHelpAction extends EditorAction {
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(AccessibilityHelpController);
|
||||
registerEditorContribution(AccessibilityHelpController.ID, AccessibilityHelpController);
|
||||
registerEditorAction(ShowAccessibilityHelpAction);
|
||||
|
||||
const AccessibilityHelpCommand = EditorCommand.bindToContribution<AccessibilityHelpController>(AccessibilityHelpController.get);
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
import './menuPreventer';
|
||||
import './accessibility/accessibility';
|
||||
import './diffEditorHelper';
|
||||
import './inspectKeybindings';
|
||||
import './largeFileOptimizations';
|
||||
import './selectionClipboard';
|
||||
import './inspectTMScopes/inspectTMScopes';
|
||||
import './toggleMinimap';
|
||||
import './toggleMultiCursorModifier';
|
||||
|
||||
106
src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts
Normal file
106
src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerDiffEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { IDiffEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets';
|
||||
import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
|
||||
const enum WidgetState {
|
||||
Hidden,
|
||||
HintWhitespace
|
||||
}
|
||||
|
||||
class DiffEditorHelperContribution extends Disposable implements IDiffEditorContribution {
|
||||
|
||||
public static ID = 'editor.contrib.diffEditorHelper';
|
||||
|
||||
private _helperWidget: FloatingClickWidget | null;
|
||||
private _helperWidgetListener: IDisposable | null;
|
||||
private _state: WidgetState;
|
||||
|
||||
constructor(
|
||||
private readonly _diffEditor: IDiffEditor,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
) {
|
||||
super();
|
||||
this._helperWidget = null;
|
||||
this._helperWidgetListener = null;
|
||||
this._state = WidgetState.Hidden;
|
||||
|
||||
|
||||
this._register(this._diffEditor.onDidUpdateDiff(() => {
|
||||
const diffComputationResult = this._diffEditor.getDiffComputationResult();
|
||||
this._setState(this._deduceState(diffComputationResult));
|
||||
|
||||
if (diffComputationResult && diffComputationResult.quitEarly) {
|
||||
this._notificationService.prompt(
|
||||
Severity.Warning,
|
||||
nls.localize('hintTimeout', "The diff algorithm was stopped early (after {0} ms.)", this._diffEditor.maxComputationTime),
|
||||
[{
|
||||
label: nls.localize('removeTimeout', "Remove limit"),
|
||||
run: () => {
|
||||
this._configurationService.updateValue('diffEditor.maxComputationTime', 0, ConfigurationTarget.USER);
|
||||
}
|
||||
}],
|
||||
{}
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private _deduceState(diffComputationResult: IDiffComputationResult | null): WidgetState {
|
||||
if (!diffComputationResult) {
|
||||
return WidgetState.Hidden;
|
||||
}
|
||||
if (this._diffEditor.ignoreTrimWhitespace && diffComputationResult.changes.length === 0 && !diffComputationResult.identical) {
|
||||
return WidgetState.HintWhitespace;
|
||||
}
|
||||
return WidgetState.Hidden;
|
||||
}
|
||||
|
||||
private _setState(newState: WidgetState) {
|
||||
if (this._state === newState) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._state = newState;
|
||||
|
||||
if (this._helperWidgetListener) {
|
||||
this._helperWidgetListener.dispose();
|
||||
this._helperWidgetListener = null;
|
||||
}
|
||||
if (this._helperWidget) {
|
||||
this._helperWidget.dispose();
|
||||
this._helperWidget = null;
|
||||
}
|
||||
|
||||
if (this._state === WidgetState.HintWhitespace) {
|
||||
this._helperWidget = this._instantiationService.createInstance(FloatingClickWidget, this._diffEditor.getModifiedEditor(), nls.localize('hintWhitespace', "Show Whitespace Differences"), null);
|
||||
this._helperWidgetListener = this._helperWidget.onClick(() => this._onDidClickHelperWidget());
|
||||
this._helperWidget.render();
|
||||
}
|
||||
}
|
||||
|
||||
private _onDidClickHelperWidget(): void {
|
||||
if (this._state === WidgetState.HintWhitespace) {
|
||||
this._configurationService.updateValue('diffEditor.ignoreTrimWhitespace', false, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
registerDiffEditorContribution(DiffEditorHelperContribution.ID, DiffEditorHelperContribution);
|
||||
@@ -27,7 +27,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
|
||||
|
||||
class InspectTMScopesController extends Disposable implements IEditorContribution {
|
||||
|
||||
private static readonly ID = 'editor.contrib.inspectTMScopes';
|
||||
public static readonly ID = 'editor.contrib.inspectTMScopes';
|
||||
|
||||
public static get(editor: ICodeEditor): InspectTMScopesController {
|
||||
return editor.getContribution<InspectTMScopesController>(InspectTMScopesController.ID);
|
||||
@@ -60,10 +60,6 @@ class InspectTMScopesController extends Disposable implements IEditorContributio
|
||||
this._register(this._editor.onKeyUp((e) => e.keyCode === KeyCode.Escape && this.stop()));
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return InspectTMScopesController.ID;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.stop();
|
||||
super.dispose();
|
||||
@@ -374,7 +370,7 @@ class InspectTMScopesWidget extends Disposable implements IContentWidget {
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(InspectTMScopesController);
|
||||
registerEditorContribution(InspectTMScopesController.ID, InspectTMScopesController);
|
||||
registerEditorAction(InspectTMScopes);
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
|
||||
@@ -43,16 +43,7 @@ interface ILanguageConfiguration {
|
||||
}
|
||||
|
||||
function isStringArr(something: string[] | null): something is string[] {
|
||||
if (!Array.isArray(something)) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, len = something.length; i < len; i++) {
|
||||
if (typeof something[i] !== 'string') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return Array.isArray(something) && something.every(value => typeof value === 'string');
|
||||
}
|
||||
|
||||
function isCharacterPair(something: CharacterPair | null): boolean {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
|
||||
*/
|
||||
export class LargeFileOptimizationsWarner extends Disposable implements IEditorContribution {
|
||||
|
||||
private static readonly ID = 'editor.contrib.largeFileOptimizationsWarner';
|
||||
public static readonly ID = 'editor.contrib.largeFileOptimizationsWarner';
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@@ -60,10 +60,6 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return LargeFileOptimizationsWarner.ID;
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(LargeFileOptimizationsWarner);
|
||||
registerEditorContribution(LargeFileOptimizationsWarner.ID, LargeFileOptimizationsWarner);
|
||||
|
||||
@@ -14,7 +14,7 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
*/
|
||||
export class MenuPreventer extends Disposable implements IEditorContribution {
|
||||
|
||||
private static readonly ID = 'editor.contrib.menuPreventer';
|
||||
public static readonly ID = 'editor.contrib.menuPreventer';
|
||||
|
||||
private _editor: ICodeEditor;
|
||||
private _altListeningMouse: boolean;
|
||||
@@ -55,10 +55,6 @@ export class MenuPreventer extends Disposable implements IEditorContribution {
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return MenuPreventer.ID;
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(MenuPreventer);
|
||||
registerEditorContribution(MenuPreventer.ID, MenuPreventer);
|
||||
|
||||
@@ -3,114 +3,4 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as process from 'vs/base/common/process';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
export class SelectionClipboard extends Disposable implements IEditorContribution {
|
||||
private static SELECTION_LENGTH_LIMIT = 65536;
|
||||
private static readonly ID = 'editor.contrib.selectionClipboard';
|
||||
|
||||
constructor(editor: ICodeEditor, @IClipboardService clipboardService: IClipboardService) {
|
||||
super();
|
||||
|
||||
if (platform.isLinux) {
|
||||
let isEnabled = editor.getOption(EditorOption.selectionClipboard);
|
||||
|
||||
this._register(editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
|
||||
if (e.hasChanged(EditorOption.selectionClipboard)) {
|
||||
isEnabled = editor.getOption(EditorOption.selectionClipboard);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(editor.onMouseDown((e: IEditorMouseEvent) => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
if (e.event.middleButton) {
|
||||
e.event.preventDefault();
|
||||
editor.focus();
|
||||
|
||||
if (e.target.position) {
|
||||
editor.setPosition(e.target.position);
|
||||
}
|
||||
|
||||
if (e.target.type === MouseTargetType.SCROLLBAR) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.nextTick(() => {
|
||||
// TODO@Alex: electron weirdness: calling clipboard.readText('selection') generates a paste event, so no need to execute paste ourselves
|
||||
clipboardService.readText('selection');
|
||||
// keybindingService.executeCommand(Handler.Paste, {
|
||||
// text: clipboard.readText('selection'),
|
||||
// pasteOnNewLine: false
|
||||
// });
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
let setSelectionToClipboard = this._register(new RunOnceScheduler(() => {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
let model = editor.getModel();
|
||||
let selections = editor.getSelections();
|
||||
selections = selections.slice(0);
|
||||
selections.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
let resultLength = 0;
|
||||
for (const sel of selections) {
|
||||
if (sel.isEmpty()) {
|
||||
// Only write if all cursors have selection
|
||||
return;
|
||||
}
|
||||
resultLength += model.getValueLengthInRange(sel);
|
||||
}
|
||||
|
||||
if (resultLength > SelectionClipboard.SELECTION_LENGTH_LIMIT) {
|
||||
// This is a large selection!
|
||||
// => do not write it to the selection clipboard
|
||||
return;
|
||||
}
|
||||
|
||||
let result: string[] = [];
|
||||
for (const sel of selections) {
|
||||
result.push(model.getValueInRange(sel, EndOfLinePreference.TextDefined));
|
||||
}
|
||||
|
||||
let textToCopy = result.join(model.getEOL());
|
||||
clipboardService.writeText(textToCopy, 'selection');
|
||||
}, 100));
|
||||
|
||||
this._register(editor.onDidChangeCursorSelection((e: ICursorSelectionChangedEvent) => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
setSelectionToClipboard.schedule();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return SelectionClipboard.ID;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(SelectionClipboard);
|
||||
export const SelectionClipboardContributionID = 'editor.contrib.selectionClipboard';
|
||||
|
||||
@@ -9,8 +9,9 @@ import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu
|
||||
import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2';
|
||||
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
|
||||
import { MenuPreventer } from 'vs/workbench/contrib/codeEditor/browser/menuPreventer';
|
||||
import { SelectionClipboard } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { TabCompletionController } from 'vs/workbench/contrib/snippets/browser/tabCompletion';
|
||||
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
|
||||
|
||||
export function getSimpleEditorOptions(): IEditorOptions {
|
||||
return {
|
||||
@@ -40,13 +41,13 @@ export function getSimpleEditorOptions(): IEditorOptions {
|
||||
export function getSimpleCodeEditorWidgetOptions(): ICodeEditorWidgetOptions {
|
||||
return {
|
||||
isSimpleWidget: true,
|
||||
contributions: [
|
||||
MenuPreventer,
|
||||
SelectionClipboard,
|
||||
ContextMenuController,
|
||||
SuggestController,
|
||||
SnippetController2,
|
||||
TabCompletionController,
|
||||
]
|
||||
contributions: EditorExtensionsRegistry.getSomeEditorContributions([
|
||||
MenuPreventer.ID,
|
||||
SelectionClipboardContributionID,
|
||||
ContextMenuController.ID,
|
||||
SuggestController.ID,
|
||||
SnippetController2.ID,
|
||||
TabCompletionController.ID,
|
||||
])
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.suggest-input-container {
|
||||
padding: 3px 4px 5px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.suggest-input-container .monaco-editor-background,
|
||||
|
||||
@@ -31,7 +31,8 @@ import { IStyleOverrides, IThemable, attachStyler } from 'vs/platform/theme/comm
|
||||
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { MenuPreventer } from 'vs/workbench/contrib/codeEditor/browser/menuPreventer';
|
||||
import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
|
||||
import { SelectionClipboard } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
|
||||
|
||||
interface SuggestResultsProvider {
|
||||
/**
|
||||
@@ -130,7 +131,13 @@ export class SuggestEnabledInput extends Widget implements IThemable {
|
||||
this.inputWidget = instantiationService.createInstance(CodeEditorWidget, this.stylingContainer,
|
||||
editorOptions,
|
||||
{
|
||||
contributions: [SuggestController, SnippetController2, ContextMenuController, MenuPreventer, SelectionClipboard],
|
||||
contributions: EditorExtensionsRegistry.getSomeEditorContributions([
|
||||
SuggestController.ID,
|
||||
SnippetController2.ID,
|
||||
ContextMenuController.ID,
|
||||
MenuPreventer.ID,
|
||||
SelectionClipboardContributionID,
|
||||
]),
|
||||
isSimpleWidget: true,
|
||||
});
|
||||
this._register(this.inputWidget);
|
||||
@@ -216,7 +223,7 @@ export class SuggestEnabledInput extends Widget implements IThemable {
|
||||
|
||||
|
||||
public style(colors: ISuggestEnabledInputStyles): void {
|
||||
this.stylingContainer.style.backgroundColor = colors.inputBackground ? colors.inputBackground.toString() : null;
|
||||
this.stylingContainer.style.backgroundColor = colors.inputBackground ? colors.inputBackground.toString() : '';
|
||||
this.stylingContainer.style.color = colors.inputForeground ? colors.inputForeground.toString() : null;
|
||||
this.placeholderText.style.color = colors.inputPlaceholderForeground ? colors.inputPlaceholderForeground.toString() : null;
|
||||
|
||||
@@ -228,7 +235,7 @@ export class SuggestEnabledInput extends Widget implements IThemable {
|
||||
|
||||
const cursor = this.stylingContainer.getElementsByClassName('cursor')[0] as HTMLDivElement;
|
||||
if (cursor) {
|
||||
cursor.style.backgroundColor = colors.inputForeground ? colors.inputForeground.toString() : null;
|
||||
cursor.style.backgroundColor = colors.inputForeground ? colors.inputForeground.toString() : '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +297,7 @@ function getSuggestEnabledInputOptions(ariaLabel?: string): IEditorOptions {
|
||||
ariaLabel: ariaLabel || '',
|
||||
|
||||
snippetSuggestions: 'none',
|
||||
suggest: { filterGraceful: false, showIcons: false }
|
||||
suggest: { filterGraceful: false, showIcons: false },
|
||||
autoClosingBrackets: 'never'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ class ToggleWordWrapAction extends EditorAction {
|
||||
|
||||
class ToggleWordWrapController extends Disposable implements IEditorContribution {
|
||||
|
||||
private static readonly _ID = 'editor.contrib.toggleWordWrapController';
|
||||
public static readonly ID = 'editor.contrib.toggleWordWrapController';
|
||||
|
||||
constructor(
|
||||
private readonly editor: ICodeEditor,
|
||||
@@ -254,10 +254,6 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution
|
||||
wordWrapMinified: state.configuredWordWrapMinified
|
||||
});
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return ToggleWordWrapController._ID;
|
||||
}
|
||||
}
|
||||
|
||||
function canToggleWordWrap(uri: URI): boolean {
|
||||
@@ -268,7 +264,7 @@ function canToggleWordWrap(uri: URI): boolean {
|
||||
}
|
||||
|
||||
|
||||
registerEditorContribution(ToggleWordWrapController);
|
||||
registerEditorContribution(ToggleWordWrapController.ID, ToggleWordWrapController);
|
||||
|
||||
registerEditorAction(ToggleWordWrapAction);
|
||||
|
||||
|
||||
@@ -37,4 +37,4 @@ export class WorkbenchReferencesController extends ReferencesController {
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(WorkbenchReferencesController);
|
||||
registerEditorContribution(ReferencesController.ID, WorkbenchReferencesController);
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import './sleepResumeRepaintMinimap';
|
||||
import './selectionClipboard';
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { ICodeEditor, IEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
|
||||
export class SelectionClipboard extends Disposable implements IEditorContribution {
|
||||
private static readonly SELECTION_LENGTH_LIMIT = 65536;
|
||||
|
||||
constructor(editor: ICodeEditor, @IClipboardService clipboardService: IClipboardService) {
|
||||
super();
|
||||
|
||||
if (platform.isLinux) {
|
||||
let isEnabled = editor.getOption(EditorOption.selectionClipboard);
|
||||
|
||||
this._register(editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
|
||||
if (e.hasChanged(EditorOption.selectionClipboard)) {
|
||||
isEnabled = editor.getOption(EditorOption.selectionClipboard);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(editor.onMouseUp((e: IEditorMouseEvent) => {
|
||||
if (!isEnabled) {
|
||||
if (e.event.middleButton) {
|
||||
// try to stop the upcoming paste
|
||||
e.event.preventDefault();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let setSelectionToClipboard = this._register(new RunOnceScheduler(() => {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
let model = editor.getModel();
|
||||
let selections = editor.getSelections();
|
||||
selections = selections.slice(0);
|
||||
selections.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
let resultLength = 0;
|
||||
for (const sel of selections) {
|
||||
if (sel.isEmpty()) {
|
||||
// Only write if all cursors have selection
|
||||
return;
|
||||
}
|
||||
resultLength += model.getValueLengthInRange(sel);
|
||||
}
|
||||
|
||||
if (resultLength > SelectionClipboard.SELECTION_LENGTH_LIMIT) {
|
||||
// This is a large selection!
|
||||
// => do not write it to the selection clipboard
|
||||
return;
|
||||
}
|
||||
|
||||
let result: string[] = [];
|
||||
for (const sel of selections) {
|
||||
result.push(model.getValueInRange(sel, EndOfLinePreference.TextDefined));
|
||||
}
|
||||
|
||||
let textToCopy = result.join(model.getEOL());
|
||||
clipboardService.writeText(textToCopy, 'selection');
|
||||
}, 100));
|
||||
|
||||
this._register(editor.onDidChangeCursorSelection((e: ICursorSelectionChangedEvent) => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (e.source === 'restoreState') {
|
||||
// do not set selection to clipboard if this selection change
|
||||
// was caused by restoring editors...
|
||||
return;
|
||||
}
|
||||
setSelectionToClipboard.schedule();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(SelectionClipboardContributionID, SelectionClipboard);
|
||||
Reference in New Issue
Block a user