Fixes #46455: Restore logical viewport when edits occur in another editor

This commit is contained in:
Alex Dima 2018-03-27 23:08:35 +02:00
parent 5fbcfff69a
commit f9faca3fbb
5 changed files with 38 additions and 1 deletions

View file

@ -321,6 +321,7 @@ export class View extends ViewEventHandler {
}
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
this.domNode.setClassName(this.getEditorClassName());
this._context.model.setHasFocus(e.isFocused);
if (e.isFocused) {
this.outgoingEvents.emitViewFocusGained();
} else {

View file

@ -1067,6 +1067,12 @@ export interface ITextModel {
* @internal
*/
isAttachedToEditor(): boolean;
/**
* Returns the count of editors this model is attached to.
* @internal
*/
getAttachedEditorCount(): number;
}
/**

View file

@ -551,6 +551,10 @@ export class TextModel extends Disposable implements model.ITextModel {
return this._attachedEditorCount > 0;
}
public getAttachedEditorCount(): number {
return this._attachedEditorCount;
}
public isTooLargeForHavingARichMode(): boolean {
return this._shouldSimplifyMode;
}

View file

@ -122,6 +122,7 @@ export interface IViewModel {
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void;
setHasFocus(hasFocus: boolean): void;
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;

View file

@ -23,7 +23,7 @@ import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ITheme } from 'vs/platform/theme/common/themeService';
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModel';
import { ITextModel, EndOfLinePreference } from 'vs/editor/common/model';
import { ITextModel, EndOfLinePreference, TrackedRangeStickiness } from 'vs/editor/common/model';
const USE_IDENTITY_LINES_COLLECTION = true;
@ -32,6 +32,9 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
private readonly editorId: number;
private readonly configuration: editorCommon.IConfiguration;
private readonly model: ITextModel;
private hasFocus: boolean;
private viewportStartLineTrackedRange: string;
private viewportStartLineTop: number;
private readonly lines: IViewModelLinesCollection;
public readonly coordinatesConverter: ICoordinatesConverter;
public readonly viewLayout: ViewLayout;
@ -46,6 +49,9 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.editorId = editorId;
this.configuration = configuration;
this.model = model;
this.hasFocus = false;
this.viewportStartLineTrackedRange = null;
this.viewportStartLineTop = 0;
if (USE_IDENTITY_LINES_COLLECTION && this.model.isTooLargeForTokenization()) {
@ -114,6 +120,11 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
super.dispose();
this.decorations.dispose();
this.lines.dispose();
this.viewportStartLineTrackedRange = this.model._setTrackedRange(this.viewportStartLineTrackedRange, null, TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges);
}
public setHasFocus(hasFocus: boolean): void {
this.hasFocus = hasFocus;
}
private _onConfigurationChanged(eventsCollector: viewEvents.ViewEventsCollector, e: IConfigurationChangedEvent): void {
@ -238,6 +249,16 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
// Update the configuration and reset the centered view line
this._centeredViewLine = -1;
this.configuration.setMaxLineNumber(this.model.getLineCount());
// Recover viewport
if (!this.hasFocus && this.model.getAttachedEditorCount() >= 2 && this.viewportStartLineTrackedRange) {
const modelRange = this.model._getTrackedRange(this.viewportStartLineTrackedRange);
if (modelRange) {
const viewPosition = this.coordinatesConverter.convertModelPositionToViewPosition(modelRange.getStartPosition());
const viewPositionTop = this.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber);
this.viewLayout.deltaScrollNow(0, viewPositionTop - this.viewportStartLineTop);
}
}
}));
this._register(this.model.onDidChangeTokens((e) => {
@ -402,6 +423,10 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
public setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void {
this._centeredViewLine = centeredLineNumber;
this.lines.warmUpLookupCache(startLineNumber, endLineNumber);
let position = this.coordinatesConverter.convertViewPositionToModelPosition(new Position(startLineNumber, this.getLineMinColumn(startLineNumber)));
this.viewportStartLineTrackedRange = this.model._setTrackedRange(this.viewportStartLineTrackedRange, new Range(position.lineNumber, position.column, position.lineNumber, position.column), TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges);
this.viewportStartLineTop = this.viewLayout.getVerticalOffsetForLineNumber(startLineNumber);
}
public getLinesIndentGuides(startLineNumber: number, endLineNumber: number): number[] {