|
|
@@ -157,23 +157,6 @@ function equalFlags(cell1: IBufferCell, cell2: IBufferCell): boolean {
|
|
|
abstract class BaseSerializeHandler {
|
|
|
constructor(protected readonly _buffer: IBuffer) {}
|
|
|
|
|
|
- private _isRealContent(codepoint: number): boolean {
|
|
|
- if (codepoint === 0) return false
|
|
|
- if (codepoint >= 0xf000) return false
|
|
|
- return true
|
|
|
- }
|
|
|
-
|
|
|
- private _findLastContentColumn(line: IBufferLine): number {
|
|
|
- let lastContent = -1
|
|
|
- for (let col = 0; col < line.length; col++) {
|
|
|
- const cell = line.getCell(col)
|
|
|
- if (cell && this._isRealContent(cell.getCode())) {
|
|
|
- lastContent = col
|
|
|
- }
|
|
|
- }
|
|
|
- return lastContent + 1
|
|
|
- }
|
|
|
-
|
|
|
public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {
|
|
|
let oldCell = this._buffer.getNullCell()
|
|
|
|
|
|
@@ -182,14 +165,14 @@ abstract class BaseSerializeHandler {
|
|
|
const startColumn = range.start.x
|
|
|
const endColumn = range.end.x
|
|
|
|
|
|
- this._beforeSerialize(endRow - startRow, startRow, endRow)
|
|
|
+ this._beforeSerialize(endRow - startRow + 1, startRow, endRow)
|
|
|
|
|
|
for (let row = startRow; row <= endRow; row++) {
|
|
|
const line = this._buffer.getLine(row)
|
|
|
if (line) {
|
|
|
const startLineColumn = row === range.start.y ? startColumn : 0
|
|
|
- const maxColumn = row === range.end.y ? endColumn : this._findLastContentColumn(line)
|
|
|
- const endLineColumn = Math.min(maxColumn, line.length)
|
|
|
+ const endLineColumn = Math.min(endColumn, line.length)
|
|
|
+
|
|
|
for (let col = startLineColumn; col < endLineColumn; col++) {
|
|
|
const c = line.getCell(col)
|
|
|
if (!c) {
|
|
|
@@ -243,6 +226,13 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
|
|
|
|
|
protected _beforeSerialize(rows: number, start: number, _end: number): void {
|
|
|
this._allRows = new Array<string>(rows)
|
|
|
+ this._allRowSeparators = new Array<string>(rows)
|
|
|
+ this._rowIndex = 0
|
|
|
+
|
|
|
+ this._currentRow = ""
|
|
|
+ this._nullCellCount = 0
|
|
|
+ this._cursorStyle = this._buffer.getNullCell()
|
|
|
+
|
|
|
this._lastContentCursorRow = start
|
|
|
this._lastCursorRow = start
|
|
|
this._firstRow = start
|
|
|
@@ -251,6 +241,11 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
|
|
protected _rowEnd(row: number, isLastRow: boolean): void {
|
|
|
let rowSeparator = ""
|
|
|
|
|
|
+ if (this._nullCellCount > 0) {
|
|
|
+ this._currentRow += " ".repeat(this._nullCellCount)
|
|
|
+ this._nullCellCount = 0
|
|
|
+ }
|
|
|
+
|
|
|
if (!isLastRow) {
|
|
|
const nextLine = this._buffer.getLine(row + 1)
|
|
|
|
|
|
@@ -388,7 +383,8 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
|
|
}
|
|
|
|
|
|
const codepoint = cell.getCode()
|
|
|
- const isGarbage = codepoint >= 0xf000
|
|
|
+ const isInvalidCodepoint = codepoint > 0x10ffff || (codepoint >= 0xd800 && codepoint <= 0xdfff)
|
|
|
+ const isGarbage = isInvalidCodepoint || (codepoint >= 0xf000 && cell.getWidth() === 1)
|
|
|
const isEmptyCell = codepoint === 0 || cell.getChars() === "" || isGarbage
|
|
|
|
|
|
const sgrSeq = this._diffStyle(cell, this._cursorStyle)
|
|
|
@@ -397,7 +393,7 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
|
|
|
|
|
if (styleChanged) {
|
|
|
if (this._nullCellCount > 0) {
|
|
|
- this._currentRow += `\u001b[${this._nullCellCount}C`
|
|
|
+ this._currentRow += " ".repeat(this._nullCellCount)
|
|
|
this._nullCellCount = 0
|
|
|
}
|
|
|
|
|
|
@@ -417,7 +413,7 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
|
|
this._nullCellCount += cell.getWidth()
|
|
|
} else {
|
|
|
if (this._nullCellCount > 0) {
|
|
|
- this._currentRow += `\u001b[${this._nullCellCount}C`
|
|
|
+ this._currentRow += " ".repeat(this._nullCellCount)
|
|
|
this._nullCellCount = 0
|
|
|
}
|
|
|
|