Change:
CC Note: the following issue is only found in terminal profile. Other shells may or may not have the same issue. NVDA. . . the following in the and hit enter: Shift+Tab to focus in the a11y terminal buffer. Ctrl+End key to go to the bottom of the buffer. After the last terminal content, redundant 4-5 blank lines are so users will have to press UpArrow keys multiple times to reach the last content. The redundant blanks need to be removed. Version: 1.76.0-insider (system setup) Commit: Date: 2023-02-17T22:22:55.538Z Electron: 19.1.9 Chromium: 102.0.5005.194 16.14.2 V8: 10.2.154.23-electron.0 OS: Windows_NT x64 10.0. Sandboxed: Yes
I have noticed that there are more blank lines produced when you use . I assume that this is because the a11y buffer size reflects Monaco editor size and pressing Ctrl+End key thus puts your cursor at the end of the editor buffer. This makes sense, but it would be nice if we could trim out the blank lines after the actual terminal content.
On macOS, end and cmd+end does nothing, while ctrl+end or alt+end both focus the vscode window rather than anything in the terminal (or, when screencast mode is on, they focus the screencast hint)
this is just an issue about not having empty lines in the accessible terminal buffer. Those terminal keybindings are not expected to work in the accessible buffer, but feel free to create an issue if you think they should and we can discuss
no empty lines to be seen

Discussion:
import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; <del> import { DisposableStore } from 'vs/base/common/lifecycle'; </del> <ins> import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; </ins> import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IShellIntegration, TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { ITerminalFont, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';

private _accessibleBuffer: HTMLElement; private _bufferEditor: CodeEditorWidget; private _editorContainer: HTMLElement; <ins> private _commandFinishedDisposable: IDisposable | undefined; private _refreshSelection: boolean = true; </ins> private _registered: boolean = false; <ins> private _lastContentLength: number = 0; </ins> private _font: ITerminalFont; constructor(

async focus(): Promise<void> { await this._updateBufferEditor(); <del> // Updates xterm's accessibleBufferActive property // such that mouse events do not cause the terminal buffer // to steal the focus this._accessibleBuffer.focus(); this._bufferEditor.focus(); </del> } private async _updateBufferEditor(): Promise<void> { <ins> const commandDetection = this._capabilities.get(TerminalCapability.CommandDetection); const fragment = !!commandDetection ? this._getShellIntegrationContent() : this._getAllContent(); const model = await this._getTextModel(URI.from({ scheme: ACCESSIBLE_BUFFER.Scheme, fragment })); if (model) { this._bufferEditor.setModel(model); } </ins> if (!this._registered) { <del> // Registration is delayed until focus so the capability has time to have been added </del> this.add(this._terminal.raw.registerBufferElementProvider({ provideBufferElements: () => this._editorContainer })); <ins> // When this is created, the element isn't yet attached so the dimensions are tiny this._bufferEditor.layout({ width: this._accessibleBuffer.clientWidth, height: this._accessibleBuffer.clientHeight }); </ins> this._registered = true; } <del> // When this is created, the element isn't yet attached so the dimensions are tiny this._bufferEditor.layout({ width: this._accessibleBuffer.clientWidth, height: this._accessibleBuffer.clientHeight }); const commandDetection = this._capabilities.has(TerminalCapability.CommandDetection); const fragment = commandDetection ? this._getShellIntegrationContent() : this._getAllContent(); const model = await this._getTextModel(URI.from({ scheme: ACCESSIBLE_BUFFER.Scheme, fragment })); if (model) { this._bufferEditor.setModel(model); </del> <ins> if (!this._commandFinishedDisposable && commandDetection) { this._commandFinishedDisposable = commandDetection.onCommandFinished(() => this._refreshSelection = true); this.add(this._commandFinishedDisposable); } if (this._lastContentLength !== fragment.length || this._refreshSelection) { let lineNumber = 1; const lineCount = model?.getLineCount(); if (lineCount && model) { lineNumber = commandDetection ? lineCount - 1 : lineCount > 2 ? lineCount - 2 : 1; } this._bufferEditor.setSelection({ startLineNumber: lineNumber, startColumn: 1, endLineNumber: lineNumber, endColumn: 1 }); this._bufferEditor.setScrollTop(this._bufferEditor.getScrollHeight()); this._refreshSelection = false; this._lastContentLength = fragment.length; </ins> } <ins> // Updates xterm's accessibleBufferActive property // such that mouse events do not cause the terminal buffer // to steal the focus this._accessibleBuffer.focus(); this._bufferEditor.focus(); </ins> } async _getTextModel(resource: URI): Promise<ITextModel | null> {

} const isWrapped = buffer.getLine(i + 1)?.isWrapped; currentLine += line.translateToString(!isWrapped); <del> if (!isWrapped || i === end - 1) { </del> <ins> if (currentLine && !isWrapped || i === end - 1) { </ins> lines.push(currentLine.replace(new RegExp(' ', 'g'), 'xA0')); currentLine = ''; }