@xterm/xterm 5.4.0-beta.20 → 5.4.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/package.json +1 -1
- package/src/browser/{Linkifier2.ts → Linkifier.ts} +34 -62
- package/src/browser/OscLinkProvider.ts +2 -1
- package/src/browser/Terminal.ts +19 -13
- package/src/browser/Types.d.ts +1 -9
- package/src/browser/services/LinkProviderService.ts +28 -0
- package/src/browser/services/Services.ts +12 -1
- package/src/common/CoreTerminal.ts +1 -0
package/package.json
CHANGED
|
@@ -4,18 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { addDisposableDomListener } from 'browser/Lifecycle';
|
|
7
|
-
import { IBufferCellPosition, ILink, ILinkDecorations,
|
|
7
|
+
import { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from 'browser/Types';
|
|
8
8
|
import { EventEmitter } from 'common/EventEmitter';
|
|
9
9
|
import { Disposable, disposeArray, getDisposeArrayDisposable, toDisposable } from 'common/Lifecycle';
|
|
10
10
|
import { IDisposable } from 'common/Types';
|
|
11
11
|
import { IBufferService } from 'common/services/Services';
|
|
12
|
-
import { IMouseService, IRenderService } from './services/Services';
|
|
12
|
+
import { ILinkProviderService, IMouseService, IRenderService } from './services/Services';
|
|
13
13
|
|
|
14
|
-
export class
|
|
15
|
-
private _element: HTMLElement | undefined;
|
|
16
|
-
private _mouseService: IMouseService | undefined;
|
|
17
|
-
private _renderService: IRenderService | undefined;
|
|
18
|
-
private _linkProviders: ILinkProvider[] = [];
|
|
14
|
+
export class Linkifier extends Disposable implements ILinkifier2 {
|
|
19
15
|
public get currentLink(): ILinkWithState | undefined { return this._currentLink; }
|
|
20
16
|
protected _currentLink: ILinkWithState | undefined;
|
|
21
17
|
private _mouseDownLink: ILinkWithState | undefined;
|
|
@@ -33,14 +29,17 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
33
29
|
public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;
|
|
34
30
|
|
|
35
31
|
constructor(
|
|
36
|
-
|
|
32
|
+
private readonly _element: HTMLElement,
|
|
33
|
+
@IMouseService private readonly _mouseService: IMouseService,
|
|
34
|
+
@IRenderService private readonly _renderService: IRenderService,
|
|
35
|
+
@IBufferService private readonly _bufferService: IBufferService,
|
|
36
|
+
@ILinkProviderService private readonly _linkProviderService: ILinkProviderService
|
|
37
37
|
) {
|
|
38
38
|
super();
|
|
39
39
|
this.register(getDisposeArrayDisposable(this._linkCacheDisposables));
|
|
40
40
|
this.register(toDisposable(() => {
|
|
41
41
|
this._lastMouseEvent = undefined;
|
|
42
42
|
// Clear out link providers as they could easily cause an embedder memory leak
|
|
43
|
-
this._linkProviders.length = 0;
|
|
44
43
|
this._activeProviderReplies?.clear();
|
|
45
44
|
}));
|
|
46
45
|
// Listen to resize to catch the case where it's resized and the cursor is out of the viewport.
|
|
@@ -48,27 +47,6 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
48
47
|
this._clearCurrentLink();
|
|
49
48
|
this._wasResized = true;
|
|
50
49
|
}));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
|
|
54
|
-
this._linkProviders.push(linkProvider);
|
|
55
|
-
return {
|
|
56
|
-
dispose: () => {
|
|
57
|
-
// Remove the link provider from the list
|
|
58
|
-
const providerIndex = this._linkProviders.indexOf(linkProvider);
|
|
59
|
-
|
|
60
|
-
if (providerIndex !== -1) {
|
|
61
|
-
this._linkProviders.splice(providerIndex, 1);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public attachToDom(element: HTMLElement, mouseService: IMouseService, renderService: IRenderService): void {
|
|
68
|
-
this._element = element;
|
|
69
|
-
this._mouseService = mouseService;
|
|
70
|
-
this._renderService = renderService;
|
|
71
|
-
|
|
72
50
|
this.register(addDisposableDomListener(this._element, 'mouseleave', () => {
|
|
73
51
|
this._isMouseOut = true;
|
|
74
52
|
this._clearCurrentLink();
|
|
@@ -81,10 +59,6 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
81
59
|
private _handleMouseMove(event: MouseEvent): void {
|
|
82
60
|
this._lastMouseEvent = event;
|
|
83
61
|
|
|
84
|
-
if (!this._element || !this._mouseService) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
62
|
const position = this._positionFromMouseEvent(event, this._element, this._mouseService);
|
|
89
63
|
if (!position) {
|
|
90
64
|
return;
|
|
@@ -145,7 +119,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
145
119
|
let linkProvided = false;
|
|
146
120
|
|
|
147
121
|
// There is no link cached, so ask for one
|
|
148
|
-
for (const [i, linkProvider] of this.
|
|
122
|
+
for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {
|
|
149
123
|
if (useLineCache) {
|
|
150
124
|
const existingReply = this._activeProviderReplies?.get(i);
|
|
151
125
|
// If there isn't a reply, the provider hasn't responded yet.
|
|
@@ -167,7 +141,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
167
141
|
|
|
168
142
|
// If all providers have responded, remove lower priority links that intersect ranges of
|
|
169
143
|
// higher priority links
|
|
170
|
-
if (this._activeProviderReplies?.size === this.
|
|
144
|
+
if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {
|
|
171
145
|
this._removeIntersectingLinks(position.y, this._activeProviderReplies);
|
|
172
146
|
}
|
|
173
147
|
});
|
|
@@ -223,7 +197,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
223
197
|
}
|
|
224
198
|
|
|
225
199
|
// Check if all the providers have responded
|
|
226
|
-
if (this._activeProviderReplies.size === this.
|
|
200
|
+
if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {
|
|
227
201
|
// Respect the order of the link providers
|
|
228
202
|
for (let j = 0; j < this._activeProviderReplies.size; j++) {
|
|
229
203
|
const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));
|
|
@@ -243,7 +217,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
243
217
|
}
|
|
244
218
|
|
|
245
219
|
private _handleMouseUp(event: MouseEvent): void {
|
|
246
|
-
if (!this.
|
|
220
|
+
if (!this._currentLink) {
|
|
247
221
|
return;
|
|
248
222
|
}
|
|
249
223
|
|
|
@@ -258,7 +232,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
258
232
|
}
|
|
259
233
|
|
|
260
234
|
private _clearCurrentLink(startRow?: number, endRow?: number): void {
|
|
261
|
-
if (!this.
|
|
235
|
+
if (!this._currentLink || !this._lastMouseEvent) {
|
|
262
236
|
return;
|
|
263
237
|
}
|
|
264
238
|
|
|
@@ -271,7 +245,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
271
245
|
}
|
|
272
246
|
|
|
273
247
|
private _handleNewLink(linkWithState: ILinkWithState): void {
|
|
274
|
-
if (!this.
|
|
248
|
+
if (!this._lastMouseEvent) {
|
|
275
249
|
return;
|
|
276
250
|
}
|
|
277
251
|
|
|
@@ -302,7 +276,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
302
276
|
if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {
|
|
303
277
|
this._currentLink.state.decorations.pointerCursor = v;
|
|
304
278
|
if (this._currentLink.state.isHovered) {
|
|
305
|
-
this._element
|
|
279
|
+
this._element.classList.toggle('xterm-cursor-pointer', v);
|
|
306
280
|
}
|
|
307
281
|
}
|
|
308
282
|
}
|
|
@@ -322,29 +296,27 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
|
|
322
296
|
|
|
323
297
|
// Listen to viewport changes to re-render the link under the cursor (only when the line the
|
|
324
298
|
// link is on changes)
|
|
325
|
-
|
|
326
|
-
this
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
this._askForLink(position, false);
|
|
343
|
-
}
|
|
299
|
+
this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {
|
|
300
|
+
// Sanity check, this shouldn't happen in practice as this listener would be disposed
|
|
301
|
+
if (!this._currentLink) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// When start is 0 a scroll most likely occurred, make sure links above the fold also get
|
|
305
|
+
// cleared.
|
|
306
|
+
const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;
|
|
307
|
+
const end = this._bufferService.buffer.ydisp + 1 + e.end;
|
|
308
|
+
// Only clear the link if the viewport change happened on this line
|
|
309
|
+
if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {
|
|
310
|
+
this._clearCurrentLink(start, end);
|
|
311
|
+
if (this._lastMouseEvent) {
|
|
312
|
+
// re-eval previously active link after changes
|
|
313
|
+
const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element, this._mouseService!);
|
|
314
|
+
if (position) {
|
|
315
|
+
this._askForLink(position, false);
|
|
344
316
|
}
|
|
345
317
|
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
318
|
+
}
|
|
319
|
+
}));
|
|
348
320
|
}
|
|
349
321
|
}
|
|
350
322
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IBufferRange, ILink
|
|
6
|
+
import { IBufferRange, ILink } from 'browser/Types';
|
|
7
|
+
import { ILinkProvider } from 'browser/services/Services';
|
|
7
8
|
import { CellData } from 'common/buffer/CellData';
|
|
8
9
|
import { IBufferService, IOptionsService, IOscLinkService } from 'common/services/Services';
|
|
9
10
|
|
package/src/browser/Terminal.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from 'browser/Clipboard';
|
|
25
25
|
import { addDisposableDomListener } from 'browser/Lifecycle';
|
|
26
|
-
import {
|
|
26
|
+
import { Linkifier } from './Linkifier';
|
|
27
27
|
import * as Strings from 'browser/LocalizableStrings';
|
|
28
28
|
import { OscLinkProvider } from 'browser/OscLinkProvider';
|
|
29
29
|
import { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal, IViewport } from 'browser/Types';
|
|
@@ -39,7 +39,7 @@ import { CoreBrowserService } from 'browser/services/CoreBrowserService';
|
|
|
39
39
|
import { MouseService } from 'browser/services/MouseService';
|
|
40
40
|
import { RenderService } from 'browser/services/RenderService';
|
|
41
41
|
import { SelectionService } from 'browser/services/SelectionService';
|
|
42
|
-
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
|
|
42
|
+
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, ILinkProviderService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
|
|
43
43
|
import { ThemeService } from 'browser/services/ThemeService';
|
|
44
44
|
import { color, rgba } from 'common/Color';
|
|
45
45
|
import { CoreTerminal } from 'common/CoreTerminal';
|
|
@@ -57,6 +57,7 @@ import { IDecorationService } from 'common/services/Services';
|
|
|
57
57
|
import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker } from '@xterm/xterm';
|
|
58
58
|
import { WindowsOptionsReportType } from '../common/InputHandler';
|
|
59
59
|
import { AccessibilityManager } from './AccessibilityManager';
|
|
60
|
+
import { LinkProviderService } from 'browser/services/LinkProviderService';
|
|
60
61
|
|
|
61
62
|
export class Terminal extends CoreTerminal implements ITerminal {
|
|
62
63
|
public textarea: HTMLTextAreaElement | undefined;
|
|
@@ -69,6 +70,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
69
70
|
private _helperContainer: HTMLElement | undefined;
|
|
70
71
|
private _compositionView: HTMLElement | undefined;
|
|
71
72
|
|
|
73
|
+
public linkifier: ILinkifier2 | undefined;
|
|
72
74
|
private _overviewRulerRenderer: OverviewRulerRenderer | undefined;
|
|
73
75
|
|
|
74
76
|
public browser: IBrowser = Browser as any;
|
|
@@ -76,8 +78,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
76
78
|
private _customKeyEventHandler: CustomKeyEventHandler | undefined;
|
|
77
79
|
private _customWheelEventHandler: CustomWheelEventHandler | undefined;
|
|
78
80
|
|
|
79
|
-
//
|
|
81
|
+
// Browser services
|
|
80
82
|
private _decorationService: DecorationService;
|
|
83
|
+
private _linkProviderService: ILinkProviderService;
|
|
84
|
+
|
|
85
|
+
// Optional browser services
|
|
81
86
|
private _charSizeService: ICharSizeService | undefined;
|
|
82
87
|
private _coreBrowserService: ICoreBrowserService | undefined;
|
|
83
88
|
private _mouseService: IMouseService | undefined;
|
|
@@ -113,7 +118,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
113
118
|
*/
|
|
114
119
|
private _unprocessedDeadKey: boolean = false;
|
|
115
120
|
|
|
116
|
-
public linkifier2: ILinkifier2;
|
|
117
121
|
public viewport: IViewport | undefined;
|
|
118
122
|
private _compositionHelper: ICompositionHelper | undefined;
|
|
119
123
|
private _accessibilityManager: MutableDisposable<AccessibilityManager> = this.register(new MutableDisposable());
|
|
@@ -149,10 +153,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
149
153
|
|
|
150
154
|
this._setup();
|
|
151
155
|
|
|
152
|
-
this.linkifier2 = this.register(this._instantiationService.createInstance(Linkifier2));
|
|
153
|
-
this.linkifier2.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
|
|
154
156
|
this._decorationService = this._instantiationService.createInstance(DecorationService);
|
|
155
157
|
this._instantiationService.setService(IDecorationService, this._decorationService);
|
|
158
|
+
this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);
|
|
159
|
+
this._instantiationService.setService(ILinkProviderService, this._linkProviderService);
|
|
160
|
+
this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
|
|
156
161
|
|
|
157
162
|
// Setup InputHandler listeners
|
|
158
163
|
this.register(this._inputHandler.onRequestBell(() => this._onBell.fire()));
|
|
@@ -482,6 +487,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
482
487
|
this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);
|
|
483
488
|
this._helperContainer.appendChild(this._compositionView);
|
|
484
489
|
|
|
490
|
+
this._mouseService = this._instantiationService.createInstance(MouseService);
|
|
491
|
+
this._instantiationService.setService(IMouseService, this._mouseService);
|
|
492
|
+
|
|
493
|
+
this.linkifier = this.register(this._instantiationService.createInstance(Linkifier, this.screenElement));
|
|
494
|
+
|
|
485
495
|
// Performance: Add viewport and helper elements from the fragment
|
|
486
496
|
this.element.appendChild(fragment);
|
|
487
497
|
|
|
@@ -493,9 +503,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
493
503
|
this._renderService.setRenderer(this._createRenderer());
|
|
494
504
|
}
|
|
495
505
|
|
|
496
|
-
this._mouseService = this._instantiationService.createInstance(MouseService);
|
|
497
|
-
this._instantiationService.setService(IMouseService, this._mouseService);
|
|
498
|
-
|
|
499
506
|
this.viewport = this._instantiationService.createInstance(Viewport, this._viewportElement, this._viewportScrollArea);
|
|
500
507
|
this.viewport.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent, ScrollSource.VIEWPORT)),
|
|
501
508
|
this.register(this._inputHandler.onRequestSyncScrollBar(() => this.viewport!.syncScrollArea()));
|
|
@@ -513,7 +520,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
513
520
|
this._selectionService = this.register(this._instantiationService.createInstance(SelectionService,
|
|
514
521
|
this.element,
|
|
515
522
|
this.screenElement,
|
|
516
|
-
this.
|
|
523
|
+
this.linkifier
|
|
517
524
|
));
|
|
518
525
|
this._instantiationService.setService(ISelectionService, this._selectionService);
|
|
519
526
|
this.register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));
|
|
@@ -533,7 +540,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
533
540
|
}));
|
|
534
541
|
this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => this._selectionService!.refresh()));
|
|
535
542
|
|
|
536
|
-
this.linkifier2.attachToDom(this.screenElement, this._mouseService, this._renderService);
|
|
537
543
|
this.register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));
|
|
538
544
|
this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));
|
|
539
545
|
|
|
@@ -575,7 +581,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
575
581
|
}
|
|
576
582
|
|
|
577
583
|
private _createRenderer(): IRenderer {
|
|
578
|
-
return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.
|
|
584
|
+
return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);
|
|
579
585
|
}
|
|
580
586
|
|
|
581
587
|
/**
|
|
@@ -894,7 +900,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|
|
894
900
|
}
|
|
895
901
|
|
|
896
902
|
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
|
|
897
|
-
return this.
|
|
903
|
+
return this._linkProviderService.registerLinkProvider(linkProvider);
|
|
898
904
|
}
|
|
899
905
|
|
|
900
906
|
public registerCharacterJoiner(handler: CharacterJoinerHandler): number {
|
package/src/browser/Types.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { IEvent } from 'common/EventEmitter';
|
|
|
7
7
|
import { CharData, IColor, ICoreTerminal, ITerminalOptions } from 'common/Types';
|
|
8
8
|
import { IBuffer } from 'common/buffer/Types';
|
|
9
9
|
import { IDisposable, Terminal as ITerminalApi } from '@xterm/xterm';
|
|
10
|
-
import { IMouseService, IRenderService } from './services/Services';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* A portion of the public API that are implemented identially internally and simply passed through.
|
|
@@ -18,9 +17,9 @@ export interface ITerminal extends InternalPassthroughApis, ICoreTerminal {
|
|
|
18
17
|
screenElement: HTMLElement | undefined;
|
|
19
18
|
browser: IBrowser;
|
|
20
19
|
buffer: IBuffer;
|
|
20
|
+
linkifier: ILinkifier2 | undefined;
|
|
21
21
|
viewport: IViewport | undefined;
|
|
22
22
|
options: Required<ITerminalOptions>;
|
|
23
|
-
linkifier2: ILinkifier2;
|
|
24
23
|
|
|
25
24
|
onBlur: IEvent<void>;
|
|
26
25
|
onFocus: IEvent<void>;
|
|
@@ -128,13 +127,6 @@ export interface ILinkifier2 extends IDisposable {
|
|
|
128
127
|
onShowLinkUnderline: IEvent<ILinkifierEvent>;
|
|
129
128
|
onHideLinkUnderline: IEvent<ILinkifierEvent>;
|
|
130
129
|
readonly currentLink: ILinkWithState | undefined;
|
|
131
|
-
|
|
132
|
-
attachToDom(element: HTMLElement, mouseService: IMouseService, renderService: IRenderService): void;
|
|
133
|
-
registerLinkProvider(linkProvider: ILinkProvider): IDisposable;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
interface ILinkProvider {
|
|
137
|
-
provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
|
|
138
130
|
}
|
|
139
131
|
|
|
140
132
|
interface ILink {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ILinkProvider, ILinkProviderService } from 'browser/services/Services';
|
|
2
|
+
import { Disposable, toDisposable } from 'common/Lifecycle';
|
|
3
|
+
import { IDisposable } from 'common/Types';
|
|
4
|
+
|
|
5
|
+
export class LinkProviderService extends Disposable implements ILinkProviderService {
|
|
6
|
+
declare public serviceBrand: undefined;
|
|
7
|
+
|
|
8
|
+
public readonly linkProviders: ILinkProvider[] = [];
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.register(toDisposable(() => this.linkProviders.length = 0));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
|
|
16
|
+
this.linkProviders.push(linkProvider);
|
|
17
|
+
return {
|
|
18
|
+
dispose: () => {
|
|
19
|
+
// Remove the link provider from the list
|
|
20
|
+
const providerIndex = this.linkProviders.indexOf(linkProvider);
|
|
21
|
+
|
|
22
|
+
if (providerIndex !== -1) {
|
|
23
|
+
this.linkProviders.splice(providerIndex, 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { IEvent } from 'common/EventEmitter';
|
|
7
7
|
import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
|
|
8
|
-
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
|
|
8
|
+
import { IColorSet, ILink, ReadonlyColorSet } from 'browser/Types';
|
|
9
9
|
import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
|
|
10
10
|
import { createDecorator } from 'common/services/ServiceRegistry';
|
|
11
11
|
import { AllColorIndex, IDisposable } from 'common/Types';
|
|
@@ -145,3 +145,14 @@ export interface IThemeService {
|
|
|
145
145
|
*/
|
|
146
146
|
modifyColors(callback: (colors: IColorSet) => void): void;
|
|
147
147
|
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
export const ILinkProviderService = createDecorator<ILinkProviderService>('LinkProviderService');
|
|
151
|
+
export interface ILinkProviderService extends IDisposable {
|
|
152
|
+
serviceBrand: undefined;
|
|
153
|
+
readonly linkProviders: ReadonlyArray<ILinkProvider>;
|
|
154
|
+
registerLinkProvider(linkProvider: ILinkProvider): IDisposable;
|
|
155
|
+
}
|
|
156
|
+
export interface ILinkProvider {
|
|
157
|
+
provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
|
|
158
|
+
}
|
|
@@ -120,6 +120,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
120
120
|
this._oscLinkService = this._instantiationService.createInstance(OscLinkService);
|
|
121
121
|
this._instantiationService.setService(IOscLinkService, this._oscLinkService);
|
|
122
122
|
|
|
123
|
+
|
|
123
124
|
// Register input handler and handle/forward events
|
|
124
125
|
this._inputHandler = this.register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.coreMouseService, this.unicodeService));
|
|
125
126
|
this.register(forwardEvent(this._inputHandler.onLineFeed, this._onLineFeed));
|