Fix wide word links and tests

This commit is contained in:
Daniel Imms 2020-05-06 09:51:14 -07:00
parent 46e54a24b5
commit b8ec024d40
2 changed files with 37 additions and 50 deletions

View file

@ -48,9 +48,10 @@ export class TerminalWordLinkProvider extends TerminalBaseLinkProvider {
for (let x = 0; x < line.length; x++) {
line.getCell(x, cellData);
const chars = cellData.getChars();
const width = cellData.getWidth();
// Add a link if this is a separator
if (wordSeparators.indexOf(chars) >= 0) {
if (width !== 0 && wordSeparators.indexOf(chars) >= 0) {
if (startX !== -1) {
result.push(new TerminalLink({ start: { x: startX + 1, y }, end: { x, y } }, text, this._xterm.buffer.active.viewportY, activateCallback, this._tooltipCallback, false, localize('searchWorkspace', 'Search workspace'), this._configurationService));
text = '';

View file

@ -10,7 +10,7 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
suite('Workbench - TerminalWordLinkProvider', () => {
suite.only('Workbench - TerminalWordLinkProvider', () => {
let instantiationService: TestInstantiationService;
let configurationService: TestConfigurationService;
@ -21,68 +21,54 @@ suite('Workbench - TerminalWordLinkProvider', () => {
instantiationService.stub(IConfigurationService, configurationService);
});
async function assertLink(text: string, expected: { text: string, range: [number, number][] }) {
async function assertLink2(text: string, expected: { text: string, range: [number, number][] }[]) {
const xterm = new Terminal();
const provider = instantiationService.createInstance(TerminalWordLinkProvider, xterm, () => { }, () => { });
const provider: TerminalWordLinkProvider = instantiationService.createInstance(TerminalWordLinkProvider, xterm, () => { }, () => { });
// Write the text and wait for the parser to finish
await new Promise<void>(r => xterm.write(text, r));
// Calculate positions just outside of link boundaries
const noLinkPositions: IBufferCellPosition[] = [
{ x: expected.range[0][0] - 1, y: expected.range[0][1] },
{ x: expected.range[1][0] + 1, y: expected.range[1][1] }
];
// Ensure outside positions do not detect the link
for (let i = 0; i < noLinkPositions.length; i++) {
const link = await new Promise<ILink | undefined>(r => provider.provideLink(noLinkPositions[i], r));
assert.equal(link, undefined, `Just outside range boundary should not result in link, link found at (${link?.range.start.x}, ${link?.range.start.y}) to (${link?.range.end.x}, ${link?.range.end.y}) while checking (${noLinkPositions[i].x}, ${noLinkPositions[i].y})\nExpected link text=${expected.text}\nActual link text=${link?.text}`);
}
// Convert range from [[startx, starty], [endx, endy]] to an IBufferRange
const linkRange: IBufferRange = {
start: { x: expected.range[0][0], y: expected.range[0][1] },
end: { x: expected.range[1][0], y: expected.range[1][1] },
};
// Calculate positions inside the link boundaries
const linkPositions: IBufferCellPosition[] = [
linkRange.start,
linkRange.end
];
// Ensure inside positions do detect the link
for (let i = 0; i < linkPositions.length; i++) {
const link = await new Promise<ILink | undefined>(r => provider.provideLink(linkPositions[i], r));
assert.deepEqual(link?.text, expected.text);
assert.deepEqual(link?.range, linkRange);
}
// Ensure all links are provided
const links = (await new Promise<ILink[] | undefined>(r => provider.provideLinks(1, r)))!;
assert.equal(links.length, expected.length);
const actual = links.map(e => ({
text: e.text,
range: e.range
}));
const expectedVerbose = expected.map(e => ({
text: e.text,
range: {
start: { x: e.range[0][0], y: e.range[0][1] },
end: { x: e.range[1][0], y: e.range[1][1] },
}
}));
assert.deepEqual(actual, expectedVerbose);
}
test('should link words as defined by wordSeparators', async () => {
await configurationService.setUserConfiguration('terminal', { integrated: { wordSeparators: ' ()[]' } });
await assertLink('foo', { range: [[1, 1], [3, 1]], text: 'foo' });
await assertLink(' foo ', { range: [[2, 1], [4, 1]], text: 'foo' });
await assertLink('(foo)', { range: [[2, 1], [4, 1]], text: 'foo' });
await assertLink('[foo]', { range: [[2, 1], [4, 1]], text: 'foo' });
await assertLink('{foo}', { range: [[1, 1], [5, 1]], text: '{foo}' });
await assertLink2('foo', [{ range: [[1, 1], [3, 1]], text: 'foo' }]);
await assertLink2('foo', [{ range: [[1, 1], [3, 1]], text: 'foo' }]);
await assertLink2(' foo ', [{ range: [[2, 1], [4, 1]], text: 'foo' }]);
await assertLink2('(foo)', [{ range: [[2, 1], [4, 1]], text: 'foo' }]);
await assertLink2('[foo]', [{ range: [[2, 1], [4, 1]], text: 'foo' }]);
await assertLink2('{foo}', [{ range: [[1, 1], [5, 1]], text: '{foo}' }]);
await configurationService.setUserConfiguration('terminal', { integrated: { wordSeparators: ' ' } });
await assertLink('foo', { range: [[1, 1], [3, 1]], text: 'foo' });
await assertLink(' foo ', { range: [[2, 1], [4, 1]], text: 'foo' });
await assertLink('(foo)', { range: [[1, 1], [5, 1]], text: '(foo)' });
await assertLink('[foo]', { range: [[1, 1], [5, 1]], text: '[foo]' });
await assertLink('{foo}', { range: [[1, 1], [5, 1]], text: '{foo}' });
await assertLink2('foo', [{ range: [[1, 1], [3, 1]], text: 'foo' }]);
await assertLink2(' foo ', [{ range: [[2, 1], [4, 1]], text: 'foo' }]);
await assertLink2('(foo)', [{ range: [[1, 1], [5, 1]], text: '(foo)' }]);
await assertLink2('[foo]', [{ range: [[1, 1], [5, 1]], text: '[foo]' }]);
await assertLink2('{foo}', [{ range: [[1, 1], [5, 1]], text: '{foo}' }]);
});
test('should support wide characters', async () => {
await configurationService.setUserConfiguration('terminal', { integrated: { wordSeparators: ' []' } });
await assertLink('aabbccdd.txt ', { range: [[1, 1], [12, 1]], text: 'aabbccdd.txt' });
await assertLink('我是学生.txt ', { range: [[1, 1], [12, 1]], text: '我是学生.txt' });
await assertLink(' aabbccdd.txt ', { range: [[2, 1], [13, 1]], text: 'aabbccdd.txt' });
await assertLink(' 我是学生.txt ', { range: [[2, 1], [13, 1]], text: '我是学生.txt' });
await assertLink(' [aabbccdd.txt] ', { range: [[3, 1], [14, 1]], text: 'aabbccdd.txt' });
await assertLink(' [我是学生.txt] ', { range: [[3, 1], [14, 1]], text: '我是学生.txt' });
await assertLink2('aabbccdd.txt ', [{ range: [[1, 1], [12, 1]], text: 'aabbccdd.txt' }]);
await assertLink2('我是学生.txt ', [{ range: [[1, 1], [12, 1]], text: '我是学生.txt' }]);
await assertLink2(' aabbccdd.txt ', [{ range: [[2, 1], [13, 1]], text: 'aabbccdd.txt' }]);
await assertLink2(' 我是学生.txt ', [{ range: [[2, 1], [13, 1]], text: '我是学生.txt' }]);
await assertLink2(' [aabbccdd.txt] ', [{ range: [[3, 1], [14, 1]], text: 'aabbccdd.txt' }]);
await assertLink2(' [我是学生.txt] ', [{ range: [[3, 1], [14, 1]], text: '我是学生.txt' }]);
});
});