提交 eadda7cd 编写于 作者: A Alex Dima

Fixes #41492: Add collapseOnReplaceEdit decoration option

上级 141f0554
......@@ -77,6 +77,11 @@ export interface IModelDecorationOptions {
* @internal
*/
showIfCollapsed?: boolean;
/**
* Collapse the decoration if its entire range is being replaced via an edit.
* @internal
*/
collapseOnReplaceEdit?: boolean;
/**
* Specifies the stack order of a decoration.
* A decoration with greater stack order is always in front of a decoration with a lower stack order.
......
......@@ -58,6 +58,10 @@ const enum Constants {
StickinessMaskInverse = 0b11001111,
StickinessOffset = 4,
CollapseOnReplaceEditMask = 0b01000000,
CollapseOnReplaceEditMaskInverse = 0b10111111,
CollapseOnReplaceEditOffset = 6,
/**
* Due to how deletion works (in order to avoid always walking the right subtree of the deleted node),
* the deltas for nodes can grow and shrink dramatically. It has been observed, in practice, that unless
......@@ -121,6 +125,14 @@ function _setNodeStickiness(node: IntervalNode, stickiness: TrackedRangeStickine
(node.metadata & Constants.StickinessMaskInverse) | (stickiness << Constants.StickinessOffset)
);
}
function getCollapseOnReplaceEdit(node: IntervalNode): boolean {
return ((node.metadata & Constants.CollapseOnReplaceEditMask) >>> Constants.CollapseOnReplaceEditOffset) === 1;
}
function setCollapseOnReplaceEdit(node: IntervalNode, value: boolean): void {
node.metadata = (
(node.metadata & Constants.CollapseOnReplaceEditMaskInverse) | ((value ? 1 : 0) << Constants.CollapseOnReplaceEditOffset)
);
}
export function setNodeStickiness(node: IntervalNode, stickiness: ActualTrackedRangeStickiness): void {
_setNodeStickiness(node, <number>stickiness);
}
......@@ -170,6 +182,7 @@ export class IntervalNode implements IModelDecoration {
setNodeIsForValidation(this, false);
_setNodeStickiness(this, TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges);
setNodeIsInOverviewRuler(this, false);
setCollapseOnReplaceEdit(this, false);
this.cachedVersionId = 0;
this.cachedAbsoluteStart = start;
......@@ -199,6 +212,7 @@ export class IntervalNode implements IModelDecoration {
));
_setNodeStickiness(this, <number>this.options.stickiness);
setNodeIsInOverviewRuler(this, (this.options.overviewRuler && this.options.overviewRuler.color) ? true : false);
setCollapseOnReplaceEdit(this, this.options.collapseOnReplaceEdit);
}
public setCachedOffsets(absoluteStart: number, absoluteEnd: number, cachedVersionId: number): void {
......@@ -417,6 +431,15 @@ export function nodeAcceptEdit(node: IntervalNode, start: number, end: number, t
const nodeEnd = node.end;
let endDone = false;
if (start <= nodeStart && nodeEnd <= end && getCollapseOnReplaceEdit(node)) {
// This edit encompasses the entire decoration range
// and the decoration has asked to become collapsed
node.start = start;
startDone = true;
node.end = start;
endDone = true;
}
{
const moveSemantics = forceMoveMarkers ? MarkerMoveSemantics.ForceMove : (deletingCnt > 0 ? MarkerMoveSemantics.ForceStay : MarkerMoveSemantics.MarkerDefined);
if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, start, moveSemantics)) {
......
......@@ -2839,6 +2839,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
readonly glyphMarginHoverMessage: IMarkdownString | IMarkdownString[];
readonly isWholeLine: boolean;
readonly showIfCollapsed: boolean;
readonly collapseOnReplaceEdit: boolean;
readonly overviewRuler: ModelDecorationOverviewRulerOptions;
readonly glyphMarginClassName: string;
readonly linesDecorationsClassName: string;
......@@ -2856,6 +2857,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
this.glyphMarginHoverMessage = options.glyphMarginHoverMessage || null;
this.isWholeLine = options.isWholeLine || false;
this.showIfCollapsed = options.showIfCollapsed || false;
this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
this.overviewRuler = options.overviewRuler ? new ModelDecorationOverviewRulerOptions(options.overviewRuler) : null;
this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null;
this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null;
......
......@@ -54,41 +54,49 @@ const HOVER_MESSAGE_COMMAND_ALT = new MarkdownString().appendText(
const decoration = {
meta: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link',
hoverMessage: HOVER_MESSAGE_GENERAL_META
}),
metaActive: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link-active',
hoverMessage: HOVER_MESSAGE_GENERAL_META
}),
alt: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link',
hoverMessage: HOVER_MESSAGE_GENERAL_ALT
}),
altActive: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link-active',
hoverMessage: HOVER_MESSAGE_GENERAL_ALT
}),
altCommand: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link',
hoverMessage: HOVER_MESSAGE_COMMAND_ALT
}),
altCommandActive: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link-active',
hoverMessage: HOVER_MESSAGE_COMMAND_ALT
}),
metaCommand: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link',
hoverMessage: HOVER_MESSAGE_COMMAND_META
}),
metaCommandActive: ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
collapseOnReplaceEdit: true,
inlineClassName: 'detected-link-active',
hoverMessage: HOVER_MESSAGE_COMMAND_META
}),
......
......@@ -1370,4 +1370,22 @@ suite('deltaDecorations', () => {
model.dispose();
});
test('issue #41492: URL highlighting persists after pasting over url', () => {
let model = TextModel.createFromString([
'My First Line'
].join('\n'));
const id = model.deltaDecorations([], [{ range: new Range(1, 2, 1, 14), options: { stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, collapseOnReplaceEdit: true } }])[0];
model.applyEdits([{
range: new Range(1, 1, 1, 14),
text: 'Some new text that is longer than the previous one',
forceMoveMarkers: false
}]);
const actual = model.getDecorationRange(id);
assert.deepEqual(actual, new Range(1, 1, 1, 1));
model.dispose();
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册