Skip to content

Commit e826f6b

Browse files
authored
Merge pull request #5234 from jtbandes/reflow-cursor-line
Add reflowCursorLine option
2 parents 41e8ae3 + 0d67393 commit e826f6b

File tree

8 files changed

+49
-20
lines changed

8 files changed

+49
-20
lines changed

demo/client.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,19 @@ function createTerminal(): void {
366366
// Set terminal size again to set the specific dimensions on the demo
367367
updateTerminalSize();
368368

369-
const res = await fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, { method: 'POST' });
370-
const processId = await res.text();
371-
pid = processId;
372-
socketURL += processId;
373-
socket = new WebSocket(socketURL);
374-
socket.onopen = runRealTerminal;
375-
socket.onclose = runFakeTerminal;
376-
socket.onerror = runFakeTerminal;
369+
const useRealTerminal = document.getElementById('use-real-terminal');
370+
if (useRealTerminal instanceof HTMLInputElement && !useRealTerminal.checked) {
371+
runFakeTerminal();
372+
} else {
373+
const res = await fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, { method: 'POST' });
374+
const processId = await res.text();
375+
pid = processId;
376+
socketURL += processId;
377+
socket = new WebSocket(socketURL);
378+
socket.onopen = runRealTerminal;
379+
socket.onclose = runFakeTerminal;
380+
socket.onerror = runFakeTerminal;
381+
}
377382
}, 0);
378383
}
379384

demo/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ <h3>Test</h3>
8181
<div style="display: inline-block; margin-right: 16px;">
8282
<dl>
8383
<dt>Lifecycle</dt>
84+
<dd><label for="use-real-terminal"><input type="checkbox" checked id="use-real-terminal" title="This is used to real vs fake terminals" />Use real terminal</label></dd>
8485
<dd><button id="dispose" title="This is used to testing memory leaks">Dispose terminal</button></dd>
8586
<dd><button id="create-new-window" title="This is used to test rendering in other windows">Create terminal in new window</button></dd>
8687

src/common/buffer/Buffer.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ export class Buffer implements IBuffer {
315315
}
316316

317317
private _reflowLarger(newCols: number, newRows: number): void {
318-
const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA));
318+
const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;
319+
const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);
319320
if (toRemove.length > 0) {
320321
const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);
321322
reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);
@@ -347,6 +348,7 @@ export class Buffer implements IBuffer {
347348
}
348349

349350
private _reflowSmaller(newCols: number, newRows: number): void {
351+
const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;
350352
const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);
351353
// Gather all BufferLines that need to be inserted into the Buffer here so that they can be
352354
// batched up and only committed once
@@ -367,11 +369,13 @@ export class Buffer implements IBuffer {
367369
wrappedLines.unshift(nextLine);
368370
}
369371

370-
// If these lines contain the cursor don't touch them, the program will handle fixing up
371-
// wrapped lines with the cursor
372-
const absoluteY = this.ybase + this.y;
373-
if (absoluteY >= y && absoluteY < y + wrappedLines.length) {
374-
continue;
372+
if (!reflowCursorLine) {
373+
// If these lines contain the cursor don't touch them, the program will handle fixing up
374+
// wrapped lines with the cursor
375+
const absoluteY = this.ybase + this.y;
376+
if (absoluteY >= y && absoluteY < y + wrappedLines.length) {
377+
continue;
378+
}
375379
}
376380

377381
const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();

src/common/buffer/BufferReflow.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ export interface INewLayoutResult {
2020
* @param newCols The columns after resize.
2121
* @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).
2222
* @param nullCell The cell data to use when filling in empty cells.
23+
* @param reflowCursorLine Whether to reflow the line containing the cursor.
2324
*/
24-
export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData): number[] {
25+
export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {
2526
// Gather all BufferLines that need to be removed from the Buffer here so that they can be
2627
// batched up and only committed once
2728
const toRemove: number[] = [];
@@ -41,11 +42,13 @@ export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, o
4142
nextLine = lines.get(++i) as BufferLine;
4243
}
4344

44-
// If these lines contain the cursor don't touch them, the program will handle fixing up wrapped
45-
// lines with the cursor
46-
if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {
47-
y += wrappedLines.length - 1;
48-
continue;
45+
if (!reflowCursorLine) {
46+
// If these lines contain the cursor don't touch them, the program will handle fixing up
47+
// wrapped lines with the cursor
48+
if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {
49+
y += wrappedLines.length - 1;
50+
continue;
51+
}
4952
}
5053

5154
// Copy buffer data to new locations

src/common/services/OptionsService.ts

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const DEFAULT_OPTIONS: Readonly<Required<ITerminalOptions>> = {
4444
allowTransparency: false,
4545
tabStopWidth: 8,
4646
theme: {},
47+
reflowCursorLine: false,
4748
rescaleOverlappingGlyphs: false,
4849
rightClickSelectsWord: isMac,
4950
windowOptions: {},

src/common/services/Services.ts

+1
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export interface ITerminalOptions {
237237
macOptionIsMeta?: boolean;
238238
macOptionClickForcesSelection?: boolean;
239239
minimumContrastRatio?: number;
240+
reflowCursorLine?: boolean;
240241
rescaleOverlappingGlyphs?: boolean;
241242
rightClickSelectsWord?: boolean;
242243
rows?: number;

typings/xterm-headless.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ declare module '@xterm/headless' {
142142
*/
143143
minimumContrastRatio?: number;
144144

145+
/**
146+
* Whether to reflow the line containing the cursor when the terminal is
147+
* resized. Defaults to false, because shells usually handle this
148+
* themselves.
149+
*/
150+
reflowCursorLine?: boolean;
151+
145152
/**
146153
* Whether to rescale glyphs horizontally that are a single cell wide but
147154
* have glyphs that would overlap following cell(s). This typically happens

typings/xterm.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ declare module '@xterm/xterm' {
213213
*/
214214
minimumContrastRatio?: number;
215215

216+
/**
217+
* Whether to reflow the line containing the cursor when the terminal is
218+
* resized. Defaults to false, because shells usually handle this
219+
* themselves.
220+
*/
221+
reflowCursorLine?: boolean;
222+
216223
/**
217224
* Whether to rescale glyphs horizontally that are a single cell wide but
218225
* have glyphs that would overlap following cell(s). This typically happens

0 commit comments

Comments
 (0)