Introduce editor.wrappingAlgorithm

上级 c6dec6ef
......@@ -116,9 +116,7 @@ function createLineBreaks(requests: string[], fontInfo: FontInfo, tabSize: numbe
containerDomNode.innerHTML = sb.build();
containerDomNode.style.position = 'absolute';
containerDomNode.style.right = '0';
containerDomNode.style.bottom = '0';
containerDomNode.style.zIndex = '10000';
containerDomNode.style.top = '10000';
document.body.appendChild(containerDomNode);
let range = document.createRange();
......
......@@ -54,7 +54,6 @@ import { MonospaceLineBreaksComputerFactory } from 'vs/editor/common/viewModel/m
import { DOMLineBreaksComputerFactory } from 'vs/editor/browser/view/domLineBreaksComputer';
let EDITOR_ID = 0;
const useDOMLineBreaksComputerFactory = false;
export interface ICodeEditorWidgetOptions {
/**
......@@ -1343,11 +1342,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
this._id,
this._configuration,
model,
(
useDOMLineBreaksComputerFactory
? DOMLineBreaksComputerFactory.create(this._configuration.options)
: MonospaceLineBreaksComputerFactory.create(this._configuration.options)
),
DOMLineBreaksComputerFactory.create(this._configuration.options),
MonospaceLineBreaksComputerFactory.create(this._configuration.options),
(callback) => dom.scheduleAtNextAnimationFrame(callback)
);
......
......@@ -262,6 +262,11 @@ export interface IEditorOptions {
* Defaults to 'same' in vscode and to 'none' in monaco-editor.
*/
wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent';
/**
* Controls the wrapping algorithm to use.
* Defaults to 'monospace'.
*/
wrappingAlgorithm?: 'monospace' | 'dom';
/**
* Configure word wrapping characters. A break will be introduced before these characters.
* Defaults to '([{‘“〈《「『【〔([{「£¥$£¥++'.
......@@ -3158,6 +3163,7 @@ export const enum EditorOption {
wordWrapColumn,
wordWrapMinified,
wrappingIndent,
wrappingAlgorithm,
// Leave these at the end (because they have dependencies!)
editorClassName,
......@@ -3722,6 +3728,17 @@ export const EditorOptions = {
description: nls.localize('wrappingIndent', "Controls the indentation of wrapped lines."),
}
)),
wrappingAlgorithm: register(new EditorStringEnumOption(
EditorOption.wrappingAlgorithm, 'wrappingAlgorithm',
'monospace', ['monospace', 'dom'],
{
enumDescriptions: [
nls.localize('wrappingAlgorithm.monospace', "Assumes that all characters are of the same width. This is a fast algorithm."),
nls.localize('wrappingAlgorithm.dom', "Delegates wrapping points computation to the DOM. This is a slow algorithm, that might cause freezes for large files.")
],
description: nls.localize('wrappingAlgorithm', "Controls the algorithm that computes wrapping points.")
}
)),
// Leave these at the end (because they have dependencies!)
editorClassName: register(new EditorClassName()),
......
......@@ -264,11 +264,16 @@ class LineNumberMapper {
}
}
const usDOMLineBreaksComputerFactory = false;
export class SplitLinesCollection implements IViewModelLinesCollection {
private readonly model: ITextModel;
private _validModelVersionId: number;
private readonly _domLineBreaksComputerFactory: ILineBreaksComputerFactory;
private readonly _monospaceLineBreaksComputerFactory: ILineBreaksComputerFactory;
private wrappingColumn: number;
private columnsForFullWidthChar: number;
private wrappingIndent: WrappingIndent;
......@@ -277,18 +282,25 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
private prefixSumComputer!: LineNumberMapper;
private readonly linePositionMapperFactory: ILineBreaksComputerFactory;
private hiddenAreasIds!: string[];
constructor(model: ITextModel, linePositionMapperFactory: ILineBreaksComputerFactory, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent) {
constructor(
model: ITextModel,
domLineBreaksComputerFactory: ILineBreaksComputerFactory,
monospaceLineBreaksComputerFactory: ILineBreaksComputerFactory,
tabSize: number,
wrappingColumn: number,
columnsForFullWidthChar: number,
wrappingIndent: WrappingIndent
) {
this.model = model;
this._validModelVersionId = -1;
this._domLineBreaksComputerFactory = domLineBreaksComputerFactory;
this._monospaceLineBreaksComputerFactory = monospaceLineBreaksComputerFactory;
this.tabSize = tabSize;
this.wrappingColumn = wrappingColumn;
this.columnsForFullWidthChar = columnsForFullWidthChar;
this.wrappingIndent = wrappingIndent;
this.linePositionMapperFactory = linePositionMapperFactory;
this._constructLines(/*resetHiddenAreas*/true, null);
}
......@@ -310,7 +322,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
let linesContent = this.model.getLinesContent();
const lineCount = linesContent.length;
const lineBreaksComputer = this.linePositionMapperFactory.createLineBreaksComputer(this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent);
const lineBreaksComputer = this.createLineBreaksComputer();
for (let i = 0; i < lineCount; i++) {
lineBreaksComputer.addRequest(linesContent[i], previousLineBreaks ? previousLineBreaks[i] : null);
}
......@@ -495,7 +507,12 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
}
public createLineBreaksComputer(): ILineBreaksComputer {
return this.linePositionMapperFactory.createLineBreaksComputer(this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent);
const lineBreaksComputerFactory = (
usDOMLineBreaksComputerFactory
? this._domLineBreaksComputerFactory
: this._monospaceLineBreaksComputerFactory
);
return lineBreaksComputerFactory.createLineBreaksComputer(this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent);
}
public onModelFlushed(): void {
......
......@@ -46,7 +46,8 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
editorId: number,
configuration: editorCommon.IConfiguration,
model: ITextModel,
lineMapperFactory: ILineBreaksComputerFactory,
domLineBreaksComputerFactory: ILineBreaksComputerFactory,
monospaceLineBreaksComputerFactory: ILineBreaksComputerFactory,
scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable
) {
super();
......@@ -72,7 +73,8 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.lines = new SplitLinesCollection(
this.model,
lineMapperFactory,
domLineBreaksComputerFactory,
monospaceLineBreaksComputerFactory,
this.model.getOptions().tabSize,
wrappingInfo.wrappingColumn,
fontInfo.typicalFullwidthCharacterWidth / fontInfo.typicalHalfwidthCharacterWidth,
......
......@@ -201,7 +201,8 @@ suite('SideEditing', () => {
function _runTest(selection: Selection, editRange: Range, editText: string, editForceMoveMarkers: boolean, expected: Selection, msg: string): void {
const model = TextModel.createFromString(LINES.join('\n'));
const config = new TestConfiguration({});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const monospaceLineBreaksComputerFactory = MonospaceLineBreaksComputerFactory.create(config.options);
const viewModel = new ViewModel(0, config, model, monospaceLineBreaksComputerFactory, monospaceLineBreaksComputerFactory, null!);
const cursor = new Cursor(config, model, viewModel);
cursor.setSelections('tests', [selection]);
......
......@@ -12,7 +12,7 @@ import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { TokenizationResult2 } from 'vs/editor/common/core/token';
import { Handler, ICommand, ICursorStateComputerData, IEditOperationBuilder } from 'vs/editor/common/editorCommon';
import { Handler, ICommand, ICursorStateComputerData, IEditOperationBuilder, IConfiguration } from 'vs/editor/common/editorCommon';
import { EndOfLinePreference, EndOfLineSequence, ITextModel } from 'vs/editor/common/model';
import { TextModel } from 'vs/editor/common/model/textModel';
import { IState, ITokenizationSupport, LanguageIdentifier, TokenizationRegistry } from 'vs/editor/common/modes';
......@@ -131,6 +131,11 @@ function assertCursor(cursor: Cursor, what: Position | Selection | Selection[]):
assert.deepEqual(actual, expected);
}
function createViewModel(configuration: IConfiguration, model: ITextModel): ViewModel {
const monospaceLineBreaksComputerFactory = MonospaceLineBreaksComputerFactory.create(configuration.options);
return new ViewModel(0, configuration, model, monospaceLineBreaksComputerFactory, monospaceLineBreaksComputerFactory, null!);
}
suite('Editor Controller - Cursor', () => {
const LINE1 = ' \tMy First Line\t ';
const LINE2 = '\tMy Second Line';
......@@ -153,7 +158,7 @@ suite('Editor Controller - Cursor', () => {
thisModel = createTextModel(text);
thisConfiguration = new TestConfiguration({});
thisViewModel = new ViewModel(0, thisConfiguration, thisModel, MonospaceLineBreaksComputerFactory.create(thisConfiguration.options), null!);
thisViewModel = createViewModel(thisConfiguration, thisModel);
thisCursor = new Cursor(thisConfiguration, thisModel, thisViewModel);
});
......@@ -777,7 +782,7 @@ suite('Editor Controller - Cursor', () => {
'var newer = require("gulp-newer");',
].join('\n'));
const config = new TestConfiguration({});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const viewModel = createViewModel(config, model);
const cursor = new Cursor(config, model, viewModel);
moveTo(cursor, 1, 4, false);
......@@ -817,7 +822,7 @@ suite('Editor Controller - Cursor', () => {
'<property id="SomeThing" key="SomeKey" value="00X"/>',
].join('\n'));
const config = new TestConfiguration({});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const viewModel = createViewModel(config, model);
const cursor = new Cursor(config, model, viewModel);
moveTo(cursor, 10, 10, false);
......@@ -881,7 +886,7 @@ suite('Editor Controller - Cursor', () => {
'<property id="SomeThing" key="SomeKey" value="00X"/>',
].join('\n'));
const config = new TestConfiguration({});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const viewModel = createViewModel(config, model);
const cursor = new Cursor(config, model, viewModel);
moveTo(cursor, 10, 10, false);
......@@ -930,7 +935,7 @@ suite('Editor Controller - Cursor', () => {
'var newer = require("gulp-newer");',
].join('\n'));
const config = new TestConfiguration({});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const viewModel = createViewModel(config, model);
const cursor = new Cursor(config, model, viewModel);
moveTo(cursor, 1, 4, false);
......@@ -2075,7 +2080,7 @@ suite('Editor Controller - Regression tests', () => {
wordWrap: 'wordWrapColumn',
wordWrapColumn: 100
});
const viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
const viewModel = createViewModel(config, model);
const cursor = new Cursor(config, model, viewModel);
moveTo(cursor, 1, 43, false);
......@@ -3835,7 +3840,7 @@ function usingCursor(opts: ICursorOpts, callback: (model: TextModel, cursor: Cur
let model = createTextModel(opts.text.join('\n'), opts.modelOpts, opts.languageIdentifier);
model.forceTokenization(model.getLineCount());
let config = new TestConfiguration(opts.editorOpts || {});
let viewModel = new ViewModel(0, config, model, MonospaceLineBreaksComputerFactory.create(config.options), null!);
let viewModel = createViewModel(config, model);
let cursor = new Cursor(config, model, viewModel);
callback(model, cursor);
......
......@@ -33,7 +33,8 @@ suite('Cursor move command test', () => {
thisModel = TextModel.createFromString(text);
thisConfiguration = new TestConfiguration({});
thisViewModel = new ViewModel(0, thisConfiguration, thisModel, MonospaceLineBreaksComputerFactory.create(thisConfiguration.options), null!);
const monospaceLineBreaksComputerFactory = MonospaceLineBreaksComputerFactory.create(thisConfiguration.options);
thisViewModel = new ViewModel(0, thisConfiguration, thisModel, monospaceLineBreaksComputerFactory, monospaceLineBreaksComputerFactory, null!);
thisCursor = new Cursor(thisConfiguration, thisModel, thisViewModel);
});
......
......@@ -19,7 +19,6 @@ import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
suite('Editor ViewModel - SplitLinesCollection', () => {
test('SplitLine', () => {
let model1 = createModel('My First LineMy Second LineAnd another one');
......@@ -95,10 +94,7 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
const wordWrapBreakBeforeCharacters = config.options.get(EditorOption.wordWrapBreakBeforeCharacters);
const wrappingIndent = config.options.get(EditorOption.wrappingIndent);
const lineBreaksComputerFactory = new MonospaceLineBreaksComputerFactory(
wordWrapBreakBeforeCharacters,
wordWrapBreakAfterCharacters
);
const lineBreaksComputerFactory = new MonospaceLineBreaksComputerFactory(wordWrapBreakBeforeCharacters, wordWrapBreakAfterCharacters);
const model = TextModel.createFromString([
'int main() {',
......@@ -112,6 +108,7 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
const linesCollection = new SplitLinesCollection(
model,
lineBreaksComputerFactory,
lineBreaksComputerFactory,
model.getOptions().tabSize,
wrappingInfo.wrappingColumn,
fontInfo.typicalFullwidthCharacterWidth / fontInfo.typicalHalfwidthCharacterWidth,
......@@ -747,14 +744,12 @@ suite('SplitLinesCollection', () => {
const wordWrapBreakBeforeCharacters = configuration.options.get(EditorOption.wordWrapBreakBeforeCharacters);
const wrappingIndent = configuration.options.get(EditorOption.wrappingIndent);
const factory = new MonospaceLineBreaksComputerFactory(
wordWrapBreakBeforeCharacters,
wordWrapBreakAfterCharacters
);
const lineBreaksComputerFactory = new MonospaceLineBreaksComputerFactory(wordWrapBreakBeforeCharacters, wordWrapBreakAfterCharacters);
const linesCollection = new SplitLinesCollection(
model,
factory,
lineBreaksComputerFactory,
lineBreaksComputerFactory,
model.getOptions().tabSize,
wrappingInfo.wrappingColumn,
fontInfo.typicalFullwidthCharacterWidth / fontInfo.typicalHalfwidthCharacterWidth,
......
......@@ -12,11 +12,10 @@ import { MonospaceLineBreaksComputerFactory } from 'vs/editor/common/viewModel/m
export function testViewModel(text: string[], options: IEditorOptions, callback: (viewModel: ViewModel, model: TextModel) => void): void {
const EDITOR_ID = 1;
let configuration = new TestConfiguration(options);
let model = TextModel.createFromString(text.join('\n'));
let viewModel = new ViewModel(EDITOR_ID, configuration, model, MonospaceLineBreaksComputerFactory.create(configuration.options), null!);
const configuration = new TestConfiguration(options);
const model = TextModel.createFromString(text.join('\n'));
const monospaceLineBreaksComputerFactory = MonospaceLineBreaksComputerFactory.create(configuration.options);
const viewModel = new ViewModel(EDITOR_ID, configuration, model, monospaceLineBreaksComputerFactory, monospaceLineBreaksComputerFactory, null!);
callback(viewModel, model);
......
......@@ -2707,6 +2707,11 @@ declare namespace monaco.editor {
* Defaults to 'same' in vscode and to 'none' in monaco-editor.
*/
wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent';
/**
* Controls the wrapping algorithm to use.
* Defaults to 'monospace'.
*/
wrappingAlgorithm?: 'monospace' | 'dom';
/**
* Configure word wrapping characters. A break will be introduced before these characters.
* Defaults to '([{‘“〈《「『【〔([{「£¥$£¥++'.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册