Skip to content

Commit

Permalink
start work on #95077
Browse files Browse the repository at this point in the history
  • Loading branch information
meganrogge committed May 19, 2021
1 parent 8c27c1f commit 5b01900
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import type { Terminal, IViewportRange } from 'xterm';
import type { Terminal, IViewportRange, IBufferLine } from 'xterm';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalConfiguration, TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalLink } from 'vs/workbench/contrib/terminal/browser/links/terminalLink';
Expand Down Expand Up @@ -36,56 +36,72 @@ export class TerminalWordLinkProvider extends TerminalBaseLinkProvider {
}

protected _provideLinks(y: number): TerminalLink[] {
// TODO: Support wrapping
// Dispose of all old links if new links are provides, links are only cached for the current line
// Dispose of all old links if new links are provided, links are only cached for the current line
const result: TerminalLink[] = [];
const wordSeparators = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION).wordSeparators;
const activateCallback = this._wrapLinkHandler((_, link) => this._activate(link));

const line = this._xterm.buffer.active.getLine(y - 1)!;
let startLine = y - 1;
let endLine = y;
let text = '';
let startX = -1;
const cellData = line.getCell(0)!;
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 (width !== 0 && wordSeparators.indexOf(chars) >= 0) {
if (startX !== -1) {
result.push(this._createTerminalLink(startX, x, y, text, activateCallback));
text = '';
startX = -1;
const lines: IBufferLine[] = [
this._xterm.buffer.active.getLine(startLine)!
];
while (startLine >= 0 && this._xterm.buffer.active.getLine(startLine)?.isWrapped) {
lines.unshift(this._xterm.buffer.active.getLine(startLine - 1)!);
startLine--;
}

while (endLine < this._xterm.buffer.active.length && this._xterm.buffer.active.getLine(endLine + 1)?.isWrapped) {
lines.push(this._xterm.buffer.active.getLine(endLine + 1)!);
endLine++;
}

for (let i = startLine; i < endLine; i++) {
let line = this._xterm.buffer.active.getLine(i)!;
let cellData = line.getCell(0)!;
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 (width !== 0 && wordSeparators.indexOf(chars) >= 0 && i === endLine - 1) {
if (startX !== -1) {
result.push(this._createTerminalLink(startX, x, endLine, text, activateCallback));
text = '';
startX = -1;
}
continue;
}
continue;
}

// Mark the start of a link if it hasn't started yet
if (startX === -1) {
startX = x;
}
// Mark the start of a link if it hasn't started yet
if (startX === -1) {
startX = x;
}

text += chars;
}
text += chars;
}

// Add the final link if there is one
if (startX !== -1) {
result.push(this._createTerminalLink(startX, line.length, y, text, activateCallback));
// Add the final link if there is one
if (startX !== -1 && i === endLine - 1) {
result.push(this._createTerminalLink(startX, line.length, startLine, text, activateCallback, endLine));
}
}

return result;
}

private _createTerminalLink(startX: number, endX: number, y: number, text: string, activateCallback: XtermLinkMatcherHandler): TerminalLink {
private _createTerminalLink(startX: number, endX: number, y: number, text: string, activateCallback: XtermLinkMatcherHandler, endLine?: number): TerminalLink {
// Remove trailing colon if there is one so the link is more useful
if (text.length > 0 && text.charAt(text.length - 1) === ':') {
text = text.slice(0, -1);
endX--;
}
endLine = endLine ? endLine : y;
return this._instantiationService.createInstance(TerminalLink,
this._xterm,
{ start: { x: startX + 1, y }, end: { x: endX, y } },
{ start: { x: startX + 1, y }, end: { x: endX, y: endLine } },
text,
this._xterm.buffer.active.viewportY,
activateCallback,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ suite('Workbench - TerminalWordLinkProvider', () => {

// Ensure all links are provided
const links = (await new Promise<ILink[] | undefined>(r => provider.provideLinks(1, r)))!;
assert.strictEqual(links.length, expected.length);
const actual = links.map(e => ({
text: e.text,
range: e.range
Expand All @@ -43,6 +42,7 @@ suite('Workbench - TerminalWordLinkProvider', () => {
}
}));
assert.deepStrictEqual(actual, expectedVerbose);
assert.strictEqual(links.length, expected.length);
}

test('should link words as defined by wordSeparators', async () => {
Expand Down Expand Up @@ -88,4 +88,10 @@ suite('Workbench - TerminalWordLinkProvider', () => {
]);
});

test('should support wrapping', async () => {
await configurationService.setUserConfiguration('terminal', { integrated: { wordSeparators: ' ' } });
await assertLink('fsdjfsdkfjslkdfjskdfjsldkfjsdlkfjslkdjfskldjflskdfjskldjflskdfjsdklfjsdklfjsldkfjsdlkfjsdlkfjsdlkfjsldkfjslkdfjsdlkfjsldkfjsdlkfjskdfjsldkfjsdlkfjslkdfjsdlkfjsldkfjsldkfjsldkfjslkdfjsdlkfjslkdfjsdklfsd', [
{ range: [[1, 1], [41, 3]], text: 'fsdjfsdkfjslkdfjskdfjsldkfjsdlkfjslkdjfskldjflskdfjskldjflskdfjsdklfjsdklfjsldkfjsdlkfjsdlkfjsdlkfjsldkfjslkdfjsdlkfjsldkfjsdlkfjskdfjsldkfjsdlkfjslkdfjsdlkfjsldkfjsldkfjsldkfjslkdfjsdlkfjslkdfjsdklfsd' },
]);
});
});

0 comments on commit 5b01900

Please sign in to comment.