Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)

* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463

* fix config changes

* fix strictnull checks
This commit is contained in:
Anthony Dresser
2019-09-15 22:38:26 -07:00
committed by GitHub
parent fa6c52699e
commit ea0f9e6ce9
1226 changed files with 21541 additions and 17633 deletions

View File

@@ -22,6 +22,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant, themeColorFromId } from 'vs/platform/theme/common/themeService';
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const overviewRulerBracketMatchForeground = registerColor('editorOverviewRuler.bracketMatchForeground', { dark: '#A0A0A0', light: '#A0A0A0', hc: '#A0A0A0' }, nls.localize('overviewRulerBracketMatchForeground', 'Overview ruler marker color for matching brackets.'));
@@ -104,7 +105,7 @@ export class BracketMatchingController extends Disposable implements editorCommo
this._lastVersionId = 0;
this._decorations = [];
this._updateBracketsSoon = this._register(new RunOnceScheduler(() => this._updateBrackets(), 50));
this._matchBrackets = this._editor.getConfiguration().contribInfo.matchBrackets;
this._matchBrackets = this._editor.getOption(EditorOption.matchBrackets);
this._updateBracketsSoon.schedule();
this._register(editor.onDidChangeCursorPosition((e) => {
@@ -130,7 +131,7 @@ export class BracketMatchingController extends Disposable implements editorCommo
this._updateBracketsSoon.schedule();
}));
this._register(editor.onDidChangeConfiguration((e) => {
this._matchBrackets = this._editor.getConfiguration().contribInfo.matchBrackets;
this._matchBrackets = this._editor.getOption(EditorOption.matchBrackets);
if (!this._matchBrackets && this._decorations.length > 0) {
// Remove existing decorations if bracket matching is off
this._decorations = this._editor.deltaDecorations(this._decorations, []);
@@ -332,4 +333,4 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
title: nls.localize({ key: 'miGoToBracket', comment: ['&& denotes a mnemonic'] }, "Go to &&Bracket")
},
order: 2
});
});

View File

@@ -16,6 +16,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { MenuId } from 'vs/platform/actions/common/actions';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const CLIPBOARD_CONTEXT_MENU_GROUP = '9_cutcopypaste';
@@ -94,7 +95,7 @@ class ExecCommandCutAction extends ExecCommandAction {
return;
}
const emptySelectionClipboard = editor.getConfiguration().emptySelectionClipboard;
const emptySelectionClipboard = editor.getOption(EditorOption.emptySelectionClipboard);
if (!emptySelectionClipboard && editor.getSelection().isEmpty()) {
return;
@@ -143,7 +144,7 @@ class ExecCommandCopyAction extends ExecCommandAction {
return;
}
const emptySelectionClipboard = editor.getConfiguration().emptySelectionClipboard;
const emptySelectionClipboard = editor.getOption(EditorOption.emptySelectionClipboard);
if (!emptySelectionClipboard && editor.getSelection().isEmpty()) {
return;
@@ -209,7 +210,7 @@ class ExecCommandCopyWithSyntaxHighlightingAction extends ExecCommandAction {
return;
}
const emptySelectionClipboard = editor.getConfiguration().emptySelectionClipboard;
const emptySelectionClipboard = editor.getOption(EditorOption.emptySelectionClipboard);
if (!emptySelectionClipboard && editor.getSelection().isEmpty()) {
return;

View File

@@ -15,7 +15,7 @@ import { CodeAction, CodeActionContext, CodeActionProviderRegistry, CodeActionTr
import { IModelService } from 'vs/editor/common/services/modelService';
import { CodeActionFilter, CodeActionKind, CodeActionTrigger, filtersAction, mayIncludeActionsOfKind } from './codeActionTrigger';
import { TextModelCancellationTokenSource } from 'vs/editor/browser/core/editorState';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle';
export interface CodeActionSet extends IDisposable {
readonly actions: readonly CodeAction[];
@@ -143,6 +143,6 @@ registerLanguageCommand('_executeCodeActionProvider', async function (accessor,
{ type: 'manual', filter: { includeSourceActions: true, kind: kind && kind.value ? new CodeActionKind(kind.value) : undefined } },
CancellationToken.None);
setTimeout(() => codeActionSet.dispose(), 0);
setTimeout(() => codeActionSet.dispose(), 100);
return codeActionSet.actions;
});

View File

@@ -3,30 +3,32 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable } from 'vs/base/common/lifecycle';
import { escapeRegExpCharacters } from 'vs/base/common/strings';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorAction, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { IPosition } from 'vs/editor/common/core/position';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { CodeAction } from 'vs/editor/common/modes';
import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction';
import { CodeActionUi } from 'vs/editor/contrib/codeAction/codeActionUi';
import { MessageController } from 'vs/editor/contrib/message/messageController';
import * as nls from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
import { CodeActionModel, CodeActionsState, SUPPORTED_CODE_ACTIONS } from './codeActionModel';
import { CodeActionAutoApply, CodeActionFilter, CodeActionKind, CodeActionTrigger } from './codeActionTrigger';
import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction';
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { IPosition } from 'vs/editor/common/core/position';
function contextKeyForSupportedActions(kind: CodeActionKind) {
return ContextKeyExpr.regex(
@@ -56,6 +58,7 @@ export class QuickFixController extends Disposable implements IEditorContributio
@IKeybindingService keybindingService: IKeybindingService,
@ICommandService private readonly _commandService: ICommandService,
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
super();
@@ -107,21 +110,42 @@ export class QuickFixController extends Disposable implements IEditorContributio
}
private _applyCodeAction(action: CodeAction): Promise<void> {
return applyCodeAction(action, this._bulkEditService, this._commandService, this._editor);
return this._instantiationService.invokeFunction(applyCodeAction, action, this._bulkEditService, this._commandService, this._editor);
}
}
export async function applyCodeAction(
accessor: ServicesAccessor,
action: CodeAction,
bulkEditService: IBulkEditService,
commandService: ICommandService,
editor?: ICodeEditor,
): Promise<void> {
const notificationService = accessor.get(INotificationService);
if (action.edit) {
await bulkEditService.apply(action.edit, { editor });
}
if (action.command) {
await commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
try {
await commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
} catch (err) {
const message = asMessage(err);
notificationService.error(
typeof message === 'string'
? message
: nls.localize('applyCodeActionFailed', "An unknown error occurred while applying the code action"));
}
}
}
function asMessage(err: any): string | undefined {
if (typeof err === 'string') {
return err;
} else if (err instanceof Error && typeof err.message === 'string') {
return err.message;
} else {
return undefined;
}
}

View File

@@ -17,6 +17,7 @@ import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
import { getCodeActions, CodeActionSet } from './codeAction';
import { CodeActionTrigger } from './codeActionTrigger';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export const SUPPORTED_CODE_ACTIONS = new RawContextKey<string>('supportedCodeAction', '');
@@ -192,7 +193,7 @@ export class CodeActionModel extends Disposable {
const model = this._editor.getModel();
if (model
&& CodeActionProviderRegistry.has(model)
&& !this._editor.getConfiguration().readOnly
&& !this._editor.getOption(EditorOption.readOnly)
) {
const supportedActions: string[] = [];
for (const provider of CodeActionProviderRegistry.all(model)) {

View File

@@ -14,6 +14,7 @@ import { TextModel } from 'vs/editor/common/model/textModel';
import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction';
import * as nls from 'vs/nls';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
namespace LightBulbState {
@@ -78,7 +79,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
// a bit of extra work to make sure the menu
// doesn't cover the line-text
const { top, height } = dom.getDomNodePagePosition(this._domNode);
const { lineHeight } = this._editor.getConfiguration();
const lineHeight = this._editor.getOption(EditorOption.lineHeight);
let pad = Math.floor(lineHeight / 3);
if (this._state.widgetPosition.position !== null && this._state.widgetPosition.position.lineNumber < this._state.editorPosition.lineNumber) {
@@ -106,7 +107,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
}));
this._register(this._editor.onDidChangeConfiguration(e => {
// hide when told to do so
if (e.contribInfo && !this._editor.getConfiguration().contribInfo.lightbulbEnabled) {
if (e.hasChanged(EditorOption.lightbulb) && !this._editor.getOption(EditorOption.lightbulb).enabled) {
this.hide();
}
}));
@@ -137,8 +138,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
return this.hide();
}
const config = this._editor.getConfiguration();
if (!config.contribInfo.lightbulbEnabled) {
const options = this._editor.getOptions();
if (!options.get(EditorOption.lightbulb).enabled) {
return this.hide();
}
@@ -149,9 +150,10 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
}
const tabSize = model.getOptions().tabSize;
const fontInfo = options.get(EditorOption.fontInfo);
const lineContent = model.getLineContent(lineNumber);
const indent = TextModel.computeIndentLevel(lineContent, tabSize);
const lineHasSpace = config.fontInfo.spaceWidth * indent > 22;
const lineHasSpace = fontInfo.spaceWidth * indent > 22;
const isFolded = (lineNumber: number) => {
return lineNumber > 2 && this._editor.getTopForLineNumber(lineNumber) === this._editor.getTopForLineNumber(lineNumber - 1);
};
@@ -162,7 +164,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
effectiveLineNumber -= 1;
} else if (!isFolded(lineNumber + 1)) {
effectiveLineNumber += 1;
} else if (column * config.fontInfo.spaceWidth < 22) {
} else if (column * fontInfo.spaceWidth < 22) {
// cannot show lightbulb above/below and showing
// it inline would overlay the cursor...
return this.hide();

View File

@@ -17,7 +17,7 @@ import { once } from 'vs/base/common/functional';
export const ICodeLensCache = createDecorator<ICodeLensCache>('ICodeLensCache');
export interface ICodeLensCache {
_serviceBrand: any;
_serviceBrand: undefined;
put(model: ITextModel, data: CodeLensModel): void;
get(model: ITextModel): CodeLensModel | undefined;
delete(model: ITextModel): void;
@@ -38,7 +38,7 @@ class CacheItem {
export class CodeLensCache implements ICodeLensCache {
_serviceBrand: any;
_serviceBrand: undefined;
private readonly _fakeProvider = new class implements CodeLensProvider {
provideCodeLenses(): CodeLensList {

View File

@@ -22,14 +22,14 @@ export class CodeLensModel {
lenses: CodeLensItem[] = [];
private readonly _dispoables = new DisposableStore();
private readonly _disposables = new DisposableStore();
dispose(): void {
this._dispoables.dispose();
this._disposables.dispose();
}
add(list: CodeLensList, provider: CodeLensProvider): void {
this._dispoables.add(list);
this._disposables.add(list);
for (const symbol of list.lenses) {
this.lenses.push({ symbol, provider });
}
@@ -89,8 +89,10 @@ registerLanguageCommand('_executeCodeLensProvider', function (accessor, args) {
}
const result: CodeLens[] = [];
const disposables = new DisposableStore();
return getCodeLensData(model, CancellationToken.None).then(value => {
disposables.add(value);
let resolve: Promise<any>[] = [];
for (const item of value.lenses) {
@@ -101,9 +103,13 @@ registerLanguageCommand('_executeCodeLensProvider', function (accessor, args) {
}
}
return Promise.all(resolve).finally(() => setTimeout(() => value.dispose(), 0));
return Promise.all(resolve);
}).then(() => {
return result;
}).finally(() => {
// make sure to return results, then (on next tick)
// dispose the results
setTimeout(() => disposables.dispose(), 100);
});
});

View File

@@ -17,6 +17,7 @@ import { CodeLensWidget, CodeLensHelper } from 'vs/editor/contrib/codelens/codel
import { ICommandService } from 'vs/platform/commands/common/commands';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class CodeLensContribution implements editorCommon.IEditorContribution {
@@ -40,13 +41,13 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
@INotificationService private readonly _notificationService: INotificationService,
@ICodeLensCache private readonly _codeLensCache: ICodeLensCache
) {
this._isEnabled = this._editor.getConfiguration().contribInfo.codeLens;
this._isEnabled = this._editor.getOption(EditorOption.codeLens);
this._globalToDispose.add(this._editor.onDidChangeModel(() => this._onModelChange()));
this._globalToDispose.add(this._editor.onDidChangeModelLanguage(() => this._onModelChange()));
this._globalToDispose.add(this._editor.onDidChangeConfiguration(() => {
const prevIsEnabled = this._isEnabled;
this._isEnabled = this._editor.getConfiguration().contribInfo.codeLens;
this._isEnabled = this._editor.getOption(EditorOption.codeLens);
if (prevIsEnabled !== this._isEnabled) {
this._onModelChange();
}
@@ -204,7 +205,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
}
}));
this._localToDispose.add(this._editor.onDidChangeConfiguration(e => {
if (e.fontInfo) {
if (e.hasChanged(EditorOption.fontInfo)) {
for (const lens of this._lenses) {
lens.updateHeight();
}

View File

@@ -16,6 +16,7 @@ import { editorCodeLensForeground } from 'vs/editor/common/view/editorColorRegis
import { CodeLensItem } from 'vs/editor/contrib/codelens/codelens';
import { editorActiveLinkForeground } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
class CodeLensViewZone implements editorBrowser.IViewZone {
@@ -80,7 +81,9 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
}
updateHeight(): void {
const { fontInfo, lineHeight } = this._editor.getConfiguration();
const options = this._editor.getOptions();
const fontInfo = options.get(EditorOption.fontInfo);
const lineHeight = options.get(EditorOption.lineHeight);
this._domNode.style.height = `${Math.round(lineHeight * 1.1)}px`;
this._domNode.style.lineHeight = `${lineHeight}px`;
this._domNode.style.fontSize = `${Math.round(fontInfo.fontSize * 0.9)}px`;

View File

@@ -19,6 +19,7 @@ import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { ColorProviderRegistry } from 'vs/editor/common/modes';
import { IColorData, getColors } from 'vs/editor/contrib/colorPicker/color';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const MAX_DECORATORS = 500;
@@ -84,7 +85,7 @@ export class ColorDetector extends Disposable implements IEditorContribution {
}
}
return this._editor.getConfiguration().contribInfo.colorDecorators;
return this._editor.getOption(EditorOption.colorDecorators);
}
getId(): string {

View File

@@ -22,6 +22,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ITextModel } from 'vs/editor/common/model';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class ContextMenuController implements IEditorContribution {
@@ -66,7 +67,7 @@ export class ContextMenuController implements IEditorContribution {
return;
}
if (!this._editor.getConfiguration().contribInfo.contextmenu) {
if (!this._editor.getOption(EditorOption.contextmenu)) {
this._editor.focus();
// Ensure the cursor is at the position of the mouse click
if (e.target.position && !this._editor.getSelection().containsPosition(e.target.position)) {
@@ -104,7 +105,7 @@ export class ContextMenuController implements IEditorContribution {
}
public showContextMenu(anchor?: IAnchor | null): void {
if (!this._editor.getConfiguration().contribInfo.contextmenu) {
if (!this._editor.getOption(EditorOption.contextmenu)) {
return; // Context menu is turned off through configuration
}
if (!this._editor.hasModel()) {
@@ -147,7 +148,7 @@ export class ContextMenuController implements IEditorContribution {
}
// Disable hover
const oldHoverSetting = this._editor.getConfiguration().contribInfo.hover;
const oldHoverSetting = this._editor.getOption(EditorOption.hover);
this._editor.updateOptions({
hover: {
enabled: false

View File

@@ -19,6 +19,7 @@ import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { IModelDeltaDecoration } from 'vs/editor/common/model';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
function hasTriggerModifier(e: IKeyboardEvent | IMouseEvent): boolean {
if (isMacintosh) {
@@ -67,7 +68,7 @@ export class DragAndDropController extends Disposable implements editorCommon.IE
}
private onEditorKeyDown(e: IKeyboardEvent): void {
if (!this._editor.getConfiguration().dragAndDrop) {
if (!this._editor.getOption(EditorOption.dragAndDrop)) {
return;
}
@@ -83,7 +84,7 @@ export class DragAndDropController extends Disposable implements editorCommon.IE
}
private onEditorKeyUp(e: IKeyboardEvent): void {
if (!this._editor.getConfiguration().dragAndDrop) {
if (!this._editor.getOption(EditorOption.dragAndDrop)) {
return;
}

View File

@@ -386,6 +386,9 @@ export class OutlineModel extends TreeElement {
protected constructor(readonly textModel: ITextModel) {
super();
this.id = 'root';
this.parent = undefined;
}
adopt(): OutlineModel {

View File

@@ -26,6 +26,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const SEARCH_STRING_MAX_LENGTH = 524288;
@@ -120,7 +121,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
if (shouldRestartFind) {
this._start({
forceRevealReplace: false,
seedSearchStringFromSelection: false && this._editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromSelection: false && this._editor.getOption(EditorOption.find).seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: false,
@@ -352,7 +353,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
public getGlobalBufferTerm(): string {
if (this._editor.getConfiguration().contribInfo.find.globalFindClipboard
if (this._editor.getOption(EditorOption.find).globalFindClipboard
&& this._clipboardService
&& this._editor.hasModel()
&& !this._editor.getModel().isTooLargeForSyncing()
@@ -363,7 +364,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
public setGlobalBufferTerm(text: string) {
if (this._editor.getConfiguration().contribInfo.find.globalFindClipboard
if (this._editor.getOption(EditorOption.find).globalFindClipboard
&& this._clipboardService
&& this._editor.hasModel()
&& !this._editor.getModel().isTooLargeForSyncing()
@@ -398,7 +399,7 @@ export class FindController extends CommonFindController implements IFindControl
this._createFindWidget();
}
if (!this._widget!.getPosition() && this._editor.getConfiguration().contribInfo.find.autoFindInSelection) {
if (!this._widget!.getPosition() && this._editor.getOption(EditorOption.find).autoFindInSelection) {
// not visible yet so we need to set search scope if `editor.find.autoFindInSelection` is `true`
opts.updateSearchScope = true;
}
@@ -456,8 +457,8 @@ export class StartFindAction extends EditorAction {
if (controller) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getConfiguration().contribInfo.find.globalFindClipboard,
seedSearchStringFromSelection: editor.getOption(EditorOption.find).seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getOption(EditorOption.find).globalFindClipboard,
shouldFocus: FindStartFocusAction.FocusFindInput,
shouldAnimate: true,
updateSearchScope: false
@@ -507,7 +508,7 @@ export abstract class MatchFindAction extends EditorAction {
if (controller && !this._run(controller)) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: (controller.getState().searchString.length === 0) && editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromSelection: (controller.getState().searchString.length === 0) && editor.getOption(EditorOption.find).seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: true,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: true,
@@ -619,7 +620,7 @@ export abstract class SelectionMatchFindAction extends EditorAction {
if (!this._run(controller)) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromSelection: editor.getOption(EditorOption.find).seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: true,
@@ -698,7 +699,7 @@ export class StartFindReplaceAction extends EditorAction {
}
public run(accessor: ServicesAccessor | null, editor: ICodeEditor): void {
if (!editor.hasModel() || editor.getConfiguration().readOnly) {
if (!editor.hasModel() || editor.getOption(EditorOption.readOnly)) {
return;
}
@@ -708,7 +709,7 @@ export class StartFindReplaceAction extends EditorAction {
// we only seed search string from selection when the current selection is single line and not empty,
// + the find input is not focused
let seedSearchStringFromSelection = !currentSelection.isEmpty()
&& currentSelection.startLineNumber === currentSelection.endLineNumber && editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection
&& currentSelection.startLineNumber === currentSelection.endLineNumber && editor.getOption(EditorOption.find).seedSearchStringFromSelection
&& !findInputFocused;
/*
* if the existing search string in find widget is empty and we don't seed search string from selection, it means the Find Input is still empty, so we should focus the Find Input instead of Replace Input.
@@ -725,7 +726,7 @@ export class StartFindReplaceAction extends EditorAction {
controller.start({
forceRevealReplace: true,
seedSearchStringFromSelection: seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getOption(EditorOption.find).seedSearchStringFromSelection,
shouldFocus: shouldFocus,
shouldAnimate: true,
updateSearchScope: false

View File

@@ -22,6 +22,7 @@ import { ReplaceAllCommand } from 'vs/editor/contrib/find/replaceAllCommand';
import { ReplacePattern, parseReplaceString } from 'vs/editor/contrib/find/replacePattern';
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
export const CONTEXT_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = CONTEXT_FIND_WIDGET_VISIBLE.toNegated();
@@ -287,12 +288,12 @@ export class FindModelBoundToEditorModel {
let position = new Position(lineNumber, column);
let prevMatch = model.findPreviousMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false);
let prevMatch = model.findPreviousMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false);
if (prevMatch && prevMatch.range.isEmpty() && prevMatch.range.getStartPosition().equals(position)) {
// Looks like we're stuck at this position, unacceptable!
position = this._prevSearchPosition(position);
prevMatch = model.findPreviousMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false);
prevMatch = model.findPreviousMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false);
}
if (!prevMatch) {
@@ -379,12 +380,12 @@ export class FindModelBoundToEditorModel {
let position = new Position(lineNumber, column);
let nextMatch = model.findNextMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, captureMatches);
let nextMatch = model.findNextMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, captureMatches);
if (forceMove && nextMatch && nextMatch.range.isEmpty() && nextMatch.range.getStartPosition().equals(position)) {
// Looks like we're stuck at this position, unacceptable!
position = this._nextSearchPosition(position);
nextMatch = model.findNextMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, captureMatches);
nextMatch = model.findNextMatch(this._state.searchString, position, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, captureMatches);
}
if (!nextMatch) {
@@ -438,7 +439,7 @@ export class FindModelBoundToEditorModel {
private _findMatches(findScope: Range | null, captureMatches: boolean, limitResultCount: number): FindMatch[] {
let searchRange = FindModelBoundToEditorModel._getSearchRange(this._editor.getModel(), findScope);
return this._editor.getModel().findMatches(this._state.searchString, searchRange, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, captureMatches, limitResultCount);
return this._editor.getModel().findMatches(this._state.searchString, searchRange, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, captureMatches, limitResultCount);
}
public replaceAll(): void {
@@ -459,7 +460,7 @@ export class FindModelBoundToEditorModel {
}
private _largeReplaceAll(): void {
const searchParams = new SearchParams(this._state.searchString, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null);
const searchParams = new SearchParams(this._state.searchString, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null);
const searchData = searchParams.parseSearchRequest();
if (!searchData) {
return;
@@ -467,7 +468,7 @@ export class FindModelBoundToEditorModel {
let searchRegex = searchData.regex;
if (!searchRegex.multiline) {
let mod = 'm';
let mod = 'mu';
if (searchRegex.ignoreCase) {
mod += 'i';
}

View File

@@ -23,7 +23,7 @@ import { toDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Range } from 'vs/editor/common/core/range';
import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_REPLACE_INPUT_FOCUSED, FIND_IDS, MATCHES_LIMIT } from 'vs/editor/contrib/find/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
@@ -67,6 +67,7 @@ let FIND_ALL_CONTROLS_WIDTH = 17/** Find Input margin-left */ + (MAX_MATCHES_COU
const FIND_INPUT_AREA_HEIGHT = 33; // The height of Find Widget when Replace Input is not visible.
const ctrlEnterReplaceAllWarningPromptedKey = 'ctrlEnterReplaceAll.windows.donotask';
const ctrlKeyMod = (platform.isMacintosh ? KeyMod.WinCtrl : KeyMod.CtrlCmd);
export class FindWidgetViewZone implements IViewZone {
public readonly afterLineNumber: number;
public heightInPx: number;
@@ -111,7 +112,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
private readonly _notificationService: INotificationService;
private _domNode!: HTMLElement;
private _cachedHeight: number | null;
private _cachedHeight: number | null = null;
private _findInput!: FindInput;
private _replaceInput!: ReplaceInput;
@@ -175,24 +176,24 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._tryUpdateWidgetWidth();
this._findInput.inputBox.layout();
this._register(this._codeEditor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.readOnly) {
if (this._codeEditor.getConfiguration().readOnly) {
this._register(this._codeEditor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
if (e.hasChanged(EditorOption.readOnly)) {
if (this._codeEditor.getOption(EditorOption.readOnly)) {
// Hide replace part if editor becomes read only
this._state.change({ isReplaceRevealed: false }, false);
}
this._updateButtons();
}
if (e.layoutInfo) {
if (e.hasChanged(EditorOption.layoutInfo)) {
this._tryUpdateWidgetWidth();
}
if (e.accessibilitySupport) {
if (e.hasChanged(EditorOption.accessibilitySupport)) {
this.updateAccessibilitySupport();
}
if (e.contribInfo) {
const addExtraSpaceOnTop = this._codeEditor.getConfiguration().contribInfo.find.addExtraSpaceOnTop;
if (e.hasChanged(EditorOption.find)) {
const addExtraSpaceOnTop = this._codeEditor.getOption(EditorOption.find).addExtraSpaceOnTop;
if (addExtraSpaceOnTop && !this._viewZone) {
this._viewZone = new FindWidgetViewZone(0);
this._showViewZone();
@@ -238,7 +239,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}));
this._codeEditor.addOverlayWidget(this);
if (this._codeEditor.getConfiguration().contribInfo.find.addExtraSpaceOnTop) {
if (this._codeEditor.getOption(EditorOption.find).addExtraSpaceOnTop) {
this._viewZone = new FindWidgetViewZone(0); // Put it before the first line then users can scroll beyond the first line.
}
@@ -315,7 +316,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
if (e.isReplaceRevealed) {
if (this._state.isReplaceRevealed) {
if (!this._codeEditor.getConfiguration().readOnly && !this._isReplaceVisible) {
if (!this._codeEditor.getOption(EditorOption.readOnly) && !this._isReplaceVisible) {
this._isReplaceVisible = true;
this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode);
this._updateButtons();
@@ -456,7 +457,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._toggleReplaceBtn.toggleClass('expand', this._isReplaceVisible);
this._toggleReplaceBtn.setExpanded(this._isReplaceVisible);
let canReplace = !this._codeEditor.getConfiguration().readOnly;
let canReplace = !this._codeEditor.getOption(EditorOption.readOnly);
this._toggleReplaceBtn.setEnabled(this._isVisible && canReplace);
}
@@ -466,7 +467,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
const selection = this._codeEditor.getSelection();
const isSelection = selection ? (selection.startLineNumber !== selection.endLineNumber || selection.startColumn !== selection.endColumn) : false;
if (isSelection && this._codeEditor.getConfiguration().contribInfo.find.autoFindInSelection) {
if (isSelection && this._codeEditor.getOption(EditorOption.find).autoFindInSelection) {
this._toggleSelectionFind.checked = true;
} else {
this._toggleSelectionFind.checked = false;
@@ -487,7 +488,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._codeEditor.layoutOverlayWidget(this);
let adjustEditorScrollTop = true;
if (this._codeEditor.getConfiguration().contribInfo.find.seedSearchStringFromSelection && selection) {
if (this._codeEditor.getOption(EditorOption.find).seedSearchStringFromSelection && selection) {
const domNode = this._codeEditor.getDomNode();
if (domNode) {
const editorCoords = dom.getDomNodePagePosition(domNode);
@@ -534,7 +535,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
private _layoutViewZone() {
const addExtraSpaceOnTop = this._codeEditor.getConfiguration().contribInfo.find.addExtraSpaceOnTop;
const addExtraSpaceOnTop = this._codeEditor.getOption(EditorOption.find).addExtraSpaceOnTop;
if (!addExtraSpaceOnTop) {
this._removeViewZone();
@@ -562,7 +563,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
return;
}
const addExtraSpaceOnTop = this._codeEditor.getConfiguration().contribInfo.find.addExtraSpaceOnTop;
const addExtraSpaceOnTop = this._codeEditor.getOption(EditorOption.find).addExtraSpaceOnTop;
if (!addExtraSpaceOnTop) {
return;
@@ -642,7 +643,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
return;
}
const editorContentWidth = this._codeEditor.getConfiguration().layoutInfo.contentWidth;
const layoutInfo = this._codeEditor.getLayoutInfo();
const editorContentWidth = layoutInfo.contentWidth;
if (editorContentWidth <= 0) {
// for example, diff view original editor
@@ -652,8 +654,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
dom.removeClass(this._domNode, 'hiddenEditor');
}
const editorWidth = this._codeEditor.getConfiguration().layoutInfo.width;
const minimapWidth = this._codeEditor.getConfiguration().layoutInfo.minimapWidth;
const editorWidth = layoutInfo.width;
const minimapWidth = layoutInfo.minimapWidth;
let collapsedFindWidget = false;
let reducedFindWidget = false;
let narrowFindWidget = false;
@@ -775,20 +777,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
private _onFindInputKeyDown(e: IKeyboardEvent): void {
if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) {
const inputElement = this._findInput.inputBox.inputElement;
const start = inputElement.selectionStart;
const end = inputElement.selectionEnd;
const content = inputElement.value;
if (start && end) {
const value = content.substr(0, start) + '\n' + content.substr(end);
this._findInput.inputBox.value = value;
inputElement.setSelectionRange(start + 1, start + 1);
this._findInput.inputBox.layout();
e.preventDefault();
return;
}
if (e.equals(ctrlKeyMod | KeyCode.Enter)) {
this._findInput.inputBox.insertAtCursor('\n');
e.preventDefault();
return;
}
if (e.equals(KeyCode.Tab)) {
@@ -817,7 +809,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
private _onReplaceInputKeyDown(e: IKeyboardEvent): void {
if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) {
if (e.equals(ctrlKeyMod | KeyCode.Enter)) {
if (platform.isWindows && platform.isNative && !this._ctrlEnterReplaceAllWarningPrompted) {
// this is the first time when users press Ctrl + Enter to replace all
this._notificationService.info(
@@ -830,19 +822,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
const inputElement = this._replaceInput.inputBox.inputElement;
const start = inputElement.selectionStart;
const end = inputElement.selectionEnd;
const content = inputElement.value;
if (start && end) {
const value = content.substr(0, start) + '\n' + content.substr(end);
this._replaceInput.inputBox.value = value;
inputElement.setSelectionRange(start + 1, start + 1);
this._replaceInput.inputBox.layout();
e.preventDefault();
return;
}
this._replaceInput.inputBox.insertAtCursor('\n');
e.preventDefault();
return;
}
if (e.equals(KeyCode.Tab)) {
@@ -1187,7 +1169,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
if (!this._resized || currentWidth === FIND_WIDGET_INITIAL_WIDTH) {
// 1. never resized before, double click should maximizes it
// 2. users resized it already but its width is the same as default
width = this._codeEditor.getConfiguration().layoutInfo.width - 28 - this._codeEditor.getConfiguration().layoutInfo.minimapWidth - 15;
const layoutInfo = this._codeEditor.getLayoutInfo();
width = layoutInfo.width - 28 - layoutInfo.minimapWidth - 15;
this._resized = true;
} else {
/**
@@ -1208,7 +1191,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
private updateAccessibilitySupport(): void {
const value = this._codeEditor.getConfiguration().accessibilitySupport;
const value = this._codeEditor.getOption(EditorOption.accessibilitySupport);
this._findInput.setFocusInputOnOptionClick(value !== AccessibilitySupport.Enabled);
}
}

View File

@@ -183,6 +183,15 @@ suite('Replace Pattern test', () => {
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo-newbar-newabc'), 'Newfoo-Newbar-Newabc');
actual = ['Foo-Bar-abc'];
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo-newbar'), 'Newfoo-newbar');
actual = ['Foo_Bar'];
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo_newbar'), 'Newfoo_Newbar');
actual = ['Foo_Bar_Abc'];
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo_newbar_newabc'), 'Newfoo_Newbar_Newabc');
actual = ['Foo_Bar_abc'];
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo_newbar'), 'Newfoo_newbar');
actual = ['Foo_Bar-abc'];
assert.equal(buildReplaceStringWithCasePreserved(actual, 'newfoo_newbar-abc'), 'Newfoo_newbar-abc');
});
test('preserve case', () => {
@@ -217,5 +226,21 @@ suite('Replace Pattern test', () => {
replacePattern = parseReplaceString('newfoo-newbar');
actual = replacePattern.buildReplaceString(['Foo-Bar-abc'], true);
assert.equal(actual, 'Newfoo-newbar');
replacePattern = parseReplaceString('newfoo_newbar');
actual = replacePattern.buildReplaceString(['Foo_Bar'], true);
assert.equal(actual, 'Newfoo_Newbar');
replacePattern = parseReplaceString('newfoo_newbar_newabc');
actual = replacePattern.buildReplaceString(['Foo_Bar_Abc'], true);
assert.equal(actual, 'Newfoo_Newbar_Newabc');
replacePattern = parseReplaceString('newfoo_newbar');
actual = replacePattern.buildReplaceString(['Foo_Bar_abc'], true);
assert.equal(actual, 'Newfoo_newbar');
replacePattern = parseReplaceString('newfoo_newbar-abc');
actual = replacePattern.buildReplaceString(['Foo_Bar-abc'], true);
assert.equal(actual, 'Newfoo_newbar-abc');
});
});

View File

@@ -18,7 +18,7 @@ import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStat
import { FoldingDecorationProvider } from './foldingDecorations';
import { FoldingRegions, FoldingRegion } from './foldingRanges';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { IMarginData, IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget';
import { HiddenRangeModel } from 'vs/editor/contrib/folding/hiddenRangeModel';
import { IRange } from 'vs/editor/common/core/range';
@@ -87,9 +87,10 @@ export class FoldingController extends Disposable implements IEditorContribution
) {
super();
this.editor = editor;
this._isEnabled = this.editor.getConfiguration().contribInfo.folding;
this._autoHideFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls === 'mouseover';
this._useFoldingProviders = this.editor.getConfiguration().contribInfo.foldingStrategy !== 'indentation';
const options = this.editor.getOptions();
this._isEnabled = options.get(EditorOption.folding);
this._autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
this.foldingModel = null;
this.hiddenRangeModel = null;
@@ -108,22 +109,23 @@ export class FoldingController extends Disposable implements IEditorContribution
this._register(this.editor.onDidChangeModel(() => this.onModelChanged()));
this._register(this.editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.contribInfo) {
this._register(this.editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
if (e.hasChanged(EditorOption.folding) || e.hasChanged(EditorOption.showFoldingControls) || e.hasChanged(EditorOption.foldingStrategy)) {
let oldIsEnabled = this._isEnabled;
this._isEnabled = this.editor.getConfiguration().contribInfo.folding;
const options = this.editor.getOptions();
this._isEnabled = options.get(EditorOption.folding);
this.foldingEnabled.set(this._isEnabled);
if (oldIsEnabled !== this._isEnabled) {
this.onModelChanged();
}
let oldShowFoldingControls = this._autoHideFoldingControls;
this._autoHideFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls === 'mouseover';
this._autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
if (oldShowFoldingControls !== this._autoHideFoldingControls) {
this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls;
this.onModelContentChanged();
}
let oldUseFoldingProviders = this._useFoldingProviders;
this._useFoldingProviders = this.editor.getConfiguration().contribInfo.foldingStrategy !== 'indentation';
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
if (oldUseFoldingProviders !== this._useFoldingProviders) {
this.onFoldingStrategyChanged();
}

View File

@@ -24,6 +24,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { onUnexpectedError } from 'vs/base/common/errors';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
class FormatOnType implements editorCommon.IEditorContribution {
@@ -59,7 +60,7 @@ class FormatOnType implements editorCommon.IEditorContribution {
this._callOnModel.clear();
// we are disabled
if (!this._editor.getConfiguration().contribInfo.formatOnType) {
if (!this._editor.getOption(EditorOption.formatOnType)) {
return;
}
@@ -184,7 +185,7 @@ class FormatOnPaste implements editorCommon.IEditorContribution {
this._callOnModel.clear();
// we are disabled
if (!this.editor.getConfiguration().contribInfo.formatOnPaste) {
if (!this.editor.getOption(EditorOption.formatOnPaste)) {
return;
}

View File

@@ -12,6 +12,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { Event, Emitter } from 'vs/base/common/event';
import * as platform from 'vs/base/common/platform';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
function hasModifier(e: { ctrlKey: boolean; shiftKey: boolean; altKey: boolean; metaKey: boolean }, modifier: 'ctrlKey' | 'shiftKey' | 'altKey' | 'metaKey'): boolean {
return !!e[modifier];
@@ -116,14 +117,14 @@ export class ClickLinkGesture extends Disposable {
super();
this._editor = editor;
this._opts = createOptions(this._editor.getConfiguration().multiCursorModifier);
this._opts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier));
this.lastMouseMoveEvent = null;
this.hasTriggerKeyOnMouseDown = false;
this._register(this._editor.onDidChangeConfiguration((e) => {
if (e.multiCursorModifier) {
const newOpts = createOptions(this._editor.getConfiguration().multiCursorModifier);
if (e.hasChanged(EditorOption.multiCursorModifier)) {
const newOpts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier));
if (this._opts.equals(newOpts)) {
return;
}

View File

@@ -30,6 +30,7 @@ import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefiniti
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState';
import { ISymbolNavigationService } from 'vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class DefinitionActionConfig {
@@ -137,7 +138,7 @@ export class DefinitionAction extends EditorAction {
const msg = model.getAriaMessage();
alert(msg);
const { gotoLocation } = editor.getConfiguration().contribInfo;
const gotoLocation = editor.getOption(EditorOption.gotoLocation);
if (this._configuration.openInPeek || (gotoLocation.multiple === 'peek' && model.references.length > 1)) {
this._openInPeek(editorService, editor, model);

View File

@@ -24,7 +24,7 @@ export const ctxHasSymbols = new RawContextKey('hasSymbols', false);
export const ISymbolNavigationService = createDecorator<ISymbolNavigationService>('ISymbolNavigationService');
export interface ISymbolNavigationService {
_serviceBrand: any;
_serviceBrand: undefined;
reset(): void;
put(anchor: OneReference): void;
revealNext(source: ICodeEditor): Promise<any>;
@@ -32,7 +32,7 @@ export interface ISymbolNavigationService {
class SymbolNavigationService implements ISymbolNavigationService {
_serviceBrand: any;
_serviceBrand: undefined;
private readonly _ctxHasSymbols: IContextKey<boolean>;

View File

@@ -6,7 +6,7 @@
import 'vs/css!./media/gotoErrorWidget';
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { IMarker, MarkerSeverity, IRelatedInformation } from 'vs/platform/markers/common/markers';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@@ -26,6 +26,7 @@ import { IAction } from 'vs/base/common/actions';
import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget';
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
class MessageWidget {
@@ -37,7 +38,7 @@ class MessageWidget {
private readonly _relatedBlock: HTMLDivElement;
private readonly _scrollable: ScrollableElement;
private readonly _relatedDiagnostics = new WeakMap<HTMLElement, IRelatedInformation>();
private readonly _disposables: IDisposable[] = [];
private readonly _disposables: DisposableStore = new DisposableStore();
constructor(parent: HTMLElement, editor: ICodeEditor, onRelatedInformation: (related: IRelatedInformation) => void) {
this._editor = editor;
@@ -53,7 +54,7 @@ class MessageWidget {
this._relatedBlock = document.createElement('div');
domNode.appendChild(this._relatedBlock);
this._disposables.push(dom.addStandardDisposableListener(this._relatedBlock, 'click', event => {
this._disposables.add(dom.addStandardDisposableListener(this._relatedBlock, 'click', event => {
event.preventDefault();
const related = this._relatedDiagnostics.get(event.target);
if (related) {
@@ -69,11 +70,11 @@ class MessageWidget {
verticalScrollbarSize: 3
});
parent.appendChild(this._scrollable.getDomNode());
this._disposables.push(this._scrollable.onScroll(e => {
this._disposables.add(this._scrollable.onScroll(e => {
domNode.style.left = `-${e.scrollLeft}px`;
domNode.style.top = `-${e.scrollTop}px`;
}));
this._disposables.push(this._scrollable);
this._disposables.add(this._scrollable);
}
dispose(): void {
@@ -122,7 +123,7 @@ class MessageWidget {
this._editor.applyFontInfo(this._relatedBlock);
if (isNonEmptyArray(relatedInformation)) {
const relatedInformationNode = this._relatedBlock.appendChild(document.createElement('div'));
relatedInformationNode.style.paddingTop = `${Math.floor(this._editor.getConfiguration().lineHeight * 0.66)}px`;
relatedInformationNode.style.paddingTop = `${Math.floor(this._editor.getOption(EditorOption.lineHeight) * 0.66)}px`;
this._lines += 1;
for (const related of relatedInformation) {
@@ -146,7 +147,7 @@ class MessageWidget {
}
}
const fontInfo = this._editor.getConfiguration().fontInfo;
const fontInfo = this._editor.getOption(EditorOption.fontInfo);
const scrollWidth = Math.ceil(fontInfo.typicalFullwidthCharacterWidth * this._longestLineLength * 0.75);
const scrollHeight = fontInfo.lineHeight * this._lines;
this._scrollable.setScrollDimensions({ scrollWidth, scrollHeight });

View File

@@ -55,9 +55,13 @@
margin-bottom: 0;
}
/* MarkupContent Layout */
.monaco-editor-hover ul {
padding-left: 20px;
}
.monaco-editor-hover ol {
padding-left: 20px;
}
.monaco-editor-hover li > p {
margin-bottom: 0;

View File

@@ -11,7 +11,7 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Range } from 'vs/editor/common/core/range';
import { IEditorContribution, IScrollEvent } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
@@ -74,8 +74,8 @@ export class ModesHoverController implements IEditorContribution {
this._hookEvents();
this._didChangeConfigurationHandler = this._editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.contribInfo) {
this._didChangeConfigurationHandler = this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
if (e.hasChanged(EditorOption.hover)) {
this._hideWidgets();
this._unhookEvents();
this._hookEvents();
@@ -86,7 +86,7 @@ export class ModesHoverController implements IEditorContribution {
private _hookEvents(): void {
const hideWidgetsEventHandler = () => this._hideWidgets();
const hoverOpts = this._editor.getConfiguration().contribInfo.hover;
const hoverOpts = this._editor.getOption(EditorOption.hover);
this._isHoverEnabled = hoverOpts.enabled;
this._isHoverSticky = hoverOpts.sticky;
if (this._isHoverEnabled) {
@@ -147,7 +147,6 @@ export class ModesHoverController implements IEditorContribution {
}
private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void {
// const this._editor.getConfiguration().contribInfo.hover.sticky;
let targetType = mouseEvent.target.type;
if (this._isMouseDown && this._hoverClicked && this.contentWidget.isColorPickerVisible()) {
@@ -165,7 +164,7 @@ export class ModesHoverController implements IEditorContribution {
}
if (targetType === MouseTargetType.CONTENT_EMPTY) {
const epsilon = this._editor.getConfiguration().fontInfo.typicalHalfwidthCharacterWidth / 2;
const epsilon = this._editor.getOption(EditorOption.fontInfo).typicalHalfwidthCharacterWidth / 2;
const data = <IEmptyContentData>mouseEvent.target.detail;
if (data && !data.isAfterLines && typeof data.horizontalDistanceToText === 'number' && data.horizontalDistanceToText < epsilon) {
// Let hover kick in even when the mouse is technically in the empty area after a line, given the distance is small enough
@@ -265,7 +264,7 @@ class ShowHoverAction extends EditorAction {
}
const position = editor.getPosition();
const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);
const focus = editor.getConfiguration().accessibilitySupport === AccessibilitySupport.Enabled;
const focus = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled;
controller.showContentHover(range, HoverStartMode.Immediate, focus);
}
}

View File

@@ -8,15 +8,15 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { Widget } from 'vs/base/browser/ui/widget';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { IContentWidget, ICodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
export class ContentHoverWidget extends Widget implements editorBrowser.IContentWidget {
export class ContentHoverWidget extends Widget implements IContentWidget {
private readonly _id: string;
protected _editor: editorBrowser.ICodeEditor;
protected _editor: ICodeEditor;
private _isVisible: boolean;
private readonly _containerDomNode: HTMLElement;
private readonly _domNode: HTMLElement;
@@ -37,7 +37,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent
toggleClass(this._containerDomNode, 'hidden', !this._isVisible);
}
constructor(id: string, editor: editorBrowser.ICodeEditor) {
constructor(id: string, editor: ICodeEditor) {
super();
this._id = id;
this._editor = editor;
@@ -61,8 +61,8 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent
}
});
this._register(this._editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.fontInfo) {
this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
if (e.hasChanged(EditorOption.fontInfo)) {
this.updateFont();
}
}));
@@ -113,14 +113,14 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent
}
}
public getPosition(): editorBrowser.IContentWidgetPosition | null {
public getPosition(): IContentWidgetPosition | null {
if (this.isVisible) {
return {
position: this._showAtPosition,
range: this._showAtRange,
preference: [
editorBrowser.ContentWidgetPositionPreference.ABOVE,
editorBrowser.ContentWidgetPositionPreference.BELOW
ContentWidgetPositionPreference.ABOVE,
ContentWidgetPositionPreference.BELOW
]
};
}
@@ -152,7 +152,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent
private layout(): void {
const height = Math.max(this._editor.getLayoutInfo().height / 4, 250);
const { fontSize, lineHeight } = this._editor.getConfiguration().fontInfo;
const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo);
this._domNode.style.fontSize = `${fontSize}px`;
this._domNode.style.lineHeight = `${lineHeight}px`;
@@ -161,15 +161,15 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent
}
}
export class GlyphHoverWidget extends Widget implements editorBrowser.IOverlayWidget {
export class GlyphHoverWidget extends Widget implements IOverlayWidget {
private readonly _id: string;
protected _editor: editorBrowser.ICodeEditor;
protected _editor: ICodeEditor;
private _isVisible: boolean;
private readonly _domNode: HTMLElement;
protected _showAtLineNumber: number;
constructor(id: string, editor: editorBrowser.ICodeEditor) {
constructor(id: string, editor: ICodeEditor) {
super();
this._id = id;
this._editor = editor;
@@ -182,8 +182,8 @@ export class GlyphHoverWidget extends Widget implements editorBrowser.IOverlayWi
this._showAtLineNumber = -1;
this._register(this._editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.fontInfo) {
this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
if (e.hasChanged(EditorOption.fontInfo)) {
this.updateFont();
}
}));
@@ -218,7 +218,7 @@ export class GlyphHoverWidget extends Widget implements editorBrowser.IOverlayWi
const editorLayout = this._editor.getLayoutInfo();
const topForLineNumber = this._editor.getTopForLineNumber(this._showAtLineNumber);
const editorScrollTop = this._editor.getScrollTop();
const lineHeight = this._editor.getConfiguration().lineHeight;
const lineHeight = this._editor.getOption(EditorOption.lineHeight);
const nodeHeight = this._domNode.clientHeight;
const top = topForLineNumber - editorScrollTop - ((nodeHeight - lineHeight) / 2);
@@ -233,7 +233,7 @@ export class GlyphHoverWidget extends Widget implements editorBrowser.IOverlayWi
this.isVisible = false;
}
public getPosition(): editorBrowser.IOverlayWidgetPosition | null {
public getPosition(): IOverlayWidgetPosition | null {
return null;
}

View File

@@ -37,6 +37,7 @@ import { QuickFixAction, QuickFixController } from 'vs/editor/contrib/codeAction
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const $ = dom.$;
@@ -222,7 +223,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
result => this._withResult(result, true),
null,
result => this._withResult(result, false),
this._editor.getConfiguration().contribInfo.hover.delay
this._editor.getOption(EditorOption.hover).delay
);
this._register(dom.addStandardDisposableListener(this.getDomNode(), dom.EventType.FOCUS, () => {
@@ -234,7 +235,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
dom.removeClass(this.getDomNode(), 'colorpicker-hover');
}));
this._register(editor.onDidChangeConfiguration((e) => {
this._hoverOperation.setHoverTime(this._editor.getConfiguration().contribInfo.hover.delay);
this._hoverOperation.setHoverTime(this._editor.getOption(EditorOption.hover).delay);
}));
}
@@ -365,7 +366,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
// create blank olor picker model and widget first to ensure it's positioned correctly.
const model = new ColorPickerModel(color, [], 0);
const widget = new ColorPickerWidget(fragment, model, this._editor.getConfiguration().pixelRatio, this._themeService);
const widget = new ColorPickerWidget(fragment, model, this._editor.getOption(EditorOption.pixelRatio), this._themeService);
getColorPresentations(editorModel, colorInfo, msg.provider, CancellationToken.None).then(colorPresentations => {
model.colorPresentations = colorPresentations || [];

View File

@@ -22,6 +22,7 @@ import { IndentConsts } from 'vs/editor/common/modes/supports/indentRules';
import { IModelService } from 'vs/editor/common/services/modelService';
import * as indentUtils from 'vs/editor/contrib/indentation/indentUtils';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export function getReindentEditOperations(model: ITextModel, startLineNumber: number, endLineNumber: number, inheritedIndent?: string): IIdentifiedSingleEditOperation[] {
if (model.getLineCount() === 1 && model.getLineMaxColumn(1) === 1) {
@@ -443,7 +444,7 @@ export class AutoIndentOnPaste implements IEditorContribution {
this.callOnModel = dispose(this.callOnModel);
// we are disabled
if (!this.editor.getConfiguration().autoIndent || this.editor.getConfiguration().contribInfo.formatOnPaste) {
if (!this.editor.getOption(EditorOption.autoIndent) || this.editor.getOption(EditorOption.formatOnPaste)) {
return;
}

View File

@@ -23,6 +23,7 @@ import { MoveLinesCommand } from 'vs/editor/contrib/linesOperations/moveLinesCom
import { SortLinesCommand } from 'vs/editor/contrib/linesOperations/sortLinesCommand';
import { MenuId } from 'vs/platform/actions/common/actions';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
// copy lines
@@ -111,7 +112,7 @@ abstract class AbstractMoveLinesAction extends EditorAction {
let commands: ICommand[] = [];
let selections = editor.getSelections() || [];
let autoIndent = editor.getConfiguration().autoIndent;
const autoIndent = editor.getOption(EditorOption.autoIndent);
for (const selection of selections) {
commands.push(new MoveLinesCommand(selection, this.down, autoIndent));
@@ -886,7 +887,7 @@ export abstract class AbstractCaseAction extends EditorAction {
return;
}
let wordSeparators = editor.getConfiguration().wordSeparators;
let wordSeparators = editor.getOption(EditorOption.wordSeparators);
let commands: ICommand[] = [];

View File

@@ -24,6 +24,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { editorActiveLinkForeground } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
function getHoverMessage(link: Link, useMetaKey: boolean): MarkdownString {
const executeCmd = link.url && /^command:/i.test(link.url.toString());
@@ -139,9 +140,9 @@ class LinkDetector implements editorCommon.IEditorContribution {
this.cleanUpActiveLinkDecoration();
}));
this.enabled = editor.getConfiguration().contribInfo.links;
this.enabled = editor.getOption(EditorOption.links);
this.listenersToRemove.add(editor.onDidChangeConfiguration((e) => {
let enabled = editor.getConfiguration().contribInfo.links;
const enabled = editor.getOption(EditorOption.links);
if (this.enabled === enabled) {
// No change in our configuration option
return;
@@ -218,7 +219,7 @@ class LinkDetector implements editorCommon.IEditorContribution {
}
private updateDecorations(links: Link[]): void {
const useMetaKey = (this.editor.getConfiguration().multiCursorModifier === 'altKey');
const useMetaKey = (this.editor.getOption(EditorOption.multiCursorModifier) === 'altKey');
let oldDecorations: string[] = [];
let keys = Object.keys(this.currentOccurrences);
for (let i = 0, len = keys.length; i < len; i++) {
@@ -246,7 +247,7 @@ class LinkDetector implements editorCommon.IEditorContribution {
}
private _onEditorMouseMove(mouseEvent: ClickLinkMouseEvent, withKey: ClickLinkKeyboardEvent | null): void {
const useMetaKey = (this.editor.getConfiguration().multiCursorModifier === 'altKey');
const useMetaKey = (this.editor.getOption(EditorOption.multiCursorModifier) === 'altKey');
if (this.isEnabled(mouseEvent, withKey)) {
this.cleanUpActiveLinkDecoration(); // always remove previous link decoration as their can only be one
const occurrence = this.getLinkOccurrence(mouseEvent.target.position);
@@ -262,7 +263,7 @@ class LinkDetector implements editorCommon.IEditorContribution {
}
private cleanUpActiveLinkDecoration(): void {
const useMetaKey = (this.editor.getConfiguration().multiCursorModifier === 'altKey');
const useMetaKey = (this.editor.getOption(EditorOption.multiCursorModifier) === 'altKey');
if (this.activeLinkDecorationId) {
const occurrence = this.currentOccurrences[this.activeLinkDecorationId];
if (occurrence) {

View File

@@ -15,6 +15,7 @@ import { optional } from 'vs/platform/instantiation/common/instantiation';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { TokenizationRegistry } from 'vs/editor/common/modes';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export interface IMarkdownRenderResult extends IDisposable {
element: HTMLElement;
@@ -57,7 +58,7 @@ export class MarkdownRenderer extends Disposable {
}
return tokenizeToString(value, undefined);
}).then(code => {
return `<span style="font-family: ${this._editor.getConfiguration().fontInfo.fontFamily}">${code}</span>`;
return `<span style="font-family: ${this._editor.getOption(EditorOption.fontInfo).fontFamily}">${code}</span>`;
});
},
codeBlockRenderCallback: () => this._onDidRenderCodeBlock.fire(),

View File

@@ -26,6 +26,7 @@ import { MenuId } from 'vs/platform/actions/common/actions';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { overviewRulerSelectionHighlightForeground } from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class InsertCursorAbove extends EditorAction {
@@ -72,7 +73,7 @@ export class InsertCursorAbove extends EditorAction {
CursorChangeReason.Explicit,
CursorMoveCommands.addCursorUp(context, cursors.getAll(), useLogicalLine)
);
cursors.reveal(true, RevealTarget.TopMost, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.TopMost, ScrollType.Smooth);
}
}
@@ -121,7 +122,7 @@ export class InsertCursorBelow extends EditorAction {
CursorChangeReason.Explicit,
CursorMoveCommands.addCursorDown(context, cursors.getAll(), useLogicalLine)
);
cursors.reveal(true, RevealTarget.BottomMost, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.BottomMost, ScrollType.Smooth);
}
}
@@ -350,7 +351,7 @@ export class MultiCursorSession {
const allSelections = this._editor.getSelections();
const lastAddedSelection = allSelections[allSelections.length - 1];
const nextMatch = this._editor.getModel().findNextMatch(this.searchText, lastAddedSelection.getEndPosition(), false, this.matchCase, this.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false);
const nextMatch = this._editor.getModel().findNextMatch(this.searchText, lastAddedSelection.getEndPosition(), false, this.matchCase, this.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false);
if (!nextMatch) {
return null;
@@ -401,7 +402,7 @@ export class MultiCursorSession {
const allSelections = this._editor.getSelections();
const lastAddedSelection = allSelections[allSelections.length - 1];
const previousMatch = this._editor.getModel().findPreviousMatch(this.searchText, lastAddedSelection.getStartPosition(), false, this.matchCase, this.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false);
const previousMatch = this._editor.getModel().findPreviousMatch(this.searchText, lastAddedSelection.getStartPosition(), false, this.matchCase, this.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false);
if (!previousMatch) {
return null;
@@ -416,7 +417,7 @@ export class MultiCursorSession {
this.findController.highlightFindOptions();
return this._editor.getModel().findMatches(this.searchText, true, false, this.matchCase, this.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false, Constants.MAX_SAFE_SMALL_INTEGER);
return this._editor.getModel().findMatches(this.searchText, true, false, this.matchCase, this.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false, Constants.MAX_SAFE_SMALL_INTEGER);
}
}
@@ -593,7 +594,7 @@ export class MultiCursorSelectionController extends Disposable implements IEdito
// - and we're searching for a regex
if (findState.isRevealed && findState.searchString.length > 0 && findState.isRegex) {
matches = this._editor.getModel().findMatches(findState.searchString, true, findState.isRegex, findState.matchCase, findState.wholeWord ? this._editor.getConfiguration().wordSeparators : null, false, Constants.MAX_SAFE_SMALL_INTEGER);
matches = this._editor.getModel().findMatches(findState.searchString, true, findState.isRegex, findState.matchCase, findState.wholeWord ? this._editor.getOption(EditorOption.wordSeparators) : null, false, Constants.MAX_SAFE_SMALL_INTEGER);
} else {
@@ -808,13 +809,13 @@ export class SelectionHighlighter extends Disposable implements IEditorContribut
constructor(editor: ICodeEditor) {
super();
this.editor = editor;
this._isEnabled = editor.getConfiguration().contribInfo.selectionHighlight;
this._isEnabled = editor.getOption(EditorOption.selectionHighlight);
this.decorations = [];
this.updateSoon = this._register(new RunOnceScheduler(() => this._update(), 300));
this.state = null;
this._register(editor.onDidChangeConfiguration((e) => {
this._isEnabled = editor.getConfiguration().contribInfo.selectionHighlight;
this._isEnabled = editor.getOption(EditorOption.selectionHighlight);
}));
this._register(editor.onDidChangeCursorSelection((e: ICursorSelectionChangedEvent) => {
@@ -928,7 +929,7 @@ export class SelectionHighlighter extends Disposable implements IEditorContribut
}
}
return new SelectionHighlighterState(r.searchText, r.matchCase, r.wholeWord ? editor.getConfiguration().wordSeparators : null);
return new SelectionHighlighterState(r.searchText, r.matchCase, r.wholeWord ? editor.getOption(EditorOption.wordSeparators) : null);
}
private _setState(state: SelectionHighlighterState | null): void {
@@ -1053,4 +1054,4 @@ registerEditorAction(MoveSelectionToPreviousFindMatchAction);
registerEditorAction(SelectHighlightsAction);
registerEditorAction(CompatChangeAll);
registerEditorAction(InsertCursorAtEndOfLineSelected);
registerEditorAction(InsertCursorAtTopOfLineSelected);
registerEditorAction(InsertCursorAtTopOfLineSelected);

View File

@@ -60,7 +60,7 @@ suite('Multicursor selection', () => {
let queryState: { [key: string]: any; } = {};
let serviceCollection = new ServiceCollection();
serviceCollection.set(IStorageService, {
_serviceBrand: undefined as any,
_serviceBrand: undefined,
onDidChangeStorage: Event.None,
onWillSaveState: Event.None,
get: (key: string) => queryState[key],
@@ -68,7 +68,8 @@ suite('Multicursor selection', () => {
getNumber: (key: string) => undefined!,
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
remove: (key) => undefined,
logStorage: () => undefined
logStorage: () => undefined,
migrate: (toWorkspace) => Promise.resolve(undefined)
} as IStorageService);
test('issue #8817: Cursor position changes when you cancel multicursor', () => {

View File

@@ -12,6 +12,7 @@ import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursor
import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
import * as modes from 'vs/editor/common/modes';
import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/provideSignatureHelp';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export interface TriggerContext {
readonly triggerKind: modes.SignatureHelpTriggerKind;
@@ -125,7 +126,7 @@ export class ParameterHintsModel extends Disposable {
const length = this.state.hints.signatures.length;
const activeSignature = this.state.hints.activeSignature;
const last = (activeSignature % length) === (length - 1);
const cycle = this.editor.getConfiguration().contribInfo.parameterHints.cycle;
const cycle = this.editor.getOption(EditorOption.parameterHints).cycle;
// If there is only one signature, or we're on last signature of list
if ((length < 2 || last) && !cycle) {
@@ -144,7 +145,7 @@ export class ParameterHintsModel extends Disposable {
const length = this.state.hints.signatures.length;
const activeSignature = this.state.hints.activeSignature;
const first = activeSignature === 0;
const cycle = this.editor.getConfiguration().contribInfo.parameterHints.cycle;
const cycle = this.editor.getOption(EditorOption.parameterHints).cycle;
// If there is only one signature, or we're on first signature of list
if ((length < 2 || first) && !cycle) {
@@ -271,7 +272,7 @@ export class ParameterHintsModel extends Disposable {
}
private onEditorConfigurationChange(): void {
this.triggerOnType = this.editor.getConfiguration().contribInfo.parameterHints.enabled;
this.triggerOnType = this.editor.getOption(EditorOption.parameterHints).enabled;
if (!this.triggerOnType) {
this.cancel();

View File

@@ -11,7 +11,7 @@ import { Event } from 'vs/base/common/event';
import { IDisposable, Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import 'vs/css!./parameterHints';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import * as modes from 'vs/editor/common/modes';
import { IModeService } from 'vs/editor/common/services/modeService';
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
@@ -105,14 +105,14 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget,
}));
const updateFont = () => {
const fontInfo = this.editor.getConfiguration().fontInfo;
const fontInfo = this.editor.getOption(EditorOption.fontInfo);
this.element.style.fontSize = `${fontInfo.fontSize}px`;
};
updateFont();
this._register(Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.fontInfo)
this._register(Event.chain<ConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.hasChanged(EditorOption.fontInfo))
.on(updateFont, null));
this._register(this.editor.onDidLayoutChange(e => this.updateMaxHeight()));
@@ -177,7 +177,7 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget,
const code = dom.append(this.signature, $('.code'));
const hasParameters = signature.parameters.length > 0;
const fontInfo = this.editor.getConfiguration().fontInfo;
const fontInfo = this.editor.getOption(EditorOption.fontInfo);
code.style.fontSize = `${fontInfo.fontSize}px`;
code.style.fontFamily = fontInfo.fontFamily;

View File

@@ -21,16 +21,17 @@ import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/con
import { ServicesAccessor, createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable } from 'vs/base/common/lifecycle';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export const IPeekViewService = createDecorator<IPeekViewService>('IPeekViewService');
export interface IPeekViewService {
_serviceBrand: any;
_serviceBrand: undefined;
addExclusiveWidget(editor: ICodeEditor, widget: PeekViewWidget): void;
}
registerSingleton(IPeekViewService, class implements IPeekViewService {
_serviceBrand: any;
_serviceBrand: undefined;
private _widgets = new Map<ICodeEditor, { widget: PeekViewWidget, listener: IDisposable }>();
@@ -80,7 +81,7 @@ const defaultOptions: IPeekViewOptions = {
export abstract class PeekViewWidget extends ZoneWidget {
public _serviceBrand: any;
public _serviceBrand: undefined;
private _onDidClose = new Emitter<PeekViewWidget>();
@@ -216,8 +217,8 @@ export abstract class PeekViewWidget extends ZoneWidget {
return;
}
const headHeight = Math.ceil(this.editor.getConfiguration().lineHeight * 1.2);
const bodyHeight = heightInPixel - (headHeight + 2 /* the border-top/bottom width*/);
const headHeight = Math.ceil(this.editor.getOption(EditorOption.lineHeight) * 1.2);
const bodyHeight = Math.round(heightInPixel - (headHeight + 2 /* the border-top/bottom width*/));
this._doLayoutHead(headHeight, widthInPixel);
this._doLayoutBody(bodyHeight, widthInPixel);

View File

@@ -74,9 +74,9 @@ export class FilePreview implements IDisposable {
const beforeRange = new Range(startLineNumber, word.startColumn, startLineNumber, startColumn);
const afterRange = new Range(endLineNumber, endColumn, endLineNumber, Number.MAX_VALUE);
const before = model.getValueInRange(beforeRange).replace(/^\s+/, strings.empty);
const before = model.getValueInRange(beforeRange).replace(/^\s+/, '');
const inside = model.getValueInRange(range);
const after = model.getValueInRange(afterRange).replace(/\s+$/, strings.empty);
const after = model.getValueInRange(afterRange).replace(/\s+$/, '');
return {
value: before + inside + after,

View File

@@ -311,8 +311,9 @@ export class ReferenceWidget extends PeekViewWidget {
keyboardNavigationLabelProvider: this._instantiationService.createInstance(StringRepresentationProvider),
identityProvider: new IdentityProvider()
};
this._tree = this._instantiationService.createInstance<HTMLElement, IListVirtualDelegate<TreeElement>, ITreeRenderer<any, FuzzyScore, any>[], IAsyncDataSource<ReferencesModel | FileReferences, TreeElement>, IAsyncDataTreeOptions<TreeElement, FuzzyScore>, WorkbenchAsyncDataTree<ReferencesModel | FileReferences, TreeElement, FuzzyScore>>(
this._tree = this._instantiationService.createInstance<string, HTMLElement, IListVirtualDelegate<TreeElement>, ITreeRenderer<any, FuzzyScore, any>[], IAsyncDataSource<ReferencesModel | FileReferences, TreeElement>, IAsyncDataTreeOptions<TreeElement, FuzzyScore>, WorkbenchAsyncDataTree<ReferencesModel | FileReferences, TreeElement, FuzzyScore>>(
WorkbenchAsyncDataTree,
'ReferencesWidget',
this._treeContainer,
new Delegate(),
[
@@ -382,8 +383,11 @@ export class ReferenceWidget extends PeekViewWidget {
});
this._tree.onDidOpen(e => {
const aside = (e.browserEvent instanceof MouseEvent) && (e.browserEvent.ctrlKey || e.browserEvent.metaKey || e.browserEvent.altKey);
const goto = !e.browserEvent || ((e.browserEvent instanceof MouseEvent) && e.browserEvent.detail === 2);
let goto = !e.browserEvent || ((e.browserEvent instanceof MouseEvent) && e.browserEvent.detail === 2);
if (e.browserEvent instanceof KeyboardEvent) {
// todo@joh make this a command
goto = true;
}
if (aside) {
onEvent(e.elements[0], 'side');
} else if (goto) {

View File

@@ -13,6 +13,7 @@ import { localize } from 'vs/nls';
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { inputBackground, inputBorder, inputForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export const CONTEXT_RENAME_INPUT_VISIBLE = new RawContextKey<boolean>('renameInputVisible', false);
@@ -40,7 +41,7 @@ export class RenameInputField implements IContentWidget, IDisposable {
this._editor.addContentWidget(this);
this._disposables.add(editor.onDidChangeConfiguration(e => {
if (e.fontInfo) {
if (e.hasChanged(EditorOption.fontInfo)) {
this.updateFont();
}
}));
@@ -68,7 +69,7 @@ export class RenameInputField implements IContentWidget, IDisposable {
this._inputField.type = 'text';
this._inputField.setAttribute('aria-label', localize('renameAriaLabel', "Rename input. Type new name and press Enter to commit."));
this._domNode = document.createElement('div');
this._domNode.style.height = `${this._editor.getConfiguration().lineHeight}px`;
this._domNode.style.height = `${this._editor.getOption(EditorOption.lineHeight)}px`;
this._domNode.className = 'monaco-editor rename-box';
this._domNode.appendChild(this._inputField);
@@ -103,7 +104,7 @@ export class RenameInputField implements IContentWidget, IDisposable {
return;
}
const fontInfo = this._editor.getConfiguration().fontInfo;
const fontInfo = this._editor.getOption(EditorOption.fontInfo);
this._inputField.style.fontFamily = fontInfo.fontFamily;
this._inputField.style.fontWeight = fontInfo.fontWeight;
this._inputField.style.fontSize = `${fontInfo.fontSize}px`;

View File

@@ -165,7 +165,10 @@ class GrowSelectionAction extends AbstractSmartSelect {
kbOpts: {
kbExpr: EditorContextKeys.editorTextFocus,
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.RightArrow,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.RightArrow },
mac: {
primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.RightArrow,
secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.RightArrow],
},
weight: KeybindingWeight.EditorContrib
},
menubarOpts: {
@@ -191,7 +194,10 @@ class ShrinkSelectionAction extends AbstractSmartSelect {
kbOpts: {
kbExpr: EditorContextKeys.editorTextFocus,
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.LeftArrow,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.LeftArrow },
mac: {
primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.LeftArrow,
secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.LeftArrow],
},
weight: KeybindingWeight.EditorContrib
},
menubarOpts: {

View File

@@ -22,7 +22,7 @@ import { WordSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/wordSe
class TestTextResourcePropertiesService implements ITextResourcePropertiesService {
_serviceBrand: any;
_serviceBrand: undefined;
constructor(
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -96,21 +96,21 @@ suite('SmartSelect', () => {
'\t}',
'}'
], 3, 20, [
new Range(1, 1, 5, 2), // all
new Range(1, 21, 5, 2), // {} outside
new Range(1, 22, 5, 1), // {} inside
new Range(2, 1, 4, 3), // block
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
new Range(3, 1, 3, 27), // line w/ triva
new Range(3, 3, 3, 27), // line w/o triva
new Range(3, 10, 3, 27), // () outside
new Range(3, 11, 3, 26), // () inside
new Range(3, 17, 3, 26), // () outside
new Range(3, 18, 3, 25), // () inside
]);
new Range(1, 1, 5, 2), // all
new Range(1, 21, 5, 2), // {} outside
new Range(1, 22, 5, 1), // {} inside
new Range(2, 1, 4, 3), // block
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
new Range(3, 1, 3, 27), // line w/ triva
new Range(3, 3, 3, 27), // line w/o triva
new Range(3, 10, 3, 27), // () outside
new Range(3, 11, 3, 26), // () inside
new Range(3, 17, 3, 26), // () outside
new Range(3, 18, 3, 25), // () inside
]);
});
test('getRangesToPosition #56886. Skip empty lines correctly.', () => {
@@ -122,15 +122,15 @@ suite('SmartSelect', () => {
'\t}',
'}'
], 3, 1, [
new Range(1, 1, 5, 2),
new Range(1, 21, 5, 2),
new Range(1, 22, 5, 1),
new Range(2, 1, 4, 3),
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
]);
new Range(1, 1, 5, 2),
new Range(1, 21, 5, 2),
new Range(1, 22, 5, 1),
new Range(2, 1, 4, 3),
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
]);
});
test('getRangesToPosition #56886. Do not skip lines with only whitespaces.', () => {
@@ -142,17 +142,17 @@ suite('SmartSelect', () => {
'\t}',
'}'
], 3, 1, [
new Range(1, 1, 5, 2), // all
new Range(1, 21, 5, 2), // {} outside
new Range(1, 22, 5, 1), // {} inside
new Range(2, 1, 4, 3),
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
new Range(3, 1, 3, 2), // block
new Range(3, 1, 3, 2) // empty line
]);
new Range(1, 1, 5, 2), // all
new Range(1, 21, 5, 2), // {} outside
new Range(1, 22, 5, 1), // {} inside
new Range(2, 1, 4, 3),
new Range(2, 1, 4, 3),
new Range(2, 2, 4, 3),
new Range(2, 11, 4, 3),
new Range(2, 12, 4, 2),
new Range(3, 1, 3, 2), // block
new Range(3, 1, 3, 2) // empty line
]);
});
test('getRangesToPosition #40658. Cursor at first position inside brackets should select line inside.', () => {
@@ -162,11 +162,11 @@ suite('SmartSelect', () => {
' { } ',
'( ) '
], 2, 3, [
new Range(1, 1, 3, 5),
new Range(2, 1, 2, 6), // line w/ triava
new Range(2, 2, 2, 5), // {} inside, line w/o triva
new Range(2, 3, 2, 4) // {} inside
]);
new Range(1, 1, 3, 5),
new Range(2, 1, 2, 6), // line w/ triava
new Range(2, 2, 2, 5), // {} inside, line w/o triva
new Range(2, 3, 2, 4) // {} inside
]);
});
test('getRangesToPosition #40658. Cursor in empty brackets should reveal brackets first.', () => {
@@ -176,11 +176,11 @@ suite('SmartSelect', () => {
' { } ',
' ( ) '
], 1, 3, [
new Range(1, 1, 3, 7), // all
new Range(1, 1, 1, 5), // line w/ trival
new Range(1, 2, 1, 4), // [] outside, line w/o trival
new Range(1, 3, 1, 3), // [] inside
]);
new Range(1, 1, 3, 7), // all
new Range(1, 1, 1, 5), // line w/ trival
new Range(1, 2, 1, 4), // [] outside, line w/o trival
new Range(1, 3, 1, 3), // [] inside
]);
});
test('getRangesToPosition #40658. Tokens before bracket will be revealed first.', () => {
@@ -190,11 +190,11 @@ suite('SmartSelect', () => {
' { } ',
'selectthis( ) '
], 3, 11, [
new Range(1, 1, 3, 15), // all
new Range(3, 1, 3, 15), // line w/ trivia
new Range(3, 1, 3, 14), // line w/o trivia
new Range(3, 1, 3, 11) // word
]);
new Range(1, 1, 3, 15), // all
new Range(3, 1, 3, 15), // line w/ trivia
new Range(3, 1, 3, 14), // line w/o trivia
new Range(3, 1, 3, 11) // word
]);
});
// -- bracket selections

View File

@@ -23,6 +23,7 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic
import * as colors from 'vs/platform/theme/common/colorRegistry';
import { withNullAsUndefined } from 'vs/base/common/types';
import { ILabelService } from 'vs/platform/label/common/label';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
registerThemingParticipant((theme, collector) => {
@@ -444,7 +445,7 @@ export class SnippetSession {
snippet.resolveVariables(new CompositeSnippetVariableResolver([
modelBasedVariableResolver,
new ClipboardBasedVariableResolver(clipboardText, idx, indexedSelections.length),
new ClipboardBasedVariableResolver(clipboardText, idx, indexedSelections.length, editor.getOption(EditorOption.multiCursorPaste) === 'spread'),
new SelectionBasedVariableResolver(model, selection),
new CommentBasedVariableResolver(model),
new TimeBasedVariableResolver,

View File

@@ -169,7 +169,8 @@ export class ClipboardBasedVariableResolver implements VariableResolver {
constructor(
private readonly _clipboardText: string | undefined,
private readonly _selectionIdx: number,
private readonly _selectionCount: number
private readonly _selectionCount: number,
private readonly _spread: boolean
) {
//
}
@@ -183,12 +184,16 @@ export class ClipboardBasedVariableResolver implements VariableResolver {
return undefined;
}
const lines = this._clipboardText.split(/\r\n|\n|\r/).filter(s => !isFalsyOrWhitespace(s));
if (lines.length === this._selectionCount) {
return lines[this._selectionIdx];
} else {
return this._clipboardText;
// `spread` is assigning each cursor a line of the clipboard
// text whenever there the line count equals the cursor count
// and when enabled
if (this._spread) {
const lines = this._clipboardText.split(/\r\n|\n|\r/).filter(s => !isFalsyOrWhitespace(s));
if (lines.length === this._selectionCount) {
return lines[this._selectionIdx];
}
}
return this._clipboardText;
}
}
export class CommentBasedVariableResolver implements VariableResolver {

View File

@@ -236,26 +236,28 @@ suite('Snippet Variables Resolver', function () {
test('Add variable to insert value from clipboard to a snippet #40153', function () {
assertVariableResolve(new ClipboardBasedVariableResolver(undefined, 1, 0), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver(undefined, 1, 0, true), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver(null!, 1, 0), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver(null!, 1, 0, true), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('', 1, 0), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('', 1, 0, true), 'CLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'CLIPBOARD', 'foo');
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0, true), 'CLIPBOARD', 'foo');
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'foo', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'cLIPBOARD', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0, true), 'foo', undefined);
assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0, true), 'cLIPBOARD', undefined);
});
test('Add variable to insert value from clipboard to a snippet #40153', function () {
assertVariableResolve(new ClipboardBasedVariableResolver('line1', 1, 2), 'CLIPBOARD', 'line1');
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2\nline3', 1, 2), 'CLIPBOARD', 'line1\nline2\nline3');
assertVariableResolve(new ClipboardBasedVariableResolver('line1', 1, 2, true), 'CLIPBOARD', 'line1');
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2\nline3', 1, 2, true), 'CLIPBOARD', 'line1\nline2\nline3');
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 1, 2), 'CLIPBOARD', 'line2');
resolver = new ClipboardBasedVariableResolver('line1\nline2', 0, 2);
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 0, 2), 'CLIPBOARD', 'line1');
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 1, 2, true), 'CLIPBOARD', 'line2');
resolver = new ClipboardBasedVariableResolver('line1\nline2', 0, 2, true);
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 0, 2, true), 'CLIPBOARD', 'line1');
assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 0, 2, false), 'CLIPBOARD', 'line1\nline2');
});
@@ -299,7 +301,7 @@ suite('Snippet Variables Resolver', function () {
let workspace: IWorkspace;
let resolver: VariableResolver;
const workspaceService = new class implements IWorkspaceContextService {
_serviceBrand: any;
_serviceBrand: undefined;
_throw = () => { throw new Error(); };
onDidChangeWorkbenchState = this._throw;
onDidChangeWorkspaceName = this._throw;

View File

@@ -6,7 +6,7 @@
import { fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScorer, FuzzyScore, anyScore } from 'vs/base/common/filters';
import { CompletionItemProvider, CompletionItemKind } from 'vs/editor/common/modes';
import { CompletionItem } from './suggest';
import { InternalSuggestOptions, EDITOR_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { InternalSuggestOptions } from 'vs/editor/common/config/editorOptions';
import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance';
import { CharCode } from 'vs/base/common/charCode';
import { compareIgnoreCase } from 'vs/base/common/strings';
@@ -60,7 +60,8 @@ export class CompletionModel {
column: number,
lineContext: LineContext,
wordDistance: WordDistance,
options: InternalSuggestOptions = EDITOR_DEFAULTS.contribInfo.suggest
options: InternalSuggestOptions,
snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none'
) {
this._items = items;
this._column = column;
@@ -69,9 +70,9 @@ export class CompletionModel {
this._refilterKind = Refilter.All;
this._lineContext = lineContext;
if (options.snippets === 'top') {
if (snippetSuggestions === 'top') {
this._snippetCompareFn = CompletionModel._compareCompletionItemsSnippetsUp;
} else if (options.snippets === 'bottom') {
} else if (snippetSuggestions === 'bottom') {
this._snippetCompareFn = CompletionModel._compareCompletionItemsSnippetsDown;
}
}

View File

@@ -45,6 +45,13 @@
float: right;
}
/* MarkupContent Layout */
.monaco-editor .suggest-widget > .details ul {
padding-left: 20px;
}
.monaco-editor .suggest-widget > .details ol {
padding-left: 20px;
}
/* Styles for Message element for when widget is loading or is empty */
.monaco-editor .suggest-widget > .message {
@@ -158,6 +165,7 @@
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated {
opacity: 0.66;
text-decoration: unset;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-description-container {
text-decoration: line-through;

View File

@@ -161,6 +161,10 @@ export function provideSuggestionItems(
if (!suggestion.range) {
suggestion.range = defaultRange;
}
// fill in default sortText when missing
if (!suggestion.sortText) {
suggestion.sortText = suggestion.label;
}
allSuggestions.push(new CompletionItem(position, suggestion, container, provider, model));
}
@@ -278,7 +282,7 @@ registerDefaultLanguageCommand('_executeCompletionItemProvider', async (model, p
await Promise.all(resolving);
return result;
} finally {
setTimeout(() => disposables.dispose(), 0);
setTimeout(() => disposables.dispose(), 100);
}
});

View File

@@ -8,6 +8,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { ISelectedSuggestion, SuggestWidget } from './suggestWidget';
import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class CommitCharacterController {
@@ -27,7 +28,7 @@ export class CommitCharacterController {
this._disposables.add(editor.onWillType(text => {
if (this._active) {
const ch = text.charCodeAt(text.length - 1);
if (this._active.acceptCharacters.has(ch) && editor.getConfiguration().contribInfo.acceptSuggestionOnCommitCharacter) {
if (this._active.acceptCharacters.has(ch) && editor.getOption(EditorOption.acceptSuggestionOnCommitCharacter)) {
accept(this._active.item);
}
}

View File

@@ -35,6 +35,7 @@ import { isObject } from 'vs/base/common/types';
import { CommitCharacterController } from './suggestCommitCharacters';
import { IPosition } from 'vs/editor/common/core/position';
import { TrackedRangeStickiness, ITextModel } from 'vs/editor/common/model';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
const _sticky = false; // for development purposes only
@@ -58,15 +59,19 @@ class LineSuffix {
}
dispose(): void {
if (this._marker) {
if (this._marker && !this._model.isDisposed()) {
this._model.deltaDecorations(this._marker, []);
}
}
delta(position: IPosition): number {
if (this._position.lineNumber !== position.lineNumber) {
if (this._model.isDisposed() || this._position.lineNumber !== position.lineNumber) {
// bail out early if things seems fishy
return 0;
} else if (this._marker) {
}
// read the marker (in case suggest was triggered at line end) or compare
// the cursor to the line end.
if (this._marker) {
const range = this._model.getDecorationRange(this._marker[0]);
const end = this._model.getOffsetAt(range!.getStartPosition());
return end - this._model.getOffsetAt(position);
@@ -125,7 +130,7 @@ export class SuggestController implements IEditorContribution {
const endColumn = position.column;
let value = true;
if (
this._editor.getConfiguration().contribInfo.acceptSuggestionOnEnter === 'smart'
this._editor.getOption(EditorOption.acceptSuggestionOnEnter) === 'smart'
&& this._model.state === State.Auto
&& !item.completion.command
&& !item.completion.additionalTextEdits
@@ -178,7 +183,7 @@ export class SuggestController implements IEditorContribution {
// Manage the acceptSuggestionsOnEnter context key
let acceptSuggestionsOnEnter = SuggestContext.AcceptSuggestionsOnEnter.bindTo(_contextKeyService);
let updateFromConfig = () => {
const { acceptSuggestionOnEnter } = this._editor.getConfiguration().contribInfo;
const acceptSuggestionOnEnter = this._editor.getOption(EditorOption.acceptSuggestionOnEnter);
acceptSuggestionsOnEnter.set(acceptSuggestionOnEnter === 'on' || acceptSuggestionOnEnter === 'smart');
};
this._toDispose.add(this._editor.onDidChangeConfiguration(() => updateFromConfig()));

View File

@@ -208,7 +208,7 @@ export type MemMode = 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix';
export class SuggestMemoryService extends Disposable implements ISuggestMemoryService {
readonly _serviceBrand: any;
readonly _serviceBrand: undefined;
private readonly _storagePrefix = 'suggest/memories';
@@ -292,7 +292,7 @@ export class SuggestMemoryService extends Disposable implements ISuggestMemorySe
export const ISuggestMemoryService = createDecorator<ISuggestMemoryService>('ISuggestMemories');
export interface ISuggestMemoryService {
_serviceBrand: any;
_serviceBrand: undefined;
memorize(model: ITextModel, pos: IPosition, item: CompletionItem): void;
select(model: ITextModel, pos: IPosition, items: CompletionItem[]): number;
}

View File

@@ -20,6 +20,7 @@ import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export interface ICancelEvent {
readonly retrigger: boolean;
@@ -172,7 +173,7 @@ export class SuggestModel implements IDisposable {
// --- handle configuration & precondition changes
private _updateQuickSuggest(): void {
this._quickSuggestDelay = this._editor.getConfiguration().contribInfo.quickSuggestionsDelay;
this._quickSuggestDelay = this._editor.getOption(EditorOption.quickSuggestionsDelay);
if (isNaN(this._quickSuggestDelay) || (!this._quickSuggestDelay && this._quickSuggestDelay !== 0) || this._quickSuggestDelay < 0) {
this._quickSuggestDelay = 10;
@@ -183,9 +184,9 @@ export class SuggestModel implements IDisposable {
dispose(this._triggerCharacterListener);
if (this._editor.getConfiguration().readOnly
if (this._editor.getOption(EditorOption.readOnly)
|| !this._editor.hasModel()
|| !this._editor.getConfiguration().contribInfo.suggestOnTriggerCharacters) {
|| !this._editor.getOption(EditorOption.suggestOnTriggerCharacters)) {
return;
}
@@ -277,7 +278,7 @@ export class SuggestModel implements IDisposable {
if (this._state === State.Idle) {
if (this._editor.getConfiguration().contribInfo.quickSuggestions === false) {
if (this._editor.getOption(EditorOption.quickSuggestions) === false) {
// not enabled
return;
}
@@ -287,7 +288,7 @@ export class SuggestModel implements IDisposable {
return;
}
if (this._editor.getConfiguration().contribInfo.suggest.snippetsPreventQuickSuggestions && SnippetController2.get(this._editor).isInSnippet()) {
if (this._editor.getOption(EditorOption.suggest).snippetsPreventQuickSuggestions && SnippetController2.get(this._editor).isInSnippet()) {
// no quick suggestion when in snippet mode
return;
}
@@ -307,7 +308,7 @@ export class SuggestModel implements IDisposable {
const model = this._editor.getModel();
const pos = this._editor.getPosition();
// validate enabled now
const { quickSuggestions } = this._editor.getConfiguration().contribInfo;
const quickSuggestions = this._editor.getOption(EditorOption.quickSuggestions);
if (quickSuggestions === false) {
return;
} else if (quickSuggestions === true) {
@@ -387,10 +388,11 @@ export class SuggestModel implements IDisposable {
this._requestToken = new CancellationTokenSource();
// kind filter and snippet sort rules
const { contribInfo } = this._editor.getConfiguration();
const suggestOptions = this._editor.getOption(EditorOption.suggest);
const snippetSuggestions = this._editor.getOption(EditorOption.snippetSuggestions);
let itemKindFilter = new Set<CompletionItemKind>();
let snippetSortOrder = SnippetSortOrder.Inline;
switch (contribInfo.suggest.snippets) {
switch (snippetSuggestions) {
case 'top':
snippetSortOrder = SnippetSortOrder.Top;
break;
@@ -407,9 +409,9 @@ export class SuggestModel implements IDisposable {
}
// kind filter
for (const key in contribInfo.suggest.filteredTypes) {
for (const key in suggestOptions.filteredTypes) {
const kind = completionKindFromString(key, true);
if (typeof kind !== 'undefined' && contribInfo.suggest.filteredTypes[key] === false) {
if (typeof kind !== 'undefined' && suggestOptions.filteredTypes[key] === false) {
itemKindFilter.add(kind);
}
}
@@ -449,7 +451,8 @@ export class SuggestModel implements IDisposable {
characterCountDelta: ctx.column - this._context!.column
},
wordDistance,
this._editor.getConfiguration().contribInfo.suggest
this._editor.getOption(EditorOption.suggest),
this._editor.getOption(EditorOption.snippetSuggestions)
);
// store containers so that they can be disposed later

View File

@@ -16,7 +16,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { Context as SuggestContext, CompletionItem } from './suggest';
import { CompletionModel } from './completionModel';
@@ -124,11 +124,12 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
data.readMore.title = nls.localize('readMore', "Read More...{0}", this.triggerKeybindingLabel);
const configureFont = () => {
const configuration = this.editor.getConfiguration();
const fontFamily = configuration.fontInfo.fontFamily;
const fontSize = configuration.contribInfo.suggestFontSize || configuration.fontInfo.fontSize;
const lineHeight = configuration.contribInfo.suggestLineHeight || configuration.fontInfo.lineHeight;
const fontWeight = configuration.fontInfo.fontWeight;
const options = this.editor.getOptions();
const fontInfo = options.get(EditorOption.fontInfo);
const fontFamily = fontInfo.fontFamily;
const fontSize = options.get(EditorOption.suggestFontSize) || fontInfo.fontSize;
const lineHeight = options.get(EditorOption.suggestLineHeight) || fontInfo.lineHeight;
const fontWeight = fontInfo.fontWeight;
const fontSizePx = `${fontSize}px`;
const lineHeightPx = `${lineHeight}px`;
@@ -144,8 +145,8 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
configureFont();
data.disposables.add(Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.fontInfo || e.contribInfo)
data.disposables.add(Event.chain<ConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.hasChanged(EditorOption.fontInfo) || e.hasChanged(EditorOption.suggestFontSize) || e.hasChanged(EditorOption.suggestLineHeight))
.on(configureFont, null));
return data;
@@ -276,8 +277,8 @@ class SuggestionDetails {
this.configureFont();
Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.fontInfo)
Event.chain<ConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.hasChanged(EditorOption.fontInfo))
.on(this.configureFont, this, this.disposables);
markdownRenderer.onDidRenderCodeBlock(() => this.scrollbar.scanDomNode(), this, this.disposables);
@@ -389,11 +390,12 @@ class SuggestionDetails {
}
private configureFont() {
const configuration = this.editor.getConfiguration();
const fontFamily = configuration.fontInfo.fontFamily;
const fontSize = configuration.contribInfo.suggestFontSize || configuration.fontInfo.fontSize;
const lineHeight = configuration.contribInfo.suggestLineHeight || configuration.fontInfo.lineHeight;
const fontWeight = configuration.fontInfo.fontWeight;
const options = this.editor.getOptions();
const fontInfo = options.get(EditorOption.fontInfo);
const fontFamily = fontInfo.fontFamily;
const fontSize = options.get(EditorOption.suggestFontSize) || fontInfo.fontSize;
const lineHeight = options.get(EditorOption.suggestLineHeight) || fontInfo.lineHeight;
const fontWeight = fontInfo.fontWeight;
const fontSizePx = `${fontSize}px`;
const lineHeightPx = `${lineHeight}px`;
@@ -500,12 +502,12 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.listElement = append(this.element, $('.tree'));
this.details = instantiationService.createInstance(SuggestionDetails, this.element, this, this.editor, markdownRenderer, triggerKeybindingLabel);
const applyIconStyle = () => toggleClass(this.element, 'no-icons', !this.editor.getConfiguration().contribInfo.suggest.showIcons);
const applyIconStyle = () => toggleClass(this.element, 'no-icons', !this.editor.getOption(EditorOption.suggest).showIcons);
applyIconStyle();
let renderer = instantiationService.createInstance(Renderer, this, this.editor, triggerKeybindingLabel);
this.list = new List(this.listElement, this, [renderer], {
this.list = new List('SuggestWidget', this.listElement, this, [renderer], {
useShadows: false,
openController: { shouldOpen: () => false },
mouseSupport: false
@@ -521,7 +523,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.toDispose.add(this.list.onSelectionChange(e => this.onListSelection(e)));
this.toDispose.add(this.list.onFocusChange(e => this.onListFocus(e)));
this.toDispose.add(this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged()));
this.toDispose.add(this.editor.onDidChangeConfiguration(e => e.contribInfo && applyIconStyle()));
this.toDispose.add(this.editor.onDidChangeConfiguration(e => e.hasChanged(EditorOption.suggest) && applyIconStyle()));
this.suggestWidgetVisible = SuggestContext.Visible.bindTo(contextKeyService);
@@ -1051,7 +1053,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
height = this.unfocusedHeight;
} else {
const suggestionCount = this.list.contentHeight / this.unfocusedHeight;
const { maxVisibleSuggestions } = this.editor.getConfiguration().contribInfo.suggest;
const { maxVisibleSuggestions } = this.editor.getOption(EditorOption.suggest);
height = Math.min(suggestionCount, maxVisibleSuggestions) * this.unfocusedHeight;
}
@@ -1069,7 +1071,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
return;
}
const lineHeight = this.editor.getConfiguration().fontInfo.lineHeight;
const lineHeight = this.editor.getOption(EditorOption.lineHeight);
const cursorCoords = this.editor.getScrolledVisiblePosition(this.editor.getPosition());
const editorCoords = getDomNodePagePosition(this.editor.getDomNode());
const cursorX = editorCoords.left + cursorCoords.left;
@@ -1132,12 +1134,12 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
// Heights
private get maxWidgetHeight(): number {
return this.unfocusedHeight * this.editor.getConfiguration().contribInfo.suggest.maxVisibleSuggestions;
return this.unfocusedHeight * this.editor.getOption(EditorOption.suggest).maxVisibleSuggestions;
}
private get unfocusedHeight(): number {
const configuration = this.editor.getConfiguration();
return configuration.contribInfo.suggestLineHeight || configuration.fontInfo.lineHeight;
const options = this.editor.getOptions();
return options.get(EditorOption.suggestLineHeight) || options.get(EditorOption.fontInfo).lineHeight;
}
// IDelegate

View File

@@ -8,6 +8,7 @@ import * as modes from 'vs/editor/common/modes';
import { CompletionModel } from 'vs/editor/contrib/suggest/completionModel';
import { CompletionItem, getSuggestionComparator, SnippetSortOrder } from 'vs/editor/contrib/suggest/suggest';
import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance';
import { EditorOptions } from 'vs/editor/common/config/editorOptions';
export function createSuggestItem(label: string, overwriteBefore: number, kind = modes.CompletionItemKind.Property, incomplete: boolean = false, position: IPosition = { lineNumber: 1, column: 1 }, sortText?: string, filterText?: string): CompletionItem {
const suggestion: modes.CompletionItem = {
@@ -42,9 +43,9 @@ suite('CompletionModel', function () {
createSuggestItem('Foo', 3),
createSuggestItem('foo', 2),
], 1, {
leadingLineContent: 'foo',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: 'foo',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
});
test('filtering - cached', function () {
@@ -73,9 +74,9 @@ suite('CompletionModel', function () {
createSuggestItem('foo', 3, undefined, true),
createSuggestItem('foo', 2),
], 1, {
leadingLineContent: 'foo',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: 'foo',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(incompleteModel.incomplete.size, 1);
});
@@ -84,7 +85,7 @@ suite('CompletionModel', function () {
const completeItem = createSuggestItem('foobar', 1, undefined, false, { lineNumber: 1, column: 2 });
const incompleteItem = createSuggestItem('foofoo', 1, undefined, true, { lineNumber: 1, column: 2 });
const model = new CompletionModel([completeItem, incompleteItem], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None);
const model = new CompletionModel([completeItem, incompleteItem], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(model.incomplete.size, 1);
assert.equal(model.items.length, 2);
@@ -113,7 +114,7 @@ suite('CompletionModel', function () {
completeItem4,
completeItem5,
incompleteItem1,
], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None
], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue
);
assert.equal(model.incomplete.size, 1);
assert.equal(model.items.length, 6);
@@ -135,9 +136,9 @@ suite('CompletionModel', function () {
createSuggestItem(' </tag', 4),
createSuggestItem(' XYZ', 4),
], 1, {
leadingLineContent: ' <',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: ' <',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(model.items.length, 4);
@@ -155,18 +156,17 @@ suite('CompletionModel', function () {
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
createSuggestItem('semver', 1, modes.CompletionItemKind.Property),
], 1, {
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippets: 'top',
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
});
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
}, 'top');
assert.equal(model.items.length, 2);
const [a, b] = model.items;
@@ -183,18 +183,17 @@ suite('CompletionModel', function () {
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
createSuggestItem('Semver', 1, modes.CompletionItemKind.Property),
], 1, {
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippets: 'bottom',
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
});
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
}, 'bottom');
assert.equal(model.items.length, 2);
const [a, b] = model.items;
@@ -210,18 +209,17 @@ suite('CompletionModel', function () {
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
createSuggestItem('Semver', 1),
], 1, {
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippets: 'inline',
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
});
leadingLineContent: 's',
characterCountDelta: 0
}, WordDistance.None, {
snippetsPreventQuickSuggestions: true,
filterGraceful: true,
localityBonus: false,
shareSuggestSelections: false,
showIcons: true,
maxVisibleSuggestions: 12,
filteredTypes: Object.create(null)
}, 'inline');
assert.equal(model.items.length, 2);
const [a, b] = model.items;
@@ -238,7 +236,7 @@ suite('CompletionModel', function () {
model = new CompletionModel([item1, item2], 1, {
leadingLineContent: 'M',
characterCountDelta: 0
}, WordDistance.None);
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(model.items.length, 2);
@@ -258,7 +256,7 @@ suite('CompletionModel', function () {
model = new CompletionModel(items, 3, {
leadingLineContent: ' ',
characterCountDelta: 0
}, WordDistance.None);
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(model.items.length, 2);
@@ -275,9 +273,9 @@ suite('CompletionModel', function () {
createSuggestItem('car', 0),
createSuggestItem('foo', 0),
], 1, {
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
assert.equal(model.items.length, 5);
@@ -302,9 +300,9 @@ suite('CompletionModel', function () {
createSuggestItem('car', 0),
createSuggestItem('foo', 0),
], 1, {
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
// query gets longer, narrow down the narrow-down'ed-set from before
model.lineContext = { leadingLineContent: 'rlut', characterCountDelta: 4 };
@@ -324,9 +322,9 @@ suite('CompletionModel', function () {
createSuggestItem('testForeignMeasure', 0),
createSuggestItem('fooRoom', 0),
], 1, {
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None);
leadingLineContent: '',
characterCountDelta: 0
}, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue);
model.lineContext = { leadingLineContent: 'form', characterCountDelta: 4 };
assert.equal(model.items.length, 5);

View File

@@ -47,7 +47,7 @@ function createMockEditor(model: TextModel): TestCodeEditor {
[ITelemetryService, NullTelemetryService],
[IStorageService, new InMemoryStorageService()],
[ISuggestMemoryService, new class implements ISuggestMemoryService {
_serviceBrand: any;
_serviceBrand: undefined;
memorize(): void {
}
select(): number {

View File

@@ -6,6 +6,7 @@
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export class WordContextKey extends Disposable {
@@ -22,7 +23,7 @@ export class WordContextKey extends Disposable {
) {
super();
this._ckAtEnd = WordContextKey.AtEnd.bindTo(contextKeyService);
this._register(this._editor.onDidChangeConfiguration(e => e.contribInfo && this._update()));
this._register(this._editor.onDidChangeConfiguration(e => e.hasChanged(EditorOption.tabCompletion) && this._update()));
this._update();
}
@@ -34,7 +35,7 @@ export class WordContextKey extends Disposable {
private _update(): void {
// only update this when tab completions are enabled
const enabled = this._editor.getConfiguration().contribInfo.tabCompletion === 'on';
const enabled = this._editor.getOption(EditorOption.tabCompletion) === 'on';
if (this._enabled === enabled) {
return;
}

View File

@@ -10,6 +10,7 @@ import { IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { CompletionItem, CompletionItemKind } from 'vs/editor/common/modes';
import { BracketSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/bracketSelections';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export abstract class WordDistance {
@@ -17,55 +18,53 @@ export abstract class WordDistance {
distance() { return 0; }
};
static create(service: IEditorWorkerService, editor: ICodeEditor): Promise<WordDistance> {
static async create(service: IEditorWorkerService, editor: ICodeEditor): Promise<WordDistance> {
if (!editor.getConfiguration().contribInfo.suggest.localityBonus) {
return Promise.resolve(WordDistance.None);
if (!editor.getOption(EditorOption.suggest).localityBonus) {
return WordDistance.None;
}
if (!editor.hasModel()) {
return Promise.resolve(WordDistance.None);
return WordDistance.None;
}
const model = editor.getModel();
const position = editor.getPosition();
if (!service.canComputeWordRanges(model.uri)) {
return Promise.resolve(WordDistance.None);
return WordDistance.None;
}
return new BracketSelectionRangeProvider().provideSelectionRanges(model, [position]).then(ranges => {
if (!ranges || ranges.length === 0 || ranges[0].length === 0) {
return WordDistance.None;
}
return service.computeWordRanges(model.uri, ranges[0][0].range).then(wordRanges => {
return new class extends WordDistance {
distance(anchor: IPosition, suggestion: CompletionItem) {
if (!wordRanges || !position.equals(editor.getPosition())) {
return 0;
}
if (suggestion.kind === CompletionItemKind.Keyword) {
return 2 << 20;
}
let word = suggestion.label;
let wordLines = wordRanges[word];
if (isFalsyOrEmpty(wordLines)) {
return 2 << 20;
}
let idx = binarySearch(wordLines, Range.fromPositions(anchor), Range.compareRangesUsingStarts);
let bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
let blockDistance = ranges.length;
for (const range of ranges[0]) {
if (!Range.containsRange(range.range, bestWordRange)) {
break;
}
blockDistance -= 1;
}
return blockDistance;
const ranges = await new BracketSelectionRangeProvider().provideSelectionRanges(model, [position]);
if (!ranges || ranges.length === 0 || ranges[0].length === 0) {
return WordDistance.None;
}
const wordRanges = await service.computeWordRanges(model.uri, ranges[0][0].range);
return new class extends WordDistance {
distance(anchor: IPosition, suggestion: CompletionItem) {
if (!wordRanges || !position.equals(editor.getPosition())) {
return 0;
}
if (suggestion.kind === CompletionItemKind.Keyword) {
return 2 << 20;
}
let word = suggestion.label;
let wordLines = wordRanges[word];
if (isFalsyOrEmpty(wordLines)) {
return 2 << 20;
}
let idx = binarySearch(wordLines, Range.fromPositions(anchor), Range.compareRangesUsingStarts);
let bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
let blockDistance = ranges.length;
for (const range of ranges[0]) {
if (!Range.containsRange(range.range, bestWordRange)) {
break;
}
};
});
});
blockDistance -= 1;
}
return blockDistance;
}
};
}
abstract distance(anchor: IPosition, suggestion: CompletionItem): number;

View File

@@ -26,16 +26,15 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { activeContrastBorder, editorSelectionHighlight, editorSelectionHighlightBorder, overviewRulerSelectionHighlightForeground, registerColor } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant, themeColorFromId } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export const editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable. The color must not be opaque so as not to hide underlying decorations.'), true);
export const editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable. The color must not be opaque so as not to hide underlying decorations.'), true);
export const editorWordHighlightBorder = registerColor('editor.wordHighlightBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightBorder', 'Border color of a symbol during read-access, like reading a variable.'));
export const editorWordHighlightStrongBorder = registerColor('editor.wordHighlightStrongBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightStrongBorder', 'Border color of a symbol during write-access, like writing to a variable.'));
export const overviewRulerWordHighlightForeground = registerColor('editorOverviewRuler.wordHighlightForeground', { dark: '#A0A0A0CC', light: '#A0A0A0CC', hc: '#A0A0A0CC' }, nls.localize('overviewRulerWordHighlightForeground', 'Overview ruler marker color for symbol highlights. The color must not be opaque so as not to hide underlying decorations.'), true);
export const overviewRulerWordHighlightStrongForeground = registerColor('editorOverviewRuler.wordHighlightStrongForeground', { dark: '#C0A0C0CC', light: '#C0A0C0CC', hc: '#C0A0C0CC' }, nls.localize('overviewRulerWordHighlightStrongForeground', 'Overview ruler marker color for write-access symbol highlights. The color must not be opaque so as not to hide underlying decorations.'), true);
export const ctxHasWordHighlights = new RawContextKey<boolean>('hasWordHighlights', false);
const editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable. The color must not be opaque so as not to hide underlying decorations.'), true);
const editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable. The color must not be opaque so as not to hide underlying decorations.'), true);
const editorWordHighlightBorder = registerColor('editor.wordHighlightBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightBorder', 'Border color of a symbol during read-access, like reading a variable.'));
const editorWordHighlightStrongBorder = registerColor('editor.wordHighlightStrongBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightStrongBorder', 'Border color of a symbol during write-access, like writing to a variable.'));
const overviewRulerWordHighlightForeground = registerColor('editorOverviewRuler.wordHighlightForeground', { dark: '#A0A0A0CC', light: '#A0A0A0CC', hc: '#A0A0A0CC' }, nls.localize('overviewRulerWordHighlightForeground', 'Overview ruler marker color for symbol highlights. The color must not be opaque so as not to hide underlying decorations.'), true);
const overviewRulerWordHighlightStrongForeground = registerColor('editorOverviewRuler.wordHighlightStrongForeground', { dark: '#C0A0C0CC', light: '#C0A0C0CC', hc: '#C0A0C0CC' }, nls.localize('overviewRulerWordHighlightStrongForeground', 'Overview ruler marker color for write-access symbol highlights. The color must not be opaque so as not to hide underlying decorations.'), true);
const ctxHasWordHighlights = new RawContextKey<boolean>('hasWordHighlights', false);
export function getOccurrencesAtPosition(model: ITextModel, position: Position, token: CancellationToken): Promise<DocumentHighlight[] | null | undefined> {
@@ -181,7 +180,7 @@ class WordHighlighter {
this.editor = editor;
this._hasWordHighlights = ctxHasWordHighlights.bindTo(contextKeyService);
this._ignorePositionChangeEvent = false;
this.occurrencesHighlight = this.editor.getConfiguration().contribInfo.occurrencesHighlight;
this.occurrencesHighlight = this.editor.getOption(EditorOption.occurrencesHighlight);
this.model = this.editor.getModel();
this.toUnhook.add(editor.onDidChangeCursorPosition((e: ICursorPositionChangedEvent) => {
@@ -202,7 +201,7 @@ class WordHighlighter {
this._stopAll();
}));
this.toUnhook.add(editor.onDidChangeConfiguration((e) => {
let newValue = this.editor.getConfiguration().contribInfo.occurrencesHighlight;
let newValue = this.editor.getOption(EditorOption.occurrencesHighlight);
if (this.occurrencesHighlight !== newValue) {
this.occurrencesHighlight = newValue;
this._stopAll();
@@ -371,7 +370,7 @@ class WordHighlighter {
let myRequestId = ++this.workerRequestTokenId;
this.workerRequestCompleted = false;
this.workerRequest = computeOccurencesAtPosition(this.model, this.editor.getSelection(), this.editor.getConfiguration().wordSeparators);
this.workerRequest = computeOccurencesAtPosition(this.model, this.editor.getSelection(), this.editor.getOption(EditorOption.wordSeparators));
this.workerRequest.result.then(data => {
if (myRequestId === this.workerRequestTokenId) {

View File

@@ -20,7 +20,7 @@ import { ITextModel } from 'vs/editor/common/model';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { EDITOR_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { EditorOption, EditorOptions } from 'vs/editor/common/config/editorOptions';
export interface MoveWordOptions extends ICommandOptions {
inSelectionMode: boolean;
@@ -42,8 +42,7 @@ export abstract class MoveWordCommand extends EditorCommand {
if (!editor.hasModel()) {
return;
}
const config = editor.getConfiguration();
const wordSeparators = getMapForWordSeparators(config.wordSeparators);
const wordSeparators = getMapForWordSeparators(editor.getOption(EditorOption.wordSeparators));
const model = editor.getModel();
const selections = editor.getSelections();
@@ -190,7 +189,7 @@ export class CursorWordAccessibilityLeft extends WordLeftCommand {
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType);
}
}
@@ -199,7 +198,7 @@ export class CursorWordAccessibilityLeftSelect extends WordLeftCommand {
super({
inSelectionMode: true,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilitLeftSelecty',
id: 'cursorWordAccessibilityLeftSelect',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
@@ -211,7 +210,7 @@ export class CursorWordAccessibilityLeftSelect extends WordLeftCommand {
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType);
}
}
@@ -310,7 +309,7 @@ export class CursorWordAccessibilityRight extends WordRightCommand {
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType);
}
}
@@ -331,7 +330,7 @@ export class CursorWordAccessibilityRightSelect extends WordRightCommand {
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType);
}
}
@@ -354,8 +353,7 @@ export abstract class DeleteWordCommand extends EditorCommand {
if (!editor.hasModel()) {
return;
}
const config = editor.getConfiguration();
const wordSeparators = getMapForWordSeparators(config.wordSeparators);
const wordSeparators = getMapForWordSeparators(editor.getOption(EditorOption.wordSeparators));
const model = editor.getModel();
const selections = editor.getSelections();

View File

@@ -11,7 +11,7 @@ import { IdGenerator } from 'vs/base/common/idGenerator';
import { DisposableStore } from 'vs/base/common/lifecycle';
import * as objects from 'vs/base/common/objects';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, IViewZoneChangeAccessor } from 'vs/editor/browser/editorBrowser';
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange, Range } from 'vs/editor/common/core/range';
import { ScrollType } from 'vs/editor/common/editorCommon';
@@ -334,7 +334,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
}
private _decoratingElementsHeight(): number {
let lineHeight = this.editor.getConfiguration().lineHeight;
let lineHeight = this.editor.getOption(EditorOption.lineHeight);
let result = 0;
if (this.options.showArrow) {
@@ -364,7 +364,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
// Render the widget as zone (rendering) and widget (lifecycle)
const viewZoneDomNode = document.createElement('div');
viewZoneDomNode.style.overflow = 'hidden';
const lineHeight = this.editor.getConfiguration().lineHeight;
const lineHeight = this.editor.getOption(EditorOption.lineHeight);
// adjust heightInLines to viewport
const maxHeightInLines = (this.editor.getLayoutInfo().height / lineHeight) * 0.8;
@@ -505,7 +505,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
this._disposables.add(this._resizeSash.onDidChange((evt: ISashEvent) => {
if (data) {
let lineDelta = (evt.currentY - data.startY) / this.editor.getConfiguration().lineHeight;
let lineDelta = (evt.currentY - data.startY) / this.editor.getOption(EditorOption.lineHeight);
let roundedLineDelta = lineDelta < 0 ? Math.ceil(lineDelta) : Math.floor(lineDelta);
let newHeightInLines = data.heightInLines + roundedLineDelta;