add ability to register/deregister character joiner
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { merge } from './MergeRanges';
|
||||
|
||||
describe('merge', () => {
|
||||
it('inserts a new range before the existing ones', () => {
|
||||
const result = merge([[1, 2], [2, 3]], [0, 1]);
|
||||
assert.deepEqual(result, [[0, 1], [1, 2], [2, 3]]);
|
||||
});
|
||||
|
||||
it('inserts in between two ranges', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [2, 4]);
|
||||
assert.deepEqual(result, [[0, 2], [2, 4], [4, 6]]);
|
||||
});
|
||||
|
||||
it('inserts after the last range', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [6, 8]);
|
||||
assert.deepEqual(result, [[0, 2], [4, 6], [6, 8]]);
|
||||
});
|
||||
|
||||
it('extends the beginning of a range', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [3, 5]);
|
||||
assert.deepEqual(result, [[0, 2], [3, 6]]);
|
||||
});
|
||||
|
||||
it('extends the end of a range', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [1, 4]);
|
||||
assert.deepEqual(result, [[0, 4], [4, 6]]);
|
||||
});
|
||||
|
||||
it('extends the last range', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [5, 7]);
|
||||
assert.deepEqual(result, [[0, 2], [4, 7]]);
|
||||
});
|
||||
|
||||
it('connects two ranges', () => {
|
||||
const result = merge([[0, 2], [4, 6]], [1, 5]);
|
||||
assert.deepEqual(result, [[0, 6]]);
|
||||
});
|
||||
|
||||
it('connects more than two ranges', () => {
|
||||
const result = merge([[0, 2], [4, 6], [8, 10], [12, 14]], [1, 10]);
|
||||
assert.deepEqual(result, [[0, 10], [12, 14]]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Merges the range defined by the provided start and end into the list of
|
||||
* existing ranges. The merge is done in place on the existing range for
|
||||
* performance and is also returned.
|
||||
* @param ranges Existing range list
|
||||
* @param newRange Tuple of two numbers representing the new range to merge in.
|
||||
* @returns The ranges input with the new range merged in place
|
||||
*/
|
||||
export function merge(ranges: [number, number][], newRange: [number, number]): [number, number][] {
|
||||
let inRange = false;
|
||||
for (let i = 0; i < ranges.length; i++) {
|
||||
const range = ranges[i];
|
||||
if (!inRange) {
|
||||
if (newRange[1] <= range[0]) {
|
||||
// Case 1: New range is before the search range
|
||||
ranges.splice(i, 0, newRange);
|
||||
return ranges;
|
||||
}
|
||||
|
||||
if (newRange[1] <= range[1]) {
|
||||
// Case 2: New range is either wholly contained within the
|
||||
// search range or overlaps with the front of it
|
||||
range[0] = Math.min(newRange[0], range[0]);
|
||||
return ranges;
|
||||
}
|
||||
|
||||
if (newRange[0] < range[1]) {
|
||||
// Case 3: New range either wholly contains the search range
|
||||
// or overlaps with the end of it
|
||||
range[0] = Math.min(newRange[0], range[0]);
|
||||
inRange = true;
|
||||
}
|
||||
|
||||
// Case 4: New range starts after the search range
|
||||
continue;
|
||||
} else {
|
||||
if (newRange[1] <= range[0]) {
|
||||
// Case 5: New range extends from previous range but doesn't
|
||||
// reach the current one
|
||||
ranges[i - 1][1] = newRange[1];
|
||||
return ranges;
|
||||
}
|
||||
|
||||
if (newRange[1] <= range[1]) {
|
||||
// Case 6: New range extends from prvious range into the
|
||||
// current range
|
||||
ranges[i - 1][1] = Math.max(newRange[1], range[1]);
|
||||
ranges.splice(i, 1);
|
||||
inRange = false;
|
||||
return ranges;
|
||||
}
|
||||
|
||||
// Case 7: New range extends from previous range past the
|
||||
// end of the current range
|
||||
ranges.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (inRange) {
|
||||
// Case 8: New range extends past the last existing range
|
||||
ranges[ranges.length - 1][1] = newRange[1];
|
||||
} else {
|
||||
// Case 9: New range starts after the last existing range
|
||||
ranges.push(newRange);
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types';
|
||||
import { LineData, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener } from '../Types';
|
||||
import { LineData, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener, CharacterJoinerHandler } from '../Types';
|
||||
import { Buffer } from '../Buffer';
|
||||
import * as Browser from '../shared/utils/Browser';
|
||||
import { ITheme, IDisposable, IMarker } from 'xterm';
|
||||
@@ -157,6 +157,8 @@ export class MockTerminal implements ITerminal {
|
||||
}
|
||||
return line;
|
||||
}
|
||||
registerCharacterJoiner(handler: CharacterJoinerHandler): number { return 0; }
|
||||
deregisterCharacterJoiner(joinerId: number): void { }
|
||||
}
|
||||
|
||||
export class MockCharMeasure implements ICharMeasure {
|
||||
@@ -339,6 +341,8 @@ export class MockRenderer implements IRenderer {
|
||||
onWindowResize(devicePixelRatio: number): void {}
|
||||
clear(): void {}
|
||||
refreshRows(start: number, end: number): void {}
|
||||
registerCharacterJoiner(handler: CharacterJoinerHandler): number { return 0; }
|
||||
deregisterCharacterJoiner(): boolean { return true; }
|
||||
}
|
||||
|
||||
export class MockViewport implements IViewport {
|
||||
|
||||
Reference in New Issue
Block a user