Initial VS Code 1.19 source merge (#571)

* Initial 1.19 xcopy

* Fix yarn build

* Fix numerous build breaks

* Next batch of build break fixes

* More build break fixes

* Runtime breaks

* Additional post merge fixes

* Fix windows setup file

* Fix test failures.

* Update license header blocks to refer to source eula
This commit is contained in:
Karl Burtram
2018-01-28 23:37:17 -08:00
committed by GitHub
parent 9a1ac20710
commit 251ae01c3e
8009 changed files with 93378 additions and 35634 deletions

View File

@@ -1,55 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
import { FindWidget, IFindController } from 'vs/editor/contrib/find/browser/findWidget';
import { FindOptionsWidget } from 'vs/editor/contrib/find/browser/findOptionsWidget';
import { CommonFindController, FindStartFocusAction, IFindStartOptions } from 'vs/editor/contrib/find/common/findController';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IStorageService } from 'vs/platform/storage/common/storage';
@editorContribution
export class FindController extends CommonFindController implements IFindController {
private _widget: FindWidget;
private _findOptionsWidget: FindOptionsWidget;
constructor(
editor: ICodeEditor,
@IContextViewService contextViewService: IContextViewService,
@IContextKeyService contextKeyService: IContextKeyService,
@IKeybindingService keybindingService: IKeybindingService,
@IThemeService themeService: IThemeService,
@IStorageService storageService: IStorageService
) {
super(editor, contextKeyService, storageService);
this._widget = this._register(new FindWidget(editor, this, this._state, contextViewService, keybindingService, contextKeyService, themeService));
this._findOptionsWidget = this._register(new FindOptionsWidget(editor, this._state, keybindingService, themeService));
}
protected _start(opts: IFindStartOptions): void {
super._start(opts);
if (opts.shouldFocus === FindStartFocusAction.FocusReplaceInput) {
this._widget.focusReplaceInput();
} else if (opts.shouldFocus === FindStartFocusAction.FocusFindInput) {
this._widget.focusFindInput();
}
}
public highlightFindOptions(): void {
if (this._state.isRevealed) {
this._widget.highlightFindOptions();
} else {
this._findOptionsWidget.highlightFindOptions();
}
}
}

View File

@@ -1,25 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as editorCommon from 'vs/editor/common/editorCommon';
export function getSelectionSearchString(editor: editorCommon.ICommonCodeEditor): string {
let selection = editor.getSelection();
// if selection spans multiple lines, default search string to empty
if (selection.startLineNumber === selection.endLineNumber) {
if (selection.isEmpty()) {
let wordAtPosition = editor.getModel().getWordAtPosition(selection.getStartPosition());
if (wordAtPosition) {
return wordAtPosition.word;
}
} else {
return editor.getModel().getValueInRange(selection);
}
}
return null;
}

View File

@@ -8,16 +8,42 @@ import * as nls from 'vs/nls';
import { HistoryNavigator } from 'vs/base/common/history';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable } from 'vs/base/common/lifecycle';
import { ContextKeyExpr, RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import * as strings from 'vs/base/common/strings';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { editorAction, ServicesAccessor, EditorAction, EditorCommand, CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
import { FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding, ToggleSearchScopeKeybinding, ShowPreviousFindTermKeybinding, ShowNextFindTermKeybinding } from 'vs/editor/contrib/find/common/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState } from 'vs/editor/contrib/find/common/findState';
import { getSelectionSearchString } from 'vs/editor/contrib/find/common/find';
import { registerEditorContribution, registerEditorAction, ServicesAccessor, EditorAction, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
import { FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding, ToggleSearchScopeKeybinding, ShowPreviousFindTermKeybinding, ShowNextFindTermKeybinding, CONTEXT_FIND_WIDGET_VISIBLE, CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState } from 'vs/editor/contrib/find/findState';
import { Delayer } from 'vs/base/common/async';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { FindWidget, IFindController } from 'vs/editor/contrib/find/findWidget';
import { FindOptionsWidget } from 'vs/editor/contrib/find/findOptionsWidget';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { optional } from 'vs/platform/instantiation/common/instantiation';
export function getSelectionSearchString(editor: ICodeEditor): string {
let selection = editor.getSelection();
// if selection spans multiple lines, default search string to empty
if (selection.startLineNumber === selection.endLineNumber) {
if (selection.isEmpty()) {
let wordAtPosition = editor.getModel().getWordAtPosition(selection.getStartPosition());
if (wordAtPosition) {
return wordAtPosition.word;
}
} else {
return editor.getModel().getValueInRange(selection);
}
}
return null;
}
export const enum FindStartFocusAction {
NoFocusChange,
@@ -28,42 +54,45 @@ export const enum FindStartFocusAction {
export interface IFindStartOptions {
forceRevealReplace: boolean;
seedSearchStringFromSelection: boolean;
seedSearchStringFromGlobalClipboard: boolean;
shouldFocus: FindStartFocusAction;
shouldAnimate: boolean;
}
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
export const CONTEXT_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = CONTEXT_FIND_WIDGET_VISIBLE.toNegated();
// Keep ContextKey use of 'Focussed' to not break when clauses
export const CONTEXT_FIND_INPUT_FOCUSED = new RawContextKey<boolean>('findInputFocussed', false);
export class CommonFindController extends Disposable implements editorCommon.IEditorContribution {
private static ID = 'editor.contrib.findController';
private static readonly ID = 'editor.contrib.findController';
private _editor: editorCommon.ICommonCodeEditor;
protected _editor: ICodeEditor;
private _findWidgetVisible: IContextKey<boolean>;
protected _state: FindReplaceState;
private _currentHistoryNavigator: HistoryNavigator<string>;
protected _updateHistoryDelayer: Delayer<void>;
private _model: FindModelBoundToEditorModel;
private _storageService: IStorageService;
private _clipboardService: IClipboardService;
public static get(editor: editorCommon.ICommonCodeEditor): CommonFindController {
public static get(editor: ICodeEditor): CommonFindController {
return editor.getContribution<CommonFindController>(CommonFindController.ID);
}
constructor(editor: editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService, @IStorageService storageService: IStorageService) {
constructor(
editor: ICodeEditor,
@IContextKeyService contextKeyService: IContextKeyService,
@IStorageService storageService: IStorageService,
@IClipboardService clipboardService: IClipboardService
) {
super();
this._editor = editor;
this._findWidgetVisible = CONTEXT_FIND_WIDGET_VISIBLE.bindTo(contextKeyService);
this._storageService = storageService;
this._clipboardService = clipboardService;
this._updateHistoryDelayer = new Delayer<void>(500);
this._currentHistoryNavigator = new HistoryNavigator<string>();
this._state = this._register(new FindReplaceState());
this.loadQueryState();
this._register(this._state.addChangeListener((e) => this._onStateChanged(e)));
this._register(this._state.onFindReplaceStateChange((e) => this._onStateChanged(e)));
this._model = null;
@@ -82,7 +111,8 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
if (shouldRestartFind) {
this._start({
forceRevealReplace: false,
seedSearchStringFromSelection: false,
seedSearchStringFromSelection: false && this._editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: false,
});
@@ -120,17 +150,20 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
this.disposeModel();
}
}
if (e.searchString) {
this.setGlobalBufferTerm(this._state.searchString);
}
}
private saveQueryState(e: FindReplaceStateChangedEvent) {
if (e.isRegex && typeof this._state.isRegex !== 'undefined') {
this._storageService.store('editor.isRegex', this._state.isRegex, StorageScope.WORKSPACE);
if (e.isRegex) {
this._storageService.store('editor.isRegex', this._state.actualIsRegex, StorageScope.WORKSPACE);
}
if (e.wholeWord && typeof this._state.wholeWord !== 'undefined') {
this._storageService.store('editor.wholeWord', this._state.wholeWord, StorageScope.WORKSPACE);
if (e.wholeWord) {
this._storageService.store('editor.wholeWord', this._state.actualWholeWord, StorageScope.WORKSPACE);
}
if (e.matchCase && typeof this._state.matchCase !== 'undefined') {
this._storageService.store('editor.matchCase', this._state.matchCase, StorageScope.WORKSPACE);
if (e.matchCase) {
this._storageService.store('editor.matchCase', this._state.actualMatchCase, StorageScope.WORKSPACE);
}
}
@@ -214,8 +247,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
isRevealed: true
};
// Consider editor selection and overwrite the state with it
if (opts.seedSearchStringFromSelection && this._editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection) {
if (opts.seedSearchStringFromSelection) {
let selectionSearchString = getSelectionSearchString(this._editor);
if (selectionSearchString) {
if (this._state.isRegex) {
@@ -226,6 +258,13 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
}
if (!stateChanges.searchString && opts.seedSearchStringFromGlobalClipboard) {
let selectionSearchString = this.getGlobalBufferTerm();
if (selectionSearchString) {
stateChanges.searchString = selectionSearchString;
}
}
// Overwrite isReplaceRevealed
if (opts.forceRevealReplace) {
stateChanges.isReplaceRevealed = true;
@@ -301,9 +340,69 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
return true;
}
public getGlobalBufferTerm(): string {
if (this._editor.getConfiguration().contribInfo.find.globalFindClipboard && this._clipboardService) {
return this._clipboardService.readFindText();
}
return '';
}
public setGlobalBufferTerm(text: string) {
if (this._editor.getConfiguration().contribInfo.find.globalFindClipboard && this._clipboardService) {
this._clipboardService.writeFindText(text);
}
}
}
export class FindController extends CommonFindController implements IFindController {
private _widget: FindWidget;
private _findOptionsWidget: FindOptionsWidget;
constructor(
editor: ICodeEditor,
@IContextViewService private _contextViewService: IContextViewService,
@IContextKeyService private _contextKeyService: IContextKeyService,
@IKeybindingService private _keybindingService: IKeybindingService,
@IThemeService private _themeService: IThemeService,
@IStorageService storageService: IStorageService,
@optional(IClipboardService) clipboardService: IClipboardService
) {
super(editor, _contextKeyService, storageService, clipboardService);
}
protected _start(opts: IFindStartOptions): void {
if (!this._widget) {
this._createFindWidget();
}
super._start(opts);
if (opts.shouldFocus === FindStartFocusAction.FocusReplaceInput) {
this._widget.focusReplaceInput();
} else if (opts.shouldFocus === FindStartFocusAction.FocusFindInput) {
this._widget.focusFindInput();
}
}
public highlightFindOptions(): void {
if (!this._widget) {
this._createFindWidget();
}
if (this._state.isRevealed) {
this._widget.highlightFindOptions();
} else {
this._findOptionsWidget.highlightFindOptions();
}
}
private _createFindWidget() {
this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService));
this._findOptionsWidget = this._register(new FindOptionsWidget(this._editor, this._state, this._keybindingService, this._themeService));
}
}
@editorAction
export class StartFindAction extends EditorAction {
constructor() {
@@ -314,21 +413,18 @@ export class StartFindAction extends EditorAction {
precondition: null,
kbOpts: {
kbExpr: null,
primary: KeyMod.CtrlCmd | KeyCode.KEY_F,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.KEY_F,
secondary: [KeyMod.CtrlCmd | KeyCode.KEY_E]
}
primary: KeyMod.CtrlCmd | KeyCode.KEY_F
}
});
}
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
let controller = CommonFindController.get(editor);
if (controller) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: true,
seedSearchStringFromSelection: editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getConfiguration().contribInfo.find.globalFindClipboard,
shouldFocus: FindStartFocusAction.FocusFindInput,
shouldAnimate: true
});
@@ -336,13 +432,47 @@ export class StartFindAction extends EditorAction {
}
}
export class StartFindWithSelectionAction extends EditorAction {
constructor() {
super({
id: FIND_IDS.StartFindWithSelection,
label: nls.localize('startFindAction', "Find"),
alias: 'Find',
precondition: null,
kbOpts: {
kbExpr: null,
primary: null,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.KEY_E,
}
}
});
}
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
let controller = CommonFindController.get(editor);
if (controller) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: true,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.FocusFindInput,
shouldAnimate: true
});
controller.setGlobalBufferTerm(controller.getState().searchString);
}
}
}
export abstract class MatchFindAction extends EditorAction {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
let controller = CommonFindController.get(editor);
if (controller && !this._run(controller)) {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: (controller.getState().searchString.length === 0),
seedSearchStringFromSelection: (controller.getState().searchString.length === 0) && editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: true,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: true
});
@@ -353,7 +483,6 @@ export abstract class MatchFindAction extends EditorAction {
protected abstract _run(controller: CommonFindController): boolean;
}
@editorAction
export class NextMatchFindAction extends MatchFindAction {
constructor() {
@@ -375,7 +504,6 @@ export class NextMatchFindAction extends MatchFindAction {
}
}
@editorAction
export class PreviousMatchFindAction extends MatchFindAction {
constructor() {
@@ -398,7 +526,7 @@ export class PreviousMatchFindAction extends MatchFindAction {
}
export abstract class SelectionMatchFindAction extends EditorAction {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
let controller = CommonFindController.get(editor);
if (!controller) {
return;
@@ -411,6 +539,7 @@ export abstract class SelectionMatchFindAction extends EditorAction {
controller.start({
forceRevealReplace: false,
seedSearchStringFromSelection: false,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: true
});
@@ -421,7 +550,6 @@ export abstract class SelectionMatchFindAction extends EditorAction {
protected abstract _run(controller: CommonFindController): boolean;
}
@editorAction
export class NextSelectionMatchFindAction extends SelectionMatchFindAction {
constructor() {
@@ -442,7 +570,6 @@ export class NextSelectionMatchFindAction extends SelectionMatchFindAction {
}
}
@editorAction
export class PreviousSelectionMatchFindAction extends SelectionMatchFindAction {
constructor() {
@@ -463,7 +590,6 @@ export class PreviousSelectionMatchFindAction extends SelectionMatchFindAction {
}
}
@editorAction
export class StartFindReplaceAction extends EditorAction {
constructor() {
@@ -480,7 +606,7 @@ export class StartFindReplaceAction extends EditorAction {
});
}
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
if (editor.getConfiguration().readOnly) {
return;
}
@@ -489,7 +615,7 @@ export class StartFindReplaceAction extends EditorAction {
let currentSelection = editor.getSelection();
// we only seed search string from selection when the current selection is single line and not empty.
let seedSearchStringFromSelection = !currentSelection.isEmpty() &&
currentSelection.startLineNumber === currentSelection.endLineNumber;
currentSelection.startLineNumber === currentSelection.endLineNumber && editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection;
let oldSearchString = controller.getState().searchString;
// 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.
@@ -500,6 +626,7 @@ export class StartFindReplaceAction extends EditorAction {
controller.start({
forceRevealReplace: true,
seedSearchStringFromSelection: seedSearchStringFromSelection,
seedSearchStringFromGlobalClipboard: editor.getConfiguration().contribInfo.find.seedSearchStringFromSelection,
shouldFocus: shouldFocus,
shouldAnimate: true
});
@@ -507,8 +634,6 @@ export class StartFindReplaceAction extends EditorAction {
}
}
@editorAction
export class ShowNextFindTermAction extends MatchFindAction {
constructor() {
@@ -518,7 +643,7 @@ export class ShowNextFindTermAction extends MatchFindAction {
alias: 'Show Next Find Term',
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSED, EditorContextKeys.focus),
primary: ShowNextFindTermKeybinding.primary,
mac: ShowNextFindTermKeybinding.mac,
@@ -533,8 +658,7 @@ export class ShowNextFindTermAction extends MatchFindAction {
}
}
@editorAction
export class ShpwPreviousFindTermAction extends MatchFindAction {
export class ShowPreviousFindTermAction extends MatchFindAction {
constructor() {
super({
@@ -543,7 +667,7 @@ export class ShpwPreviousFindTermAction extends MatchFindAction {
alias: 'Find Show Previous Find Term',
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSED, EditorContextKeys.focus),
primary: ShowPreviousFindTermKeybinding.primary,
mac: ShowPreviousFindTermKeybinding.mac,
@@ -558,26 +682,38 @@ export class ShpwPreviousFindTermAction extends MatchFindAction {
}
}
registerEditorContribution(FindController);
registerEditorAction(StartFindAction);
registerEditorAction(StartFindWithSelectionAction);
registerEditorAction(NextMatchFindAction);
registerEditorAction(PreviousMatchFindAction);
registerEditorAction(NextSelectionMatchFindAction);
registerEditorAction(PreviousSelectionMatchFindAction);
registerEditorAction(StartFindReplaceAction);
registerEditorAction(ShowNextFindTermAction);
registerEditorAction(ShowPreviousFindTermAction);
const FindCommand = EditorCommand.bindToContribution<CommonFindController>(CommonFindController.get);
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.CloseFindWidgetCommand,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.closeFindWidget(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape]
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ToggleCaseSensitiveCommand,
precondition: null,
handler: x => x.toggleCaseSensitive(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: ToggleCaseSensitiveKeybinding.primary,
mac: ToggleCaseSensitiveKeybinding.mac,
@@ -586,12 +722,12 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ToggleWholeWordCommand,
precondition: null,
handler: x => x.toggleWholeWords(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: ToggleWholeWordKeybinding.primary,
mac: ToggleWholeWordKeybinding.mac,
@@ -600,12 +736,12 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ToggleRegexCommand,
precondition: null,
handler: x => x.toggleRegex(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: ToggleRegexKeybinding.primary,
mac: ToggleRegexKeybinding.mac,
@@ -614,12 +750,12 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ToggleSearchScopeCommand,
precondition: null,
handler: x => x.toggleSearchScope(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: ToggleSearchScopeKeybinding.primary,
mac: ToggleSearchScopeKeybinding.mac,
@@ -628,35 +764,35 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ReplaceOneAction,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.replace(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_1
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.ReplaceAllAction,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.replaceAll(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
registerEditorCommand(new FindCommand({
id: FIND_IDS.SelectAllMatchesAction,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.selectAllMatches(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
weight: KeybindingsRegistry.WEIGHT.editorContrib(5),
kbExpr: EditorContextKeys.focus,
primary: KeyMod.Alt | KeyCode.Enter
}
}));
}));

View File

@@ -11,10 +11,11 @@ import { Range } from 'vs/editor/common/core/range';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
import { editorFindMatchHighlight, editorFindMatch } from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
export class FindDecorations implements IDisposable {
private _editor: editorCommon.ICommonCodeEditor;
private _editor: ICodeEditor;
private _decorations: string[];
private _overviewRulerApproximateDecorations: string[];
private _findScopeDecorationId: string;
@@ -22,7 +23,7 @@ export class FindDecorations implements IDisposable {
private _highlightedDecorationId: string;
private _startPosition: Position;
constructor(editor: editorCommon.ICommonCodeEditor) {
constructor(editor: ICodeEditor) {
this._editor = editor;
this._decorations = [];
this._overviewRulerApproximateDecorations = [];
@@ -220,7 +221,7 @@ export class FindDecorations implements IDisposable {
return result;
}
private static _CURRENT_FIND_MATCH_DECORATION = ModelDecorationOptions.register({
private static readonly _CURRENT_FIND_MATCH_DECORATION = ModelDecorationOptions.register({
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'currentFindMatch',
showIfCollapsed: true,
@@ -231,7 +232,7 @@ export class FindDecorations implements IDisposable {
}
});
private static _FIND_MATCH_DECORATION = ModelDecorationOptions.register({
private static readonly _FIND_MATCH_DECORATION = ModelDecorationOptions.register({
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'findMatch',
showIfCollapsed: true,
@@ -242,13 +243,13 @@ export class FindDecorations implements IDisposable {
}
});
private static _FIND_MATCH_NO_OVERVIEW_DECORATION = ModelDecorationOptions.register({
private static readonly _FIND_MATCH_NO_OVERVIEW_DECORATION = ModelDecorationOptions.register({
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'findMatch',
showIfCollapsed: true
});
private static _FIND_MATCH_ONLY_OVERVIEW_DECORATION = ModelDecorationOptions.register({
private static readonly _FIND_MATCH_ONLY_OVERVIEW_DECORATION = ModelDecorationOptions.register({
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
overviewRuler: {
color: themeColorFromId(editorFindMatchHighlight),
@@ -257,13 +258,13 @@ export class FindDecorations implements IDisposable {
}
});
private static _RANGE_HIGHLIGHT_DECORATION = ModelDecorationOptions.register({
private static readonly _RANGE_HIGHLIGHT_DECORATION = ModelDecorationOptions.register({
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'rangeHighlight',
isWholeLine: true
});
private static _FIND_SCOPE_DECORATION = ModelDecorationOptions.register({
private static readonly _FIND_SCOPE_DECORATION = ModelDecorationOptions.register({
className: 'findScope',
isWholeLine: true
});

View File

@@ -6,7 +6,7 @@
import { RunOnceScheduler } from 'vs/base/common/async';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ReplacePattern, parseReplaceString } from 'vs/editor/contrib/find/common/replacePattern';
import { ReplacePattern, parseReplaceString } from 'vs/editor/contrib/find/replacePattern';
import { ReplaceCommand, ReplaceCommandThatPreservesSelection } from 'vs/editor/common/commands/replaceCommand';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@@ -20,6 +20,13 @@ import { Constants } from 'vs/editor/common/core/uint';
import { SearchParams } from 'vs/editor/common/model/textModelSearch';
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
export const CONTEXT_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = CONTEXT_FIND_WIDGET_VISIBLE.toNegated();
// Keep ContextKey use of 'Focussed' to not break when clauses
export const CONTEXT_FIND_INPUT_FOCUSED = new RawContextKey<boolean>('findInputFocussed', false);
export const ToggleCaseSensitiveKeybinding: IKeybindings = {
primary: KeyMod.Alt | KeyCode.KEY_C,
@@ -46,6 +53,7 @@ export const ShowNextFindTermKeybinding: IKeybindings = {
export const FIND_IDS = {
StartFindAction: 'actions.find',
StartFindWithSelection: 'actions.findWithSelection',
NextMatchFindAction: 'editor.action.nextMatchFindAction',
PreviousMatchFindAction: 'editor.action.previousMatchFindAction',
NextSelectionMatchFindAction: 'editor.action.nextSelectionMatchFindAction',
@@ -67,7 +75,7 @@ export const MATCHES_LIMIT = 19999;
export class FindModelBoundToEditorModel {
private _editor: editorCommon.ICommonCodeEditor;
private _editor: ICodeEditor;
private _state: FindReplaceState;
private _toDispose: IDisposable[];
private _decorations: FindDecorations;
@@ -76,7 +84,7 @@ export class FindModelBoundToEditorModel {
private _updateDecorationsScheduler: RunOnceScheduler;
private _isDisposed: boolean;
constructor(editor: editorCommon.ICommonCodeEditor, state: FindReplaceState) {
constructor(editor: ICodeEditor, state: FindReplaceState) {
this._editor = editor;
this._state = state;
this._toDispose = [];
@@ -111,7 +119,7 @@ export class FindModelBoundToEditorModel {
this._updateDecorationsScheduler.schedule();
}));
this._toDispose.push(this._state.addChangeListener((e) => this._onStateChanged(e)));
this._toDispose.push(this._state.onFindReplaceStateChange((e) => this._onStateChanged(e)));
this.research(false, this._state.searchScope);
}
@@ -487,4 +495,4 @@ export class FindModelBoundToEditorModel {
this._ignoreModelContentChanged = false;
}
}
}
}

View File

@@ -9,8 +9,8 @@ import * as dom from 'vs/base/browser/dom';
import { Widget } from 'vs/base/browser/ui/widget';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { FIND_IDS } from 'vs/editor/contrib/find/common/findModel';
import { FindReplaceState } from 'vs/editor/contrib/find/common/findState';
import { FIND_IDS } from 'vs/editor/contrib/find/findModel';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
import { CaseSensitiveCheckbox, WholeWordsCheckbox, RegexCheckbox } from 'vs/base/browser/ui/findinput/findInputCheckboxes';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IThemeService, ITheme, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
@@ -18,7 +18,7 @@ import { inputActiveOptionBorder, editorWidgetBackground, contrastBorder, widget
export class FindOptionsWidget extends Widget implements IOverlayWidget {
private static ID = 'editor.contrib.findOptionsWidget';
private static readonly ID = 'editor.contrib.findOptionsWidget';
private _editor: ICodeEditor;
private _state: FindReplaceState;
@@ -88,7 +88,7 @@ export class FindOptionsWidget extends Widget implements IOverlayWidget {
this._editor.addOverlayWidget(this);
this._register(this._state.addChangeListener((e) => {
this._register(this._state.onFindReplaceStateChange((e) => {
let somethingChanged = false;
if (e.isRegex) {
this.regex.checked = this._state.isRegex;

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { EventEmitter } from 'vs/base/common/eventEmitter';
import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Range } from 'vs/editor/common/core/range';
@@ -56,9 +56,6 @@ function effectiveOptionValue(override: FindOptionOverride, value: boolean): boo
}
export class FindReplaceState implements IDisposable {
private static _CHANGED_EVENT = 'changed';
private _searchString: string;
private _replaceString: string;
private _isRevealed: boolean;
@@ -73,7 +70,7 @@ export class FindReplaceState implements IDisposable {
private _matchesPosition: number;
private _matchesCount: number;
private _currentMatch: Range;
private _eventEmitter: EventEmitter;
private _onFindReplaceStateChange: Emitter<FindReplaceStateChangedEvent>;
public get searchString(): string { return this._searchString; }
public get replaceString(): string { return this._replaceString; }
@@ -82,10 +79,16 @@ export class FindReplaceState implements IDisposable {
public get isRegex(): boolean { return effectiveOptionValue(this._isRegexOverride, this._isRegex); }
public get wholeWord(): boolean { return effectiveOptionValue(this._wholeWordOverride, this._wholeWord); }
public get matchCase(): boolean { return effectiveOptionValue(this._matchCaseOverride, this._matchCase); }
public get actualIsRegex(): boolean { return this._isRegex; }
public get actualWholeWord(): boolean { return this._wholeWord; }
public get actualMatchCase(): boolean { return this._matchCase; }
public get searchScope(): Range { return this._searchScope; }
public get matchesPosition(): number { return this._matchesPosition; }
public get matchesCount(): number { return this._matchesCount; }
public get currentMatch(): Range { return this._currentMatch; }
public get onFindReplaceStateChange(): Event<FindReplaceStateChangedEvent> { return this._onFindReplaceStateChange.event; }
constructor() {
this._searchString = '';
@@ -102,15 +105,10 @@ export class FindReplaceState implements IDisposable {
this._matchesPosition = 0;
this._matchesCount = 0;
this._currentMatch = null;
this._eventEmitter = new EventEmitter();
this._onFindReplaceStateChange = new Emitter<FindReplaceStateChangedEvent>();
}
public dispose(): void {
this._eventEmitter.dispose();
}
public addChangeListener(listener: (e: FindReplaceStateChangedEvent) => void): IDisposable {
return this._eventEmitter.addListener(FindReplaceState._CHANGED_EVENT, listener);
}
public changeMatchInfo(matchesPosition: number, matchesCount: number, currentMatch: Range): void {
@@ -158,7 +156,7 @@ export class FindReplaceState implements IDisposable {
}
if (somethingChanged) {
this._eventEmitter.emit(FindReplaceState._CHANGED_EVENT, changeEvent);
this._onFindReplaceStateChange.fire(changeEvent);
}
}
@@ -248,7 +246,7 @@ export class FindReplaceState implements IDisposable {
}
if (somethingChanged) {
this._eventEmitter.emit(FindReplaceState._CHANGED_EVENT, changeEvent);
this._onFindReplaceStateChange.fire(changeEvent);
}
}
}

View File

@@ -21,11 +21,10 @@ import { Widget } from 'vs/base/browser/ui/widget';
import { Sash, IHorizontalSashLayoutProvider, ISashEvent, Orientation } from 'vs/base/browser/ui/sash/sash';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { FIND_IDS, MATCHES_LIMIT } from 'vs/editor/contrib/find/common/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/common/findState';
import { FIND_IDS, MATCHES_LIMIT, CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
import { Range } from 'vs/editor/common/core/range';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/common/findController';
import { ITheme, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
@@ -35,6 +34,7 @@ import { editorFindRangeHighlight, editorFindMatch, editorFindMatchHighlight, ac
export interface IFindController {
replace(): void;
replaceAll(): void;
getGlobalBufferTerm(): string;
}
const NLS_FIND_INPUT_LABEL = nls.localize('label.find', "Find");
@@ -81,7 +81,7 @@ export class FindWidgetViewZone implements IViewZone {
}
export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSashLayoutProvider {
private static ID = 'editor.contrib.findWidget';
private static readonly ID = 'editor.contrib.findWidget';
private _codeEditor: ICodeEditor;
private _state: FindReplaceState;
private _controller: IFindController;
@@ -110,6 +110,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
private _viewZoneId: number;
private _resizeSash: Sash;
private _resized: boolean;
constructor(
codeEditor: ICodeEditor,
@@ -130,50 +131,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._isVisible = false;
this._isReplaceVisible = false;
this._register(this._state.addChangeListener((e) => this._onStateChanged(e)));
this._register(this._state.onFindReplaceStateChange((e) => this._onStateChanged(e)));
this._buildDomNode();
this._updateButtons();
let checkEditorWidth = () => {
let editorWidth = this._codeEditor.getConfiguration().layoutInfo.width;
let minimapWidth = this._codeEditor.getConfiguration().layoutInfo.minimapWidth;
let collapsedFindWidget = false;
let reducedFindWidget = false;
let narrowFindWidget = false;
let widgetWidth = dom.getTotalWidth(this._domNode);
if (widgetWidth > FIND_WIDGET_INITIAL_WIDTH) {
// as the widget is resized by users, we may need to change the max width of the widget as the editor width changes.
this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`;
this._replaceInputBox.inputElement.style.width = `${dom.getTotalWidth(this._findInput.inputBox.inputElement)}px`;
return;
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth >= editorWidth) {
reducedFindWidget = true;
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth - MAX_MATCHES_COUNT_WIDTH >= editorWidth) {
narrowFindWidget = true;
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth - MAX_MATCHES_COUNT_WIDTH >= editorWidth + 50) {
collapsedFindWidget = true;
}
dom.toggleClass(this._domNode, 'collapsed-find-widget', collapsedFindWidget);
dom.toggleClass(this._domNode, 'narrow-find-widget', narrowFindWidget);
dom.toggleClass(this._domNode, 'reduced-find-widget', reducedFindWidget);
if (!narrowFindWidget && !collapsedFindWidget) {
// the minimal left offset of findwidget is 15px.
this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`;
}
let findInputWidth = dom.getTotalWidth(this._findInput.inputBox.inputElement);
if (findInputWidth > 0) {
this._replaceInputBox.inputElement.style.width = `${findInputWidth}px`;
}
};
checkEditorWidth();
this._tryUpdateWidgetWidth();
this._register(this._codeEditor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.readOnly) {
@@ -184,7 +145,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._updateButtons();
}
if (e.layoutInfo) {
checkEditorWidth();
this._tryUpdateWidgetWidth();
}
}));
this._register(this._codeEditor.onDidChangeCursorSelection(() => {
@@ -192,9 +153,18 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._updateToggleSelectionFindButton();
}
}));
this._register(this._codeEditor.onDidFocusEditor(() => {
if (this._isVisible) {
let globalBufferTerm = this._controller.getGlobalBufferTerm();
if (globalBufferTerm && globalBufferTerm !== this._state.searchString) {
this._state.change({ searchString: globalBufferTerm }, true);
this._findInput.select();
}
}
}));
this._findInputFocused = CONTEXT_FIND_INPUT_FOCUSED.bindTo(contextKeyService);
this._focusTracker = this._register(dom.trackFocus(this._findInput.inputBox.inputElement));
this._focusTracker.addFocusListener(() => {
this._register(this._focusTracker.onDidFocus(() => {
this._findInputFocused.set(true);
if (this._toggleSelectionFind.checked) {
@@ -210,10 +180,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
}
}
});
this._focusTracker.addBlurListener(() => {
}));
this._register(this._focusTracker.onDidBlur(() => {
this._findInputFocused.set(false);
});
}));
this._codeEditor.addOverlayWidget(this);
this._viewZone = new FindWidgetViewZone(0); // Put it before the first line then users can scroll beyond the first line.
@@ -290,6 +260,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
if (this._state.isReplaceRevealed) {
if (!this._codeEditor.getConfiguration().readOnly && !this._isReplaceVisible) {
this._isReplaceVisible = true;
this._replaceInputBox.width = this._findInput.inputBox.width;
this._updateButtons();
}
} else {
@@ -405,6 +376,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
} else {
this._toggleSelectionFind.checked = false;
}
this._tryUpdateWidgetWidth();
this._updateButtons();
setTimeout(() => {
@@ -535,6 +507,53 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._replaceInputBox.style(inputStyles);
}
private _tryUpdateWidgetWidth() {
if (!this._isVisible) {
return;
}
let editorWidth = this._codeEditor.getConfiguration().layoutInfo.width;
let minimapWidth = this._codeEditor.getConfiguration().layoutInfo.minimapWidth;
let collapsedFindWidget = false;
let reducedFindWidget = false;
let narrowFindWidget = false;
if (this._resized) {
let widgetWidth = dom.getTotalWidth(this._domNode);
if (widgetWidth > FIND_WIDGET_INITIAL_WIDTH) {
// as the widget is resized by users, we may need to change the max width of the widget as the editor width changes.
this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`;
this._replaceInputBox.inputElement.style.width = `${dom.getTotalWidth(this._findInput.inputBox.inputElement)}px`;
return;
}
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth >= editorWidth) {
reducedFindWidget = true;
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth - MAX_MATCHES_COUNT_WIDTH >= editorWidth) {
narrowFindWidget = true;
}
if (FIND_WIDGET_INITIAL_WIDTH + 28 + minimapWidth - MAX_MATCHES_COUNT_WIDTH >= editorWidth + 50) {
collapsedFindWidget = true;
}
dom.toggleClass(this._domNode, 'collapsed-find-widget', collapsedFindWidget);
dom.toggleClass(this._domNode, 'narrow-find-widget', narrowFindWidget);
dom.toggleClass(this._domNode, 'reduced-find-widget', reducedFindWidget);
if (!narrowFindWidget && !collapsedFindWidget) {
// the minimal left offset of findwidget is 15px.
this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`;
}
if (this._resized) {
let findInputWidth = dom.getTotalWidth(this._findInput.inputBox.inputElement);
if (findInputWidth > 0) {
this._replaceInputBox.inputElement.style.width = `${findInputWidth}px`;
}
}
}
// ----- Public
public focusFindInput(): void {
@@ -862,13 +881,15 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
private _buildSash() {
this._resizeSash = new Sash(this._domNode, this, { orientation: Orientation.VERTICAL });
this._resized = false;
let originalWidth = FIND_WIDGET_INITIAL_WIDTH;
this._register(this._resizeSash.addListener('start', (e: ISashEvent) => {
this._register(this._resizeSash.onDidStart((e: ISashEvent) => {
originalWidth = dom.getTotalWidth(this._domNode);
}));
this._register(this._resizeSash.addListener('change', (evt: ISashEvent) => {
this._register(this._resizeSash.onDidChange((evt: ISashEvent) => {
this._resized = true;
let width = originalWidth + evt.startX - evt.currentX;
if (width < FIND_WIDGET_INITIAL_WIDTH) {
@@ -1076,4 +1097,3 @@ registerThemingParticipant((theme, collector) => {
collector.addRule(`.monaco-editor .find-widget .monaco-sash { background-color: ${border}; width: 3px !important; margin-left: -4px;}`);
}
});

View File

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

View File

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 307 B

View File

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 307 B

View File

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

View File

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

View File

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 131 B

View File

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 131 B

View File

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

View File

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 637 B

View File

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 637 B

View File

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 589 B

View File

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 589 B

View File

@@ -30,7 +30,7 @@ export class ReplaceAllCommand implements editorCommon.ICommand {
if (this._ranges.length > 0) {
// Collect all edit operations
var ops: IEditOperation[] = [];
for (var i = 0; i < this._ranges.length; i++) {
for (let i = 0; i < this._ranges.length; i++) {
ops.push({
range: this._ranges[i],
text: this._replaceStrings[i]
@@ -45,7 +45,7 @@ export class ReplaceAllCommand implements editorCommon.ICommand {
// Merge operations that touch each other
var resultOps: IEditOperation[] = [];
var previousOp = ops[0];
for (var i = 1; i < ops.length; i++) {
for (let i = 1; i < ops.length; i++) {
if (previousOp.range.endLineNumber === ops[i].range.startLineNumber && previousOp.range.endColumn === ops[i].range.startColumn) {
// These operations are one after another and can be merged
previousOp.range = previousOp.range.plusRange(ops[i].range);

View File

@@ -113,12 +113,12 @@ export abstract class SimpleFindWidget extends Widget {
});
this._focusTracker = this._register(dom.trackFocus(this._innerDomNode));
this._register(this._focusTracker.addFocusListener(this.onFocusTrackerFocus.bind(this)));
this._register(this._focusTracker.addBlurListener(this.onFocusTrackerBlur.bind(this)));
this._register(this._focusTracker.onDidFocus(this.onFocusTrackerFocus.bind(this)));
this._register(this._focusTracker.onDidBlur(this.onFocusTrackerBlur.bind(this)));
this._findInputFocusTracker = this._register(dom.trackFocus(this._findInput.domNode));
this._register(this._findInputFocusTracker.addFocusListener(this.onFindInputFocusTrackerFocus.bind(this)));
this._register(this._findInputFocusTracker.addBlurListener(this.onFindInputFocusTrackerBlur.bind(this)));
this._register(this._findInputFocusTracker.onDidFocus(this.onFindInputFocusTrackerFocus.bind(this)));
this._register(this._findInputFocusTracker.onDidBlur(this.onFindInputFocusTrackerBlur.bind(this)));
this._register(dom.addDisposableListener(this._innerDomNode, 'click', (event) => {
event.stopPropagation();

View File

@@ -7,16 +7,14 @@
import * as assert from 'assert';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import {
getSelectionSearchString
} from 'vs/editor/contrib/find/common/find';
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
import { getSelectionSearchString } from 'vs/editor/contrib/find/findController';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
suite('Find', () => {
test('search string at position', () => {
withMockCodeEditor([
withTestCodeEditor([
'ABC DEF',
'0123 456'
], {}, (editor, cursor) => {
@@ -39,7 +37,7 @@ suite('Find', () => {
});
test('search string with selection', () => {
withMockCodeEditor([
withTestCodeEditor([
'ABC DEF',
'0123 456'
], {}, (editor, cursor) => {
@@ -63,7 +61,7 @@ suite('Find', () => {
});
test('search string with multiline selection', () => {
withMockCodeEditor([
withTestCodeEditor([
'ABC DEF',
'0123 456'
], {}, (editor, cursor) => {
@@ -86,4 +84,4 @@ suite('Find', () => {
});
});
});
});

View File

@@ -11,14 +11,16 @@ import { EditOperation } from 'vs/editor/common/core/editOperation';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { Range } from 'vs/editor/common/core/range';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { CommonFindController, FindStartFocusAction, IFindStartOptions, NextMatchFindAction, StartFindAction } from 'vs/editor/contrib/find/common/findController';
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
import * as platform from 'vs/base/common/platform';
import { CommonFindController, FindStartFocusAction, IFindStartOptions, NextMatchFindAction, StartFindAction } from 'vs/editor/contrib/find/findController';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
import { HistoryNavigator } from 'vs/base/common/history';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { Delayer } from 'vs/base/common/async';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
export class TestFindController extends CommonFindController {
@@ -28,8 +30,13 @@ export class TestFindController extends CommonFindController {
private _delayedUpdateHistoryEvent: Emitter<void> = new Emitter<void>();
constructor(editor: ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService, @IStorageService storageService: IStorageService) {
super(editor, contextKeyService, storageService);
constructor(
editor: ICodeEditor,
@IContextKeyService contextKeyService: IContextKeyService,
@IStorageService storageService: IStorageService,
@IClipboardService clipboardService: IClipboardService
) {
super(editor, contextKeyService, storageService, clipboardService);
this._updateHistoryDelayer = new Delayer<void>(50);
}
@@ -70,21 +77,104 @@ function fromRange(rng: Range): number[] {
suite('FindController', () => {
let queryState: { [key: string]: any; } = {};
let clipboardState = '';
let serviceCollection = new ServiceCollection();
serviceCollection.set(IStorageService, <any>{
serviceCollection.set(IStorageService, {
get: (key: string) => queryState[key],
getBoolean: (key: string) => !!queryState[key],
store: (key: string, value: any) => { queryState[key] = value; }
});
} as IStorageService);
test('issue #1857: F3, Find Next, acts like "Find Under Cursor"', () => {
withMockCodeEditor([
if (platform.isMacintosh) {
serviceCollection.set(IClipboardService, <any>{
readFindText: _ => clipboardState,
writeFindText: (value: any) => { clipboardState = value; }
});
}
test('stores to the global clipboard buffer on start find action', () => {
withTestCodeEditor([
'ABC',
'ABC',
'XYZ',
'ABC'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
if (!platform.isMacintosh) {
assert.ok(true);
return;
}
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let startFindAction = new StartFindAction();
// I select ABC on the first line
editor.setSelection(new Selection(1, 1, 1, 4));
// I hit Ctrl+F to show the Find dialog
startFindAction.run(null, editor);
assert.deepEqual(findController.getGlobalBufferTerm(), findController.getState().searchString);
findController.dispose();
});
});
test('reads from the global clipboard buffer on next find action if buffer exists', () => {
withTestCodeEditor([
'ABC',
'ABC',
'XYZ',
'ABC'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = 'ABC';
if (!platform.isMacintosh) {
assert.ok(true);
return;
}
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let findState = findController.getState();
let nextMatchFindAction = new NextMatchFindAction();
nextMatchFindAction.run(null, editor);
assert.equal(findState.searchString, 'ABC');
assert.deepEqual(fromRange(editor.getSelection()), [1, 1, 1, 4]);
findController.dispose();
});
});
test('writes to the global clipboard buffer when text changes', () => {
withTestCodeEditor([
'ABC',
'ABC',
'XYZ',
'ABC'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
if (!platform.isMacintosh) {
assert.ok(true);
return;
}
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let findState = findController.getState();
findState.change({ searchString: 'ABC' }, true);
assert.deepEqual(findController.getGlobalBufferTerm(), 'ABC');
findController.dispose();
});
});
test('issue #1857: F3, Find Next, acts like "Find Under Cursor"', () => {
withTestCodeEditor([
'ABC',
'ABC',
'XYZ',
'ABC'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
// The cursor is at the very top, of the file, at the first ABC
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let findState = findController.getState();
@@ -136,10 +226,10 @@ suite('FindController', () => {
});
test('issue #3090: F3 does not loop with two matches on a single line', () => {
withMockCodeEditor([
withTestCodeEditor([
'import nls = require(\'vs/nls\');'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let nextMatchFindAction = new NextMatchFindAction();
@@ -159,12 +249,12 @@ suite('FindController', () => {
});
test('issue #6149: Auto-escape highlighted text for search and replace regex mode', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let startFindAction = new StartFindAction();
let nextMatchFindAction = new NextMatchFindAction();
@@ -185,16 +275,17 @@ suite('FindController', () => {
});
test('issue #9043: Clear search scope when find widget is hidden', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.start({
forceRevealReplace: false,
seedSearchStringFromSelection: false,
seedSearchStringFromGlobalClipboard: false,
shouldFocus: FindStartFocusAction.NoFocusChange,
shouldAnimate: false
});
@@ -213,12 +304,12 @@ suite('FindController', () => {
});
test('find term is added to history on state change', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
@@ -229,12 +320,12 @@ suite('FindController', () => {
});
test('find term is added with delay', (done) => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.delayUpdateHistory = true;
findController.getState().change({ searchString: '1' }, false);
@@ -249,12 +340,12 @@ suite('FindController', () => {
});
test('show previous find term', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
@@ -266,12 +357,12 @@ suite('FindController', () => {
});
test('show previous find term do not update history', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
@@ -283,12 +374,12 @@ suite('FindController', () => {
});
test('show next find term', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
@@ -303,12 +394,12 @@ suite('FindController', () => {
});
test('show next find term do not update history', () => {
withMockCodeEditor([
withTestCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
@@ -323,10 +414,10 @@ suite('FindController', () => {
});
test('issue #18111: Regex replace with single space replaces with no space', () => {
withMockCodeEditor([
withTestCodeEditor([
'HRESULT OnAmbientPropertyChange(DISPID dispid);'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let startFindAction = new StartFindAction();
@@ -348,12 +439,12 @@ suite('FindController', () => {
});
test('issue #24714: Regular expression with ^ in search & replace', () => {
withMockCodeEditor([
withTestCodeEditor([
'',
'line2',
'line3'
], { serviceCollection: serviceCollection }, (editor, cursor) => {
clipboardState = '';
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
let startFindAction = new StartFindAction();
@@ -392,14 +483,14 @@ suite('FindController query options persistence', () => {
queryState['editor.matchCase'] = false;
queryState['editor.wholeWord'] = false;
let serviceCollection = new ServiceCollection();
serviceCollection.set(IStorageService, <any>{
serviceCollection.set(IStorageService, {
get: (key: string) => queryState[key],
getBoolean: (key: string) => !!queryState[key],
store: (key: string, value: any) => { queryState[key] = value; }
});
} as IStorageService);
test('matchCase', () => {
withMockCodeEditor([
withTestCodeEditor([
'abc',
'ABC',
'XYZ',
@@ -426,7 +517,7 @@ suite('FindController query options persistence', () => {
queryState = { 'editor.isRegex': false, 'editor.matchCase': false, 'editor.wholeWord': true };
test('wholeWord', () => {
withMockCodeEditor([
withTestCodeEditor([
'ABC',
'AB',
'XYZ',
@@ -451,7 +542,7 @@ suite('FindController query options persistence', () => {
});
test('toggling options is saved', () => {
withMockCodeEditor([
withTestCodeEditor([
'ABC',
'AB',
'XYZ',
@@ -466,4 +557,4 @@ suite('FindController query options persistence', () => {
findController.dispose();
});
});
});
});

View File

@@ -9,17 +9,17 @@ import { Cursor } from 'vs/editor/common/controller/cursor';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { Range } from 'vs/editor/common/core/range';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { FindModelBoundToEditorModel } from 'vs/editor/contrib/find/common/findModel';
import { FindReplaceState } from 'vs/editor/contrib/find/common/findState';
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
import { CoreNavigationCommands } from 'vs/editor/common/controller/coreCommands';
import { FindModelBoundToEditorModel } from 'vs/editor/contrib/find/findModel';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
import { CoreNavigationCommands } from 'vs/editor/browser/controller/coreCommands';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
suite('FindModel', () => {
function findTest(testName: string, callback: (editor: ICommonCodeEditor, cursor: Cursor) => void): void {
function findTest(testName: string, callback: (editor: ICodeEditor, cursor: Cursor) => void): void {
test(testName, () => {
withMockCodeEditor([
withTestCodeEditor([
'// my cool header',
'#include "cool.h"',
'#include <iostream>',
@@ -40,7 +40,7 @@ suite('FindModel', () => {
return [rng.startLineNumber, rng.startColumn, rng.endLineNumber, rng.endColumn];
}
function _getFindState(editor: ICommonCodeEditor) {
function _getFindState(editor: ICodeEditor) {
let model = editor.getModel();
let currentFindMatches: Range[] = [];
let allFindMatches: Range[] = [];
@@ -63,7 +63,7 @@ suite('FindModel', () => {
};
}
function assertFindState(editor: ICommonCodeEditor, cursor: number[], highlighted: number[], findDecorations: number[][]): void {
function assertFindState(editor: ICodeEditor, cursor: number[], highlighted: number[], findDecorations: number[][]): void {
assert.deepEqual(fromRange(editor.getSelection()), cursor, 'cursor');
let expectedState = {

View File

@@ -5,7 +5,7 @@
'use strict';
import * as assert from 'assert';
import { parseReplaceString, ReplacePattern, ReplacePiece } from 'vs/editor/contrib/find/common/replacePattern';
import { parseReplaceString, ReplacePattern, ReplacePiece } from 'vs/editor/contrib/find/replacePattern';
suite('Replace Pattern test', () => {