diff --git a/src/browser/renderer/BaseRenderLayer.ts b/src/browser/renderer/BaseRenderLayer.ts index 447f5ade..ead0844f 100644 --- a/src/browser/renderer/BaseRenderLayer.ts +++ b/src/browser/renderer/BaseRenderLayer.ts @@ -569,6 +569,10 @@ export abstract class BaseRenderLayer implements IRenderLayer { if (!start || !end) { return false; } + if (this._columnSelectMode) { + return x >= start[0] && y >= start[1] && + x < end[0] && y < end[1]; + } return (y > start[1] && y < end[1]) || (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) || (start[1] < end[1] && y === end[1] && x < end[0]) || diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 840ef40d..fdeef91c 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -281,6 +281,7 @@ export class DomRenderer extends Disposable implements IRenderer { this._selectionContainer.removeChild(this._selectionContainer.children[0]); } + this._rowFactory.onSelectionChanged(start, end, columnSelectMode); this.renderRows(0, this._bufferService.rows - 1); // Selection does not exist diff --git a/src/browser/renderer/dom/DomRendererRowFactory.test.ts b/src/browser/renderer/dom/DomRendererRowFactory.test.ts index d50765f0..5a374b14 100644 --- a/src/browser/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/browser/renderer/dom/DomRendererRowFactory.test.ts @@ -50,8 +50,7 @@ describe('DomRendererRowFactory', () => { new MockCharacterJoinerService(), new MockOptionsService({ drawBoldTextInBrightColors: true }), new MockCoreService(), - new MockDecorationService(), - new MockSelectionService() + new MockDecorationService() ); lineData = createEmptyLineData(2); }); diff --git a/src/browser/renderer/dom/DomRendererRowFactory.ts b/src/browser/renderer/dom/DomRendererRowFactory.ts index fc21e638..266d7587 100644 --- a/src/browser/renderer/dom/DomRendererRowFactory.ts +++ b/src/browser/renderer/dom/DomRendererRowFactory.ts @@ -28,14 +28,17 @@ export const CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'; export class DomRendererRowFactory { private _workCell: CellData = new CellData(); + private _selectionStart: [number, number] | undefined; + private _selectionEnd: [number, number] | undefined; + private _columnSelectMode: boolean = false; + constructor( private readonly _document: Document, private _colors: IColorSet, @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService, @IOptionsService private readonly _optionsService: IOptionsService, @ICoreService private readonly _coreService: ICoreService, - @IDecorationService private readonly _decorationService: IDecorationService, - @ISelectionService private readonly _selectionService: ISelectionService + @IDecorationService private readonly _decorationService: IDecorationService ) { } @@ -43,6 +46,12 @@ export class DomRendererRowFactory { this._colors = colors; } + public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void { + this._selectionStart = start; + this._selectionEnd = end; + this._columnSelectMode = columnSelectMode; + } + public createRow(lineData: IBufferLine, row: number, isCursorRow: boolean, cursorStyle: string | undefined, cursorX: number, cursorBlink: boolean, cellWidth: number, cols: number): DocumentFragment { const fragment = this._document.createDocumentFragment(); @@ -198,7 +207,7 @@ export class DomRendererRowFactory { // Apply selection foreground if applicable if (!isTop) { - if (this._colors.selectionForeground && this._selectionService.isCellInSelection(x, row)) { + if (this._colors.selectionForeground && this._isCellInSelection(x, row)) { fgColorMode = Attributes.CM_RGB; fg = this._colors.selectionForeground.rgba >> 8 & 0xFFFFFF; fgOverride = this._colors.selectionForeground; @@ -293,6 +302,22 @@ export class DomRendererRowFactory { private _addStyle(element: HTMLElement, style: string): void { element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`); } + + private _isCellInSelection(x: number, y: number): boolean { + const start = this._selectionStart; + const end = this._selectionEnd; + if (!start || !end) { + return false; + } + if (this._columnSelectMode) { + return x >= start[0] && y >= start[1] && + x < end[0] && y < end[1]; + } + return (y > start[1] && y < end[1]) || + (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) || + (start[1] < end[1] && y === end[1] && x < end[0]) || + (start[1] < end[1] && y === start[1] && x >= start[0]); + } } function padStart(text: string, padChar: string, length: number): string {