mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Symbol reordering.
This commit is contained in:
parent
d6681dfb53
commit
dddea4442c
|
@ -21,104 +21,6 @@ import { dispose, Disposable } from 'vs/base/common/lifecycle';
|
|||
import { ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { CursorStateChangedEvent, ViewModelEventsCollector } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
|
||||
|
||||
/**
|
||||
* A snapshot of the cursor and the model state
|
||||
*/
|
||||
export class CursorModelState {
|
||||
|
||||
public readonly modelVersionId: number;
|
||||
public readonly cursorState: CursorState[];
|
||||
|
||||
constructor(model: ITextModel, cursor: CursorsController) {
|
||||
this.modelVersionId = model.getVersionId();
|
||||
this.cursorState = cursor.getCursorStates();
|
||||
}
|
||||
|
||||
public equals(other: CursorModelState | null): boolean {
|
||||
if (!other) {
|
||||
return false;
|
||||
}
|
||||
if (this.modelVersionId !== other.modelVersionId) {
|
||||
return false;
|
||||
}
|
||||
if (this.cursorState.length !== other.cursorState.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, len = this.cursorState.length; i < len; i++) {
|
||||
if (!this.cursorState[i].equals(other.cursorState[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class AutoClosedAction {
|
||||
|
||||
public static getAllAutoClosedCharacters(autoClosedActions: AutoClosedAction[]): Range[] {
|
||||
let autoClosedCharacters: Range[] = [];
|
||||
for (const autoClosedAction of autoClosedActions) {
|
||||
autoClosedCharacters = autoClosedCharacters.concat(autoClosedAction.getAutoClosedCharactersRanges());
|
||||
}
|
||||
return autoClosedCharacters;
|
||||
}
|
||||
|
||||
private readonly _model: ITextModel;
|
||||
|
||||
private _autoClosedCharactersDecorations: string[];
|
||||
private _autoClosedEnclosingDecorations: string[];
|
||||
|
||||
constructor(model: ITextModel, autoClosedCharactersDecorations: string[], autoClosedEnclosingDecorations: string[]) {
|
||||
this._model = model;
|
||||
this._autoClosedCharactersDecorations = autoClosedCharactersDecorations;
|
||||
this._autoClosedEnclosingDecorations = autoClosedEnclosingDecorations;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._autoClosedCharactersDecorations = this._model.deltaDecorations(this._autoClosedCharactersDecorations, []);
|
||||
this._autoClosedEnclosingDecorations = this._model.deltaDecorations(this._autoClosedEnclosingDecorations, []);
|
||||
}
|
||||
|
||||
public getAutoClosedCharactersRanges(): Range[] {
|
||||
let result: Range[] = [];
|
||||
for (let i = 0; i < this._autoClosedCharactersDecorations.length; i++) {
|
||||
const decorationRange = this._model.getDecorationRange(this._autoClosedCharactersDecorations[i]);
|
||||
if (decorationRange) {
|
||||
result.push(decorationRange);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public isValid(selections: Range[]): boolean {
|
||||
let enclosingRanges: Range[] = [];
|
||||
for (let i = 0; i < this._autoClosedEnclosingDecorations.length; i++) {
|
||||
const decorationRange = this._model.getDecorationRange(this._autoClosedEnclosingDecorations[i]);
|
||||
if (decorationRange) {
|
||||
enclosingRanges.push(decorationRange);
|
||||
if (decorationRange.startLineNumber !== decorationRange.endLineNumber) {
|
||||
// Stop tracking if the range becomes multiline...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
enclosingRanges.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
selections.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
for (let i = 0; i < selections.length; i++) {
|
||||
if (i >= enclosingRanges.length) {
|
||||
return false;
|
||||
}
|
||||
if (!enclosingRanges[i].strictContainsRange(selections[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class CursorsController extends Disposable {
|
||||
|
||||
public static readonly MAX_CURSOR_COUNT = 10000;
|
||||
|
@ -221,7 +123,7 @@ export class CursorsController extends Disposable {
|
|||
reachedMaxCursorCount = true;
|
||||
}
|
||||
|
||||
const oldState = new CursorModelState(this._model, this);
|
||||
const oldState = CursorModelState.from(this._model, this);
|
||||
|
||||
this._cursors.setStates(states);
|
||||
this._cursors.normalize();
|
||||
|
@ -505,7 +407,7 @@ export class CursorsController extends Disposable {
|
|||
// ----- emitting events
|
||||
|
||||
private _emitStateChangedIfNecessary(eventsCollector: ViewModelEventsCollector, source: string | null | undefined, reason: CursorChangeReason, oldState: CursorModelState | null, reachedMaxCursorCount: boolean): boolean {
|
||||
const newState = new CursorModelState(this._model, this);
|
||||
const newState = CursorModelState.from(this._model, this);
|
||||
if (newState.equals(oldState)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -616,7 +518,7 @@ export class CursorsController extends Disposable {
|
|||
return;
|
||||
}
|
||||
|
||||
const oldState = new CursorModelState(this._model, this);
|
||||
const oldState = CursorModelState.from(this._model, this);
|
||||
this._cursors.stopTrackingSelections();
|
||||
this._isHandling = true;
|
||||
|
||||
|
@ -731,6 +633,105 @@ export class CursorsController extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A snapshot of the cursor and the model state
|
||||
*/
|
||||
class CursorModelState {
|
||||
public static from(model: ITextModel, cursor: CursorsController): CursorModelState {
|
||||
return new CursorModelState(model.getVersionId(), cursor.getCursorStates());
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly modelVersionId: number,
|
||||
public readonly cursorState: CursorState[],
|
||||
) {
|
||||
}
|
||||
|
||||
public equals(other: CursorModelState | null): boolean {
|
||||
if (!other) {
|
||||
return false;
|
||||
}
|
||||
if (this.modelVersionId !== other.modelVersionId) {
|
||||
return false;
|
||||
}
|
||||
if (this.cursorState.length !== other.cursorState.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, len = this.cursorState.length; i < len; i++) {
|
||||
if (!this.cursorState[i].equals(other.cursorState[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class AutoClosedAction {
|
||||
|
||||
public static getAllAutoClosedCharacters(autoClosedActions: AutoClosedAction[]): Range[] {
|
||||
let autoClosedCharacters: Range[] = [];
|
||||
for (const autoClosedAction of autoClosedActions) {
|
||||
autoClosedCharacters = autoClosedCharacters.concat(autoClosedAction.getAutoClosedCharactersRanges());
|
||||
}
|
||||
return autoClosedCharacters;
|
||||
}
|
||||
|
||||
private readonly _model: ITextModel;
|
||||
|
||||
private _autoClosedCharactersDecorations: string[];
|
||||
private _autoClosedEnclosingDecorations: string[];
|
||||
|
||||
constructor(model: ITextModel, autoClosedCharactersDecorations: string[], autoClosedEnclosingDecorations: string[]) {
|
||||
this._model = model;
|
||||
this._autoClosedCharactersDecorations = autoClosedCharactersDecorations;
|
||||
this._autoClosedEnclosingDecorations = autoClosedEnclosingDecorations;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._autoClosedCharactersDecorations = this._model.deltaDecorations(this._autoClosedCharactersDecorations, []);
|
||||
this._autoClosedEnclosingDecorations = this._model.deltaDecorations(this._autoClosedEnclosingDecorations, []);
|
||||
}
|
||||
|
||||
public getAutoClosedCharactersRanges(): Range[] {
|
||||
let result: Range[] = [];
|
||||
for (let i = 0; i < this._autoClosedCharactersDecorations.length; i++) {
|
||||
const decorationRange = this._model.getDecorationRange(this._autoClosedCharactersDecorations[i]);
|
||||
if (decorationRange) {
|
||||
result.push(decorationRange);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public isValid(selections: Range[]): boolean {
|
||||
let enclosingRanges: Range[] = [];
|
||||
for (let i = 0; i < this._autoClosedEnclosingDecorations.length; i++) {
|
||||
const decorationRange = this._model.getDecorationRange(this._autoClosedEnclosingDecorations[i]);
|
||||
if (decorationRange) {
|
||||
enclosingRanges.push(decorationRange);
|
||||
if (decorationRange.startLineNumber !== decorationRange.endLineNumber) {
|
||||
// Stop tracking if the range becomes multiline...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
enclosingRanges.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
selections.sort(Range.compareRangesUsingStarts);
|
||||
|
||||
for (let i = 0; i < selections.length; i++) {
|
||||
if (i >= enclosingRanges.length) {
|
||||
return false;
|
||||
}
|
||||
if (!enclosingRanges[i].strictContainsRange(selections[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
interface IExecContext {
|
||||
readonly model: ITextModel;
|
||||
readonly selectionsBefore: Selection[];
|
||||
|
|
|
@ -7,15 +7,6 @@ import { CursorColumns, CursorConfiguration, ICursorSimpleModel, SingleCursorSta
|
|||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
|
||||
export interface IColumnSelectResult {
|
||||
viewStates: SingleCursorState[];
|
||||
reversed: boolean;
|
||||
fromLineNumber: number;
|
||||
fromVisualColumn: number;
|
||||
toLineNumber: number;
|
||||
toVisualColumn: number;
|
||||
}
|
||||
|
||||
export class ColumnSelection {
|
||||
|
||||
public static columnSelect(config: CursorConfiguration, model: ICursorSimpleModel, fromLineNumber: number, fromVisibleColumn: number, toLineNumber: number, toVisibleColumn: number): IColumnSelectResult {
|
||||
|
@ -124,3 +115,12 @@ export class ColumnSelection {
|
|||
return this.columnSelect(config, model, prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.fromViewVisualColumn, toViewLineNumber, prevColumnSelectData.toViewVisualColumn);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IColumnSelectResult {
|
||||
viewStates: SingleCursorState[];
|
||||
reversed: boolean;
|
||||
fromLineNumber: number;
|
||||
fromVisualColumn: number;
|
||||
toLineNumber: number;
|
||||
toVisualColumn: number;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,86 @@ export interface ICursorSimpleModel {
|
|||
getLineIndentColumn(lineNumber: number): number;
|
||||
}
|
||||
|
||||
export class CursorContext {
|
||||
_cursorContextBrand: void = undefined;
|
||||
|
||||
public readonly model: ITextModel;
|
||||
public readonly viewModel: ICursorSimpleModel;
|
||||
public readonly coordinatesConverter: ICoordinatesConverter;
|
||||
public readonly cursorConfig: CursorConfiguration;
|
||||
|
||||
constructor(model: ITextModel, viewModel: ICursorSimpleModel, coordinatesConverter: ICoordinatesConverter, cursorConfig: CursorConfiguration) {
|
||||
this.model = model;
|
||||
this.viewModel = viewModel;
|
||||
this.coordinatesConverter = coordinatesConverter;
|
||||
this.cursorConfig = cursorConfig;
|
||||
}
|
||||
}
|
||||
|
||||
export type PartialCursorState = CursorState | PartialModelCursorState | PartialViewCursorState;
|
||||
|
||||
export class CursorState {
|
||||
_cursorStateBrand: void = undefined;
|
||||
|
||||
public static fromModelState(modelState: SingleCursorState): PartialModelCursorState {
|
||||
return new PartialModelCursorState(modelState);
|
||||
}
|
||||
|
||||
public static fromViewState(viewState: SingleCursorState): PartialViewCursorState {
|
||||
return new PartialViewCursorState(viewState);
|
||||
}
|
||||
|
||||
public static fromModelSelection(modelSelection: ISelection): PartialModelCursorState {
|
||||
const selection = Selection.liftSelection(modelSelection);
|
||||
const modelState = new SingleCursorState(
|
||||
Range.fromPositions(selection.getSelectionStart()),
|
||||
0,
|
||||
selection.getPosition(), 0
|
||||
);
|
||||
return CursorState.fromModelState(modelState);
|
||||
}
|
||||
|
||||
public static fromModelSelections(modelSelections: readonly ISelection[]): PartialModelCursorState[] {
|
||||
let states: PartialModelCursorState[] = [];
|
||||
for (let i = 0, len = modelSelections.length; i < len; i++) {
|
||||
states[i] = this.fromModelSelection(modelSelections[i]);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
readonly modelState: SingleCursorState;
|
||||
readonly viewState: SingleCursorState;
|
||||
|
||||
constructor(modelState: SingleCursorState, viewState: SingleCursorState) {
|
||||
this.modelState = modelState;
|
||||
this.viewState = viewState;
|
||||
}
|
||||
|
||||
public equals(other: CursorState): boolean {
|
||||
return (this.viewState.equals(other.viewState) && this.modelState.equals(other.modelState));
|
||||
}
|
||||
}
|
||||
|
||||
export class PartialModelCursorState {
|
||||
readonly modelState: SingleCursorState;
|
||||
readonly viewState: null;
|
||||
|
||||
constructor(modelState: SingleCursorState) {
|
||||
this.modelState = modelState;
|
||||
this.viewState = null;
|
||||
}
|
||||
}
|
||||
|
||||
export class PartialViewCursorState {
|
||||
readonly modelState: null;
|
||||
readonly viewState: SingleCursorState;
|
||||
|
||||
constructor(viewState: SingleCursorState) {
|
||||
this.modelState = null;
|
||||
this.viewState = viewState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the cursor state on either the model or on the view model.
|
||||
*/
|
||||
|
@ -295,86 +375,6 @@ export class SingleCursorState {
|
|||
}
|
||||
}
|
||||
|
||||
export class CursorContext {
|
||||
_cursorContextBrand: void = undefined;
|
||||
|
||||
public readonly model: ITextModel;
|
||||
public readonly viewModel: ICursorSimpleModel;
|
||||
public readonly coordinatesConverter: ICoordinatesConverter;
|
||||
public readonly cursorConfig: CursorConfiguration;
|
||||
|
||||
constructor(model: ITextModel, viewModel: ICursorSimpleModel, coordinatesConverter: ICoordinatesConverter, cursorConfig: CursorConfiguration) {
|
||||
this.model = model;
|
||||
this.viewModel = viewModel;
|
||||
this.coordinatesConverter = coordinatesConverter;
|
||||
this.cursorConfig = cursorConfig;
|
||||
}
|
||||
}
|
||||
|
||||
export class PartialModelCursorState {
|
||||
readonly modelState: SingleCursorState;
|
||||
readonly viewState: null;
|
||||
|
||||
constructor(modelState: SingleCursorState) {
|
||||
this.modelState = modelState;
|
||||
this.viewState = null;
|
||||
}
|
||||
}
|
||||
|
||||
export class PartialViewCursorState {
|
||||
readonly modelState: null;
|
||||
readonly viewState: SingleCursorState;
|
||||
|
||||
constructor(viewState: SingleCursorState) {
|
||||
this.modelState = null;
|
||||
this.viewState = viewState;
|
||||
}
|
||||
}
|
||||
|
||||
export type PartialCursorState = CursorState | PartialModelCursorState | PartialViewCursorState;
|
||||
|
||||
export class CursorState {
|
||||
_cursorStateBrand: void = undefined;
|
||||
|
||||
public static fromModelState(modelState: SingleCursorState): PartialModelCursorState {
|
||||
return new PartialModelCursorState(modelState);
|
||||
}
|
||||
|
||||
public static fromViewState(viewState: SingleCursorState): PartialViewCursorState {
|
||||
return new PartialViewCursorState(viewState);
|
||||
}
|
||||
|
||||
public static fromModelSelection(modelSelection: ISelection): PartialModelCursorState {
|
||||
const selection = Selection.liftSelection(modelSelection);
|
||||
const modelState = new SingleCursorState(
|
||||
Range.fromPositions(selection.getSelectionStart()),
|
||||
0,
|
||||
selection.getPosition(), 0
|
||||
);
|
||||
return CursorState.fromModelState(modelState);
|
||||
}
|
||||
|
||||
public static fromModelSelections(modelSelections: readonly ISelection[]): PartialModelCursorState[] {
|
||||
let states: PartialModelCursorState[] = [];
|
||||
for (let i = 0, len = modelSelections.length; i < len; i++) {
|
||||
states[i] = this.fromModelSelection(modelSelections[i]);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
readonly modelState: SingleCursorState;
|
||||
readonly viewState: SingleCursorState;
|
||||
|
||||
constructor(modelState: SingleCursorState, viewState: SingleCursorState) {
|
||||
this.modelState = modelState;
|
||||
this.viewState = viewState;
|
||||
}
|
||||
|
||||
public equals(other: CursorState): boolean {
|
||||
return (this.viewState.equals(other.viewState) && this.modelState.equals(other.modelState));
|
||||
}
|
||||
}
|
||||
|
||||
export class EditOperationResult {
|
||||
_editOperationResultBrand: void = undefined;
|
||||
|
||||
|
|
Loading…
Reference in a new issue