OSC link progress

This commit is contained in:
Daniel Imms
2022-08-07 05:08:13 -07:00
parent c021571194
commit 91d46dae50
9 changed files with 237 additions and 15 deletions
+72
View File
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2022 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { ILink, ILinkProvider } from 'browser/Types';
import { CellData } from 'common/buffer/CellData';
import { IBufferService, IOscLinkService } from 'common/services/Services';
export class OscLinkProvider implements ILinkProvider {
constructor(
@IBufferService private readonly _bufferService: IBufferService,
@IOscLinkService private readonly _oscLinkService: IOscLinkService
) {
}
public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {
const line = this._bufferService.buffer.lines.get(y - 1);
if (!line) {
callback(undefined);
return;
}
const result: ILink[] = [];
const cell = new CellData();
const lineLength = line.getTrimmedLength();
let currentLinkId = -1;
let currentStart = -1;
let finishLink = false;
for (let x = 0; x < lineLength; x++) {
if (!line.hasContent(x)) {
continue;
}
line.loadCell(x, cell);
if (cell.extended.urlId) {
if (currentStart === -1) {
currentStart = x;
currentLinkId = cell.extended.urlId;
continue;
} else {
finishLink = cell.extended.urlId !== currentLinkId;
}
} else {
if (currentStart !== -1) {
finishLink = true;
}
}
if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {
const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;
if (text) {
// OSC links always use underline and pointer decorations
result.push({
text,
// These ranges are 1-based
range: {
start: { x: currentStart + 1, y },
end: { x: x + 1, y }
},
activate(e, text) {
console.log('activate!', text);
}
// TODO: Embedder API to handle hover
});
}
}
}
// TODO: Handle fetching and returning other link ranges to underline other links with the same id
callback(result);
}
}
+2
View File
@@ -55,6 +55,7 @@ import { BufferDecorationRenderer } from 'browser/decorations/BufferDecorationRe
import { OverviewRulerRenderer } from 'browser/decorations/OverviewRulerRenderer';
import { DecorationService } from 'common/services/DecorationService';
import { IDecorationService } from 'common/services/Services';
import { OscLinkProvider } from 'browser/OscLinkProvider';
// Let it work inside Node.js for automated testing purposes.
const document: Document = (typeof window !== 'undefined') ? window.document : null as any;
@@ -163,6 +164,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
this._setup();
this.linkifier2 = this.register(this._instantiationService.createInstance(Linkifier2));
this.linkifier2.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
this._decorationService = this._instantiationService.createInstance(DecorationService);
this._instantiationService.setService(IDecorationService, this._decorationService);