提交 68468a80 编写于 作者: S Sandeep Somavarapu

fix #8624

上级 4dff48ca
......@@ -3,7 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import * as errors from 'vs/base/common/errors';
import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import * as network from 'vs/base/common/network';
......@@ -18,7 +19,9 @@ import { IEventService } from 'vs/platform/event/common/event';
import { Match, FileMatch, FileMatchOrMatch } from 'vs/workbench/parts/search/common/searchModel';
import { BulkEdit, IResourceEdit, createBulkEdit } from 'vs/editor/common/services/bulkEdit';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
class EditorInputCache {
......@@ -29,6 +32,10 @@ class EditorInputCache {
this.cache= new Map.SimpleMap<URI, TPromise<DiffEditorInput>>();
}
public hasInput(fileMatch: FileMatch): boolean {
return this.cache.has(fileMatch.resource());
}
public getInput(fileMatch: FileMatch): TPromise<DiffEditorInput> {
let editorInputPromise= this.cache.get(fileMatch.resource());
if (!editorInputPromise) {
......@@ -120,7 +127,7 @@ export class ReplaceService implements IReplaceService {
private cache: EditorInputCache;
constructor(@IEventService private eventService: IEventService, @IEditorService private editorService, @IModelService private modelService: IModelService) {
constructor(@ITelemetryService private telemetryService: ITelemetryService, @IEventService private eventService: IEventService, @IEditorService private editorService, @IModelService private modelService: IModelService) {
this.cache= new EditorInputCache(this, editorService, modelService);
}
......@@ -167,6 +174,22 @@ export class ReplaceService implements IReplaceService {
this.cache.disposeAll();
}
public openReplacePreviewEditor(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise<any> {
this.telemetryService.publicLog('replace.open.previewEditor');
return this.getInput(element instanceof Match ? element.parent() : element).then((editorInput) => {
this.editorService.openEditor(editorInput, {preserveFocus, pinned}).then((editor) => {
let editorControl= (<IDiffEditor>editor.getControl());
if (element instanceof Match) {
editorControl.revealLineInCenter(element.range().startLineNumber);
}
}, errors.onUnexpectedError);
}, errors.onUnexpectedError);
}
public isReplacePreviewEditorOpened(element: FileMatchOrMatch): boolean {
return this.cache.hasInput(element instanceof Match ? element.parent() : element);
}
private createEdit(match: Match, text: string, resource: URI= null): IResourceEdit {
let fileMatch: FileMatch= match.parent();
let resourceEdit: IResourceEdit= {
......
......@@ -23,6 +23,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Keybinding, KeyCode, KeyMod, CommonKeybindings } from 'vs/base/common/keyCodes';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { FileEditorInput } from 'vs/workbench/parts/files/common/editors/fileEditorInput';
export function isSearchViewletFocussed(viewletService: IViewletService):boolean {
let activeViewlet= viewletService.getActiveViewlet();
......@@ -125,20 +126,44 @@ export class ClearSearchResultsAction extends Action {
}
}
export class RemoveAction extends Action {
export abstract class AbstractSearchAndReplaceAction extends Action {
protected getNextFocusElement(viewer: ITree, element: FileMatchOrMatch):FileMatchOrMatch {
if (element === viewer.getFocus()) {
let navigator= viewer.getNavigator();
// navigate to current element
while (navigator.current() !== element && !!navigator.next()) {};
let previousElement= navigator.previous();
if (previousElement) {
navigator.next();
} else {
navigator.first();
}
let nextElement;
if (element instanceof FileMatch) {
while (!!navigator.next() && !(navigator.current() instanceof FileMatch)) {};
nextElement= navigator.current();
} else {
nextElement= navigator.next();
}
return nextElement ? nextElement : previousElement;
}
return null;
}
}
export class RemoveAction extends AbstractSearchAndReplaceAction {
constructor(private viewer: ITree, private element: FileMatchOrMatch) {
super('remove', nls.localize('RemoveAction.label', "Remove"), 'action-remove');
}
public run(): TPromise<any> {
if (this.element === this.viewer.getFocus()) {
let nextFocusElement= this.getNextFocusElement();
if (nextFocusElement) {
this.viewer.setFocus(nextFocusElement);
} else {
this.viewer.focusPrevious();
}
let nextFocusElement= this.getNextFocusElement(this.viewer, this.element);
if (nextFocusElement) {
this.viewer.setFocus(nextFocusElement);
}
let elementToRefresh: any;
......@@ -152,25 +177,13 @@ export class RemoveAction extends Action {
elementToRefresh= parent.count() === 0 ? parent.parent() : parent;
}
if (this.viewer.getFocus()) {
this.viewer.DOMFocus();
}
this.viewer.DOMFocus();
return this.viewer.refresh(elementToRefresh);
}
private getNextFocusElement():FileMatchOrMatch {
let navigator= this.viewer.getNavigator();
while (navigator.current() !== this.element && !!navigator.next()) {};
if (this.element instanceof FileMatch) {
while (!!navigator.next() && !(navigator.current() instanceof FileMatch)) {};
return navigator.current();
} else {
return navigator.next();
}
}
}
export class ReplaceAllAction extends Action {
export class ReplaceAllAction extends AbstractSearchAndReplaceAction {
public static get KEY_BINDING(): number {
return KeyMod.Shift | CommonKeybindings.CTRLCMD_ENTER;
......@@ -185,13 +198,18 @@ export class ReplaceAllAction extends Action {
public run(): TPromise<any> {
this.telemetryService.publicLog('replaceAll.action.selected');
let nextFocusElement= this.getNextFocusElement(this.viewer, this.fileMatch);
return this.fileMatch.parent().replace(this.fileMatch).then(() => {
this.viewlet.open(this.fileMatch);
if (nextFocusElement) {
this.viewer.setFocus(nextFocusElement);
}
this.viewer.DOMFocus();
this.viewlet.open(this.fileMatch, true);
});
}
}
export class ReplaceAction extends Action {
export class ReplaceAction extends AbstractSearchAndReplaceAction {
public static get KEY_BINDING(): number {
return KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KEY_1;
......@@ -200,16 +218,36 @@ export class ReplaceAction extends Action {
constructor(private viewer: ITree, private element: Match, private viewlet: SearchViewlet,
@IReplaceService private replaceService: IReplaceService,
@IKeybindingService keyBindingService: IKeybindingService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@ITelemetryService private telemetryService: ITelemetryService) {
super('action-replace', appendKeyBindingLabel(nls.localize('match.replace.label', "Replace"), ReplaceAction.KEY_BINDING, keyBindingService), 'action-replace');
}
public run(): TPromise<any> {
this.telemetryService.publicLog('replace.action.selected');
let nextFocusElement= this.getNextFocusElement(this.viewer, this.element);
let elementToOpen= nextFocusElement && nextFocusElement instanceof Match ? nextFocusElement : this.element.parent();
return this.element.parent().replace(this.element).then(() => {
this.viewlet.open(this.element);
if (nextFocusElement) {
this.viewer.setFocus(nextFocusElement);
}
this.viewer.DOMFocus();
if (this.isFileActive(this.element.parent())) {
this.viewlet.open(elementToOpen, true);
} else {
this.replaceService.openReplacePreviewEditor(elementToOpen, true);
}
});
}
private isFileActive(fileMatch: FileMatch): boolean {
let activeInput = this.editorService.getActiveEditorInput();
if (activeInput instanceof FileEditorInput) {
return activeInput.getResource().fsPath === fileMatch.resource().fsPath;
}
return false;
}
}
export class ConfigureGlobalExclusionsAction extends Action {
......
......@@ -9,7 +9,6 @@ import 'vs/css!./media/searchviewlet';
import nls = require('vs/nls');
import {TPromise} from 'vs/base/common/winjs.base';
import {EditorType} from 'vs/editor/common/editorCommon';
import {IDiffEditor} from 'vs/editor/browser/editorBrowser';
import lifecycle = require('vs/base/common/lifecycle');
import errors = require('vs/base/common/errors');
import aria = require('vs/base/browser/ui/aria/aria');
......@@ -902,7 +901,7 @@ export class SearchViewlet extends Viewlet {
this.telemetryService.publicLog('searchResultChosen');
return (this.viewModel.isReplaceActive() && !!this.viewModel.replaceString) ? this.openReplacePreviewEditor(lineMatch, preserveFocus, sideBySide, pinned) : this.open(lineMatch, preserveFocus, sideBySide, pinned);
return (this.viewModel.isReplaceActive() && !!this.viewModel.replaceString) ? this.replaceService.openReplacePreviewEditor(lineMatch, preserveFocus, sideBySide, pinned) : this.open(lineMatch, preserveFocus, sideBySide, pinned);
}
public open(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise<any> {
......@@ -918,18 +917,6 @@ export class SearchViewlet extends Viewlet {
}, sideBySide);
}
private openReplacePreviewEditor(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise<any> {
this.telemetryService.publicLog('replace.open.previewEditor');
return this.replaceService.getInput(element instanceof Match ? element.parent() : element).then((editorInput) => {
this.editorService.openEditor(editorInput, {preserveFocus: preserveFocus, pinned}).then((editor) => {
let editorControl= (<IDiffEditor>editor.getControl());
if (element instanceof Match) {
editorControl.revealLineInCenter(element.range().startLineNumber);
}
}, errors.onUnexpectedError);
}, errors.onUnexpectedError);
}
private getSelectionFrom(element: FileMatchOrMatch): any {
let match: Match= null;
if (element instanceof Match) {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import { Match, FileMatch } from 'vs/workbench/parts/search/common/searchModel';
import { Match, FileMatch, FileMatchOrMatch } from 'vs/workbench/parts/search/common/searchModel';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { EditorInput } from 'vs/workbench/common/editor';
......@@ -37,6 +37,16 @@ export interface IReplaceService {
*/
refreshInput(element: FileMatch, reload?: boolean): void;
/**
* Opens the replace preview editor for given element
*/
openReplacePreviewEditor(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise<any>;
/**
* Return true if preview is already opened otherwise false
*/
isReplacePreviewEditorOpened(element: FileMatchOrMatch): boolean;
/**
* Disposes all Inputs
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册