mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 09:10:30 -04:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Terminal, IMarker } from 'vscode-xterm';
|
||||
import { ITerminalCommandTracker } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
/**
|
||||
* The minimum size of the prompt in which to assume the line is a command.
|
||||
*/
|
||||
const MINIMUM_PROMPT_LENGTH = 2;
|
||||
|
||||
enum Boundary {
|
||||
Top,
|
||||
Bottom
|
||||
}
|
||||
|
||||
export const enum ScrollPosition {
|
||||
Top,
|
||||
Middle
|
||||
}
|
||||
|
||||
export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposable {
|
||||
private _currentMarker: IMarker | Boundary = Boundary.Bottom;
|
||||
private _selectionStart: IMarker | Boundary | null = null;
|
||||
private _isDisposable: boolean = false;
|
||||
|
||||
constructor(
|
||||
private _xterm: Terminal
|
||||
) {
|
||||
this._xterm.on('key', key => this._onKey(key));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
}
|
||||
|
||||
private _onKey(key: string): void {
|
||||
if (key === '\x0d') {
|
||||
this._onEnter();
|
||||
}
|
||||
|
||||
// Clear the current marker so successive focus/selection actions are performed from the
|
||||
// bottom of the buffer
|
||||
this._currentMarker = Boundary.Bottom;
|
||||
this._selectionStart = null;
|
||||
}
|
||||
|
||||
private _onEnter(): void {
|
||||
if (this._xterm._core.buffer.x >= MINIMUM_PROMPT_LENGTH) {
|
||||
this._xterm.addMarker(0);
|
||||
}
|
||||
}
|
||||
|
||||
public scrollToPreviousCommand(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void {
|
||||
if (!retainSelection) {
|
||||
this._selectionStart = null;
|
||||
}
|
||||
|
||||
let markerIndex;
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
markerIndex = this._xterm.markers.length - 1;
|
||||
} else if (this._currentMarker === Boundary.Top) {
|
||||
markerIndex = -1;
|
||||
} else if (this._isDisposable) {
|
||||
markerIndex = this._findPreviousCommand();
|
||||
this._currentMarker.dispose();
|
||||
this._isDisposable = false;
|
||||
} else {
|
||||
markerIndex = this._xterm.markers.indexOf(this._currentMarker) - 1;
|
||||
}
|
||||
|
||||
if (markerIndex < 0) {
|
||||
this._currentMarker = Boundary.Top;
|
||||
this._xterm.scrollToTop();
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentMarker = this._xterm.markers[markerIndex];
|
||||
this._scrollToMarker(this._currentMarker, scrollPosition);
|
||||
}
|
||||
|
||||
public scrollToNextCommand(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void {
|
||||
if (!retainSelection) {
|
||||
this._selectionStart = null;
|
||||
}
|
||||
|
||||
let markerIndex;
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
markerIndex = this._xterm.markers.length;
|
||||
} else if (this._currentMarker === Boundary.Top) {
|
||||
markerIndex = 0;
|
||||
} else if (this._isDisposable) {
|
||||
markerIndex = this._findNextCommand();
|
||||
this._currentMarker.dispose();
|
||||
this._isDisposable = false;
|
||||
} else {
|
||||
markerIndex = this._xterm.markers.indexOf(this._currentMarker) + 1;
|
||||
}
|
||||
|
||||
if (markerIndex >= this._xterm.markers.length) {
|
||||
this._currentMarker = Boundary.Bottom;
|
||||
this._xterm.scrollToBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentMarker = this._xterm.markers[markerIndex];
|
||||
this._scrollToMarker(this._currentMarker, scrollPosition);
|
||||
}
|
||||
|
||||
private _scrollToMarker(marker: IMarker, position: ScrollPosition): void {
|
||||
let line = marker.line;
|
||||
if (position === ScrollPosition.Middle) {
|
||||
line = Math.max(line - this._xterm.rows / 2, 0);
|
||||
}
|
||||
this._xterm.scrollToLine(line);
|
||||
}
|
||||
|
||||
public selectToPreviousCommand(): void {
|
||||
if (this._selectionStart === null) {
|
||||
this._selectionStart = this._currentMarker;
|
||||
}
|
||||
this.scrollToPreviousCommand(ScrollPosition.Middle, true);
|
||||
this._selectLines(this._currentMarker, this._selectionStart);
|
||||
}
|
||||
|
||||
public selectToNextCommand(): void {
|
||||
if (this._selectionStart === null) {
|
||||
this._selectionStart = this._currentMarker;
|
||||
}
|
||||
this.scrollToNextCommand(ScrollPosition.Middle, true);
|
||||
this._selectLines(this._currentMarker, this._selectionStart);
|
||||
}
|
||||
|
||||
public selectToPreviousLine(): void {
|
||||
if (this._selectionStart === null) {
|
||||
this._selectionStart = this._currentMarker;
|
||||
}
|
||||
|
||||
this.scrollToPreviousLine(ScrollPosition.Middle, true);
|
||||
this._selectLines(this._currentMarker, this._selectionStart);
|
||||
}
|
||||
|
||||
public selectToNextLine(): void {
|
||||
if (this._selectionStart === null) {
|
||||
this._selectionStart = this._currentMarker;
|
||||
}
|
||||
|
||||
this.scrollToNextLine(ScrollPosition.Middle, true);
|
||||
this._selectLines(this._currentMarker, this._selectionStart);
|
||||
}
|
||||
|
||||
private _selectLines(start: IMarker | Boundary, end: IMarker | Boundary | null): void {
|
||||
if (end === null) {
|
||||
end = Boundary.Bottom;
|
||||
}
|
||||
|
||||
let startLine = this._getLine(start);
|
||||
let endLine = this._getLine(end);
|
||||
|
||||
if (startLine > endLine) {
|
||||
const temp = startLine;
|
||||
startLine = endLine;
|
||||
endLine = temp;
|
||||
}
|
||||
|
||||
// Subtract a line as the marker is on the line the command run, we do not want the next
|
||||
// command in the selection for the current command
|
||||
endLine -= 1;
|
||||
|
||||
this._xterm.selectLines(startLine, endLine);
|
||||
}
|
||||
|
||||
private _getLine(marker: IMarker | Boundary): number {
|
||||
// Use the _second last_ row as the last row is likely the prompt
|
||||
if (marker === Boundary.Bottom) {
|
||||
return this._xterm._core.buffer.ybase + this._xterm.rows - 1;
|
||||
}
|
||||
|
||||
if (marker === Boundary.Top) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return marker.line;
|
||||
}
|
||||
|
||||
public scrollToPreviousLine(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void {
|
||||
if (!retainSelection) {
|
||||
this._selectionStart = null;
|
||||
}
|
||||
|
||||
if (this._currentMarker === Boundary.Top) {
|
||||
this._xterm.scrollToTop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
this._currentMarker = this._xterm.addMarker(this._getOffset() - 1);
|
||||
} else {
|
||||
const offset = this._getOffset();
|
||||
if (this._isDisposable) {
|
||||
this._currentMarker.dispose();
|
||||
}
|
||||
this._currentMarker = this._xterm.addMarker(offset - 1);
|
||||
}
|
||||
this._isDisposable = true;
|
||||
this._scrollToMarker(this._currentMarker, scrollPosition);
|
||||
}
|
||||
|
||||
public scrollToNextLine(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void {
|
||||
if (!retainSelection) {
|
||||
this._selectionStart = null;
|
||||
}
|
||||
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
this._xterm.scrollToBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._currentMarker === Boundary.Top) {
|
||||
this._currentMarker = this._xterm.addMarker(this._getOffset() + 1);
|
||||
} else {
|
||||
const offset = this._getOffset();
|
||||
if (this._isDisposable) {
|
||||
this._currentMarker.dispose();
|
||||
}
|
||||
this._currentMarker = this._xterm.addMarker(offset + 1);
|
||||
}
|
||||
this._isDisposable = true;
|
||||
this._scrollToMarker(this._currentMarker, scrollPosition);
|
||||
}
|
||||
|
||||
private _getOffset(): number {
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
return 0;
|
||||
} else if (this._currentMarker === Boundary.Top) {
|
||||
return 0 - (this._xterm._core.buffer.ybase + this._xterm._core.buffer.y);
|
||||
} else {
|
||||
let offset = this._getLine(this._currentMarker);
|
||||
offset -= this._xterm._core.buffer.ybase + this._xterm._core.buffer.y;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
private _findPreviousCommand(): number {
|
||||
if (this._currentMarker === Boundary.Top) {
|
||||
return 0;
|
||||
} else if (this._currentMarker === Boundary.Bottom) {
|
||||
return this._xterm.markers.length - 1;
|
||||
}
|
||||
|
||||
let i;
|
||||
for (i = this._xterm.markers.length - 1; i >= 0; i--) {
|
||||
if (this._xterm.markers[i].line < this._currentMarker.line) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private _findNextCommand(): number {
|
||||
if (this._currentMarker === Boundary.Top) {
|
||||
return 0;
|
||||
} else if (this._currentMarker === Boundary.Bottom) {
|
||||
return this._xterm.markers.length - 1;
|
||||
}
|
||||
|
||||
let i;
|
||||
for (i = 0; i < this._xterm.markers.length; i++) {
|
||||
if (this._xterm.markers[i].line > this._currentMarker.line) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return this._xterm.markers.length;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user