提交 d8b6b052 编写于 作者: J Johannes Rieken

Merge branch 'master' into joh/eslint-rules

......@@ -3245,5 +3245,5 @@ interface JQuery {
declare module "jquery" {
export = $;
}
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;
\ No newline at end of file
declare const jQuery: JQueryStatic;
declare const $: JQueryStatic;
{
"name": "code-oss-dev",
"version": "1.42.0",
"distro": "902f61f7a8b3668981a644df63abeb8994546d43",
"distro": "53e32cc87942bff5525453faaa8a831355c4dabb",
"author": {
"name": "Microsoft Corporation"
},
......@@ -55,10 +55,10 @@
"vscode-ripgrep": "^1.5.7",
"vscode-sqlite3": "4.0.9",
"vscode-textmate": "4.4.0",
"xterm": "4.3.0-beta.28.vscode.1",
"xterm": "4.4.0-beta.13",
"xterm-addon-search": "0.4.0-beta4",
"xterm-addon-web-links": "0.2.1",
"xterm-addon-webgl": "0.4.0-beta.11",
"xterm-addon-webgl": "0.5.0-beta.7",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
},
......
......@@ -20,10 +20,10 @@
"vscode-proxy-agent": "^0.5.2",
"vscode-ripgrep": "^1.5.7",
"vscode-textmate": "4.4.0",
"xterm": "4.3.0-beta.28.vscode.1",
"xterm": "4.4.0-beta.13",
"xterm-addon-search": "0.4.0-beta4",
"xterm-addon-web-links": "0.2.1",
"xterm-addon-webgl": "0.4.0-beta.11",
"xterm-addon-webgl": "0.5.0-beta.7",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
},
......
......@@ -5,9 +5,9 @@
"onigasm-umd": "2.2.5",
"semver-umd": "^5.5.5",
"vscode-textmate": "4.4.0",
"xterm": "4.3.0-beta.28.vscode.1",
"xterm": "4.4.0-beta.13",
"xterm-addon-search": "0.4.0-beta4",
"xterm-addon-web-links": "0.2.1",
"xterm-addon-webgl": "0.4.0-beta.11"
"xterm-addon-webgl": "0.5.0-beta.7"
}
}
......@@ -41,12 +41,12 @@ xterm-addon-web-links@0.2.1:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2"
integrity sha512-2KnHtiq0IG7hfwv3jw2/jQeH1RBk2d5CH4zvgwQe00rLofSJqSfgnJ7gwowxxpGHrpbPr6Lv4AmH/joaNw2+HQ==
xterm-addon-webgl@0.4.0-beta.11:
version "0.4.0-beta.11"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.4.0-beta.11.tgz#0e4a7242e2353cf74aba55e5a5bdc0b4ec87ad10"
integrity sha512-AteDxm1RFy1WnjY9r5iJSETozLebvUkR+jextdZk/ASsK21vsYK0DuVWwRI8afgiN2hUVhxcxuHEJUOV+CJDQA==
xterm@4.3.0-beta.28.vscode.1:
version "4.3.0-beta.28.vscode.1"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.vscode.1.tgz#89b85398b5801708e833d08bf92b2124fa128943"
integrity sha512-JNHNZyDtAWnybJTrenPzD6g/yXpHOvPqmjau91Up4onRbjQYMSNlth17SqaES68DKn/+4kcIl2c/RG5SXJjvGw==
xterm-addon-webgl@0.5.0-beta.7:
version "0.5.0-beta.7"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.5.0-beta.7.tgz#b7b95a362e942ad6f86fa286d7b7bd8ee3e7cf67"
integrity sha512-v6aCvhm1C6mvaurGwUYQfyhb2cAUyuVnzf3Ob/hy5ebtyzUj4wW0N9NbqDEJk67UeMi1lV2xZqrO5gNeTpVqFA==
xterm@4.4.0-beta.13:
version "4.4.0-beta.13"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.4.0-beta.13.tgz#f7c5fa0d2b098ce0dd8b7c96d3d5fcaee22b86ed"
integrity sha512-ZoDOVO3w84CXekBveGw1H2lcvM4HkJG5suXesE/3S+N4DnBhBcK/vw4kdooALGoorJV2GtgA1XEA6+m4N5Sgnw==
......@@ -428,15 +428,15 @@ xterm-addon-web-links@0.2.1:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2"
integrity sha512-2KnHtiq0IG7hfwv3jw2/jQeH1RBk2d5CH4zvgwQe00rLofSJqSfgnJ7gwowxxpGHrpbPr6Lv4AmH/joaNw2+HQ==
xterm-addon-webgl@0.4.0-beta.11:
version "0.4.0-beta.11"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.4.0-beta.11.tgz#0e4a7242e2353cf74aba55e5a5bdc0b4ec87ad10"
integrity sha512-AteDxm1RFy1WnjY9r5iJSETozLebvUkR+jextdZk/ASsK21vsYK0DuVWwRI8afgiN2hUVhxcxuHEJUOV+CJDQA==
xterm@4.3.0-beta.28.vscode.1:
version "4.3.0-beta.28.vscode.1"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.vscode.1.tgz#89b85398b5801708e833d08bf92b2124fa128943"
integrity sha512-JNHNZyDtAWnybJTrenPzD6g/yXpHOvPqmjau91Up4onRbjQYMSNlth17SqaES68DKn/+4kcIl2c/RG5SXJjvGw==
xterm-addon-webgl@0.5.0-beta.7:
version "0.5.0-beta.7"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.5.0-beta.7.tgz#b7b95a362e942ad6f86fa286d7b7bd8ee3e7cf67"
integrity sha512-v6aCvhm1C6mvaurGwUYQfyhb2cAUyuVnzf3Ob/hy5ebtyzUj4wW0N9NbqDEJk67UeMi1lV2xZqrO5gNeTpVqFA==
xterm@4.4.0-beta.13:
version "4.4.0-beta.13"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.4.0-beta.13.tgz#f7c5fa0d2b098ce0dd8b7c96d3d5fcaee22b86ed"
integrity sha512-ZoDOVO3w84CXekBveGw1H2lcvM4HkJG5suXesE/3S+N4DnBhBcK/vw4kdooALGoorJV2GtgA1XEA6+m4N5Sgnw==
yauzl@^2.9.2:
version "2.10.0"
......
......@@ -31,7 +31,7 @@ declare class LoaderEvent {
readonly detail: string;
}
declare var define: {
declare const define: {
(moduleName: string, dependencies: string[], callback: (...args: any[]) => any): any;
(moduleName: string, dependencies: string[], definition: any): any;
(moduleName: string, callback: (...args: any[]) => any): any;
......
......@@ -5,7 +5,7 @@
@font-face {
font-family: "codicon";
src: url("./codicon.ttf?17db7f5e5f31fd546e62218bb0823c0c") format("truetype");
src: url("./codicon.ttf?ed926e87ee4e27771159d875e877f74a") format("truetype");
}
.codicon[class*='codicon-'] {
......@@ -409,4 +409,5 @@
.codicon-call-outgoing:before { content: "\eb93" }
.codicon-menu:before { content: "\eb94" }
.codicon-expand-all:before { content: "\eb95" }
.codicon-feedback:before { content: "\eb96" }
.codicon-debug-alt:before { content: "\f101" }
......@@ -417,7 +417,7 @@ export class ExtHostApiCommands {
};
return this._commands.executeCommand<modes.CompletionList>('_executeCompletionItemProvider', args).then(result => {
if (result) {
const items = result.suggestions.map(suggestion => typeConverters.CompletionItem.to(suggestion));
const items = result.suggestions.map(suggestion => typeConverters.CompletionItem.to(suggestion, this._commands.converter));
return new types.CompletionList(items, result.incomplete);
}
return undefined;
......
......@@ -30,6 +30,7 @@ import { cloneAndChange } from 'vs/base/common/objects';
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
export interface PositionLike {
line: number;
......@@ -830,7 +831,7 @@ export namespace CompletionItemKind {
export namespace CompletionItem {
export function to(suggestion: modes.CompletionItem): types.CompletionItem {
export function to(suggestion: modes.CompletionItem, converter?: CommandsConverter): types.CompletionItem {
const result = new types.CompletionItem(suggestion.label);
result.insertText = suggestion.insertText;
result.kind = CompletionItemKind.to(suggestion.kind);
......@@ -844,14 +845,17 @@ export namespace CompletionItem {
result.range = editorRange.Range.isIRange(suggestion.range) ? Range.to(suggestion.range) : undefined;
result.range2 = editorRange.Range.isIRange(suggestion.range) ? undefined : { inserting: Range.to(suggestion.range.insert), replacing: Range.to(suggestion.range.replace) };
result.keepWhitespace = typeof suggestion.insertTextRules === 'undefined' ? false : Boolean(suggestion.insertTextRules & modes.CompletionItemInsertTextRule.KeepWhitespace);
// 'inserText'-logic
// 'insertText'-logic
if (typeof suggestion.insertTextRules !== 'undefined' && suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) {
result.insertText = new types.SnippetString(suggestion.insertText);
} else {
result.insertText = suggestion.insertText;
result.textEdit = result.range instanceof types.Range ? new types.TextEdit(result.range, result.insertText) : undefined;
}
// TODO additionalEdits, command
if (suggestion.additionalTextEdits && suggestion.additionalTextEdits.length > 0) {
result.additionalTextEdits = suggestion.additionalTextEdits.map(e => TextEdit.to(e as modes.TextEdit));
}
result.command = converter && suggestion.command ? converter.fromInternal(suggestion.command) : undefined;
return result;
}
......
......@@ -156,7 +156,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
}
const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents);
let lastActiveWorkspace: IWorkspaceFolder | null = null;
let lastActiveWorkspace: IWorkspaceFolder | undefined;
if (activeWorkspaceRootUriComponents && activeWorkspaceRootUri) {
// Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
......@@ -175,7 +175,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
// Get the initial cwd
const terminalConfig = configProvider.getConfiguration('terminal.integrated');
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), lastActiveWorkspace ? lastActiveWorkspace : undefined, this._variableResolver, activeWorkspaceRootUri, terminalConfig.cwd, this._logService);
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), lastActiveWorkspace, this._variableResolver, activeWorkspaceRootUri, terminalConfig.cwd, this._logService);
shellLaunchConfig.cwd = initialCwd;
const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect<ITerminalEnvironment>(`env.${platformKey}`));
......
......@@ -9,7 +9,6 @@ import * as nls from 'vs/nls';
import * as platform from 'vs/base/common/platform';
import severity from 'vs/base/common/severity';
import { Event, Emitter } from 'vs/base/common/event';
import { CompletionItem, completionKindFromString } from 'vs/editor/common/modes';
import { Position, IPosition } from 'vs/editor/common/core/position';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource, IDataBreakpoint, IDebugSessionOptions } from 'vs/workbench/contrib/debug/common/debug';
......@@ -26,7 +25,6 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { normalizeDriveLetter } from 'vs/base/common/labels';
import { Range } from 'vs/editor/common/core/range';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel';
......@@ -567,35 +565,17 @@ export class DebugSession implements IDebugSession {
}
}
async completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<CompletionItem[]> {
async completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<DebugProtocol.CompletionsResponse> {
if (!this.raw) {
return Promise.reject(new Error('no debug adapter'));
}
const response = await this.raw.completions({
return this.raw.completions({
frameId,
text,
column: position.column,
line: position.lineNumber,
}, token);
const result: CompletionItem[] = [];
if (response && response.body && response.body.targets) {
response.body.targets.forEach(item => {
if (item && item.label) {
result.push({
label: item.label,
insertText: item.text || item.label,
kind: completionKindFromString(item.type || 'property'),
filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined,
range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position),
sortText: item.sortText
});
}
});
}
return result;
}
//---- threads
......
......@@ -12,6 +12,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
import { ITextModel } from 'vs/editor/common/model';
import { Range } from 'vs/editor/common/core/range';
import { Position } from 'vs/editor/common/core/position';
import { registerEditorAction, ServicesAccessor, EditorAction } from 'vs/editor/browser/editorExtensions';
import { IModelService } from 'vs/editor/common/services/modelService';
......@@ -37,7 +38,7 @@ import { IDecorationOptions } from 'vs/editor/common/editorCommon';
import { transparent, editorForeground } from 'vs/platform/theme/common/colorRegistry';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems';
import { CompletionContext, CompletionList, CompletionProviderRegistry } from 'vs/editor/common/modes';
import { CompletionContext, CompletionList, CompletionProviderRegistry, CompletionItem, completionKindFromString, CompletionItemKind } from 'vs/editor/common/modes';
import { first } from 'vs/base/common/arrays';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { ITreeNode, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
......@@ -141,7 +142,34 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
const text = model.getValue();
const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame;
const frameId = focusedStackFrame ? focusedStackFrame.frameId : undefined;
const suggestions = await session.completions(frameId, text, position, overwriteBefore, token);
const response = await session.completions(frameId, text, position, overwriteBefore, token);
const suggestions: CompletionItem[] = [];
const computeRange = (length: number) => Range.fromPositions(position.delta(0, -length), position);
if (response && response.body && response.body.targets) {
response.body.targets.forEach(item => {
if (item && item.label) {
suggestions.push({
label: item.label,
insertText: item.text || item.label,
kind: completionKindFromString(item.type || 'property'),
filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined,
range: computeRange(item.length || overwriteBefore),
sortText: item.sortText
});
}
});
}
const history = this.history.getHistory();
history.forEach(h => suggestions.push({
label: h,
insertText: h,
kind: CompletionItemKind.Text,
range: computeRange(h.length),
sortText: 'ZZZ'
}));
return { suggestions };
}
......
......@@ -13,7 +13,6 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { ITextModel as EditorIModel } from 'vs/editor/common/model';
import { IEditor, ITextEditor } from 'vs/workbench/common/editor';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { CompletionItem } from 'vs/editor/common/modes';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { Range, IRange } from 'vs/editor/common/core/range';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
......@@ -234,7 +233,7 @@ export interface IDebugSession extends ITreeElement {
pause(threadId: number): Promise<void>;
terminateThreads(threadIds: number[]): Promise<void>;
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<CompletionItem[]>;
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<DebugProtocol.CompletionsResponse>;
setVariable(variablesReference: number | undefined, name: string, value: string): Promise<DebugProtocol.SetVariableResponse>;
loadSource(resource: uri): Promise<DebugProtocol.SourceResponse>;
getLoadedSources(): Promise<Source[]>;
......
......@@ -9,7 +9,6 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource, IDataBreakpoint, IDebugSessionOptions } from 'vs/workbench/contrib/debug/common/debug';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { CompletionItem } from 'vs/editor/common/modes';
import Severity from 'vs/base/common/severity';
import { AbstractDebugAdapter } from 'vs/workbench/contrib/debug/common/abstractDebugAdapter';
......@@ -237,8 +236,8 @@ export class MockSession implements IDebugSession {
return Promise.resolve([]);
}
completions(frameId: number, text: string, position: Position, overwriteBefore: number): Promise<CompletionItem[]> {
return Promise.resolve([]);
completions(frameId: number, text: string, position: Position, overwriteBefore: number): Promise<DebugProtocol.CompletionsResponse> {
throw new Error('not implemented');
}
clearThreads(removeThreads: boolean, reference?: number): void { }
......
......@@ -94,7 +94,7 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben
private getStatusEntry(showBeak?: boolean): IStatusbarEntry {
return {
text: '$(smiley)',
text: '$(feedback)',
command: '_feedback.open',
showBeak
};
......
......@@ -8,15 +8,22 @@
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
}
.monaco-workbench .terminal-message-widget {
font-size: 12px;
line-height: 19px;
padding: 4px 5px;
padding: 4px 8px;
animation: fadein 100ms linear;
white-space: nowrap;
/* Must be drawn on the top of the terminal's canvases */
z-index: 20;
}
.monaco-workbench .terminal-message-widget p {
margin: 0px;
}
.monaco-workbench .terminal-message-widget a {
color: #3794ff;
}
......@@ -206,6 +206,11 @@ configurationRegistry.registerConfiguration({
enum: [TerminalCursorStyle.BLOCK, TerminalCursorStyle.LINE, TerminalCursorStyle.UNDERLINE],
default: TerminalCursorStyle.BLOCK
},
'terminal.integrated.cursorWidth': {
markdownDescription: nls.localize('terminal.integrated.cursorWidth', "Controls the width of the cursor when `#terminal.integrated.cursorStyle#` is set to `line`."),
type: 'number',
default: 1
},
'terminal.integrated.scrollback': {
description: nls.localize('terminal.integrated.scrollback', "Controls the maximum amount of lines the terminal keeps in its buffer."),
type: 'number',
......
......@@ -39,6 +39,7 @@ import { CommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/addon
import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/addons/navigationModeAddon';
import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IOpenerService } from 'vs/platform/opener/common/opener';
// How long in milliseconds should an average frame take to render for a notification to appear
// which suggests the fallback DOM-based renderer
......@@ -286,7 +287,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ILogService private readonly _logService: ILogService,
@IStorageService private readonly _storageService: IStorageService,
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService,
@IOpenerService private readonly _openerService: IOpenerService
) {
super();
......@@ -666,7 +668,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._refreshSelectionContextKey();
}));
const widgetManager = new TerminalWidgetManager(this._wrapperElement);
const widgetManager = new TerminalWidgetManager(this._wrapperElement, this._openerService);
this._widgetManager = widgetManager;
this._processManager.onProcessReady(() => this._linkHandler?.setWidgetManager(widgetManager));
......@@ -1227,6 +1229,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
const config = this._configHelper.config;
this._setCursorBlink(config.cursorBlinking);
this._setCursorStyle(config.cursorStyle);
this._setCursorWidth(config.cursorWidth);
this._setCommandsToSkipShell(config.commandsToSkipShell);
this._setEnableBell(config.enableBell);
this._safeSetOption('scrollback', config.scrollback);
......@@ -1269,6 +1272,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
}
private _setCursorWidth(width: number): void {
if (this._xterm && this._xterm.getOption('cursorWidth') !== width) {
this._xterm.setOption('cursorWidth', width);
}
}
private _setCommandsToSkipShell(commands: string[]): void {
const excludeCommands = commands.filter(command => command[0] === '-').map(command => command.slice(1));
this._skipTerminalCommands = DEFAULT_COMMANDS_TO_SKIP_SHELL.filter(defaultCommand => {
......@@ -1335,6 +1344,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._safeSetOption('fontWeight', config.fontWeight);
this._safeSetOption('fontWeightBold', config.fontWeightBold);
this._safeSetOption('drawBoldTextInBrightColors', config.drawBoldTextInBrightColors);
// Any of the above setting changes could have changed the dimensions of the
// terminal, re-evaluate now.
this._initDimensions();
cols = this.cols;
rows = this.rows;
}
if (isNaN(cols) || isNaN(rows)) {
......
......@@ -18,6 +18,7 @@ import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
import { posix, win32 } from 'vs/base/common/path';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { OperatingSystem, isMacintosh } from 'vs/base/common/platform';
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
const pathPrefix = '(\\.\\.?|\\~)';
const pathSeparatorClause = '\\/';
......@@ -116,7 +117,7 @@ export class TerminalLinkHandler {
const leftPosition = location.start.x * (charWidth! + (font.letterSpacing / window.devicePixelRatio));
const bottomPosition = offsetRow * (Math.ceil(charHeight! * window.devicePixelRatio) * font.lineHeight) / window.devicePixelRatio;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(uri), verticalAlignment);
} else {
const target = (e.target as HTMLElement);
const colWidth = target.offsetWidth / this._xterm.cols;
......@@ -124,7 +125,7 @@ export class TerminalLinkHandler {
const leftPosition = location.start.x * colWidth;
const bottomPosition = offsetRow * rowHeight;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(uri), verticalAlignment);
}
};
this._leaveCallback = () => {
......@@ -277,19 +278,29 @@ export class TerminalLinkHandler {
return isMacintosh ? event.metaKey : event.ctrlKey;
}
private _getLinkHoverString(): string {
private _getLinkHoverString(uri: string): IMarkdownString {
const editorConf = this._configurationService.getValue<{ multiCursorModifier: 'ctrlCmd' | 'alt' }>('editor');
let label = '';
if (editorConf.multiCursorModifier === 'ctrlCmd') {
if (isMacintosh) {
return nls.localize('terminalLinkHandler.followLinkAlt.mac', "Option + click to follow link");
label = nls.localize('terminalLinkHandler.followLinkAlt.mac', "Option + click");
} else {
return nls.localize('terminalLinkHandler.followLinkAlt', "Alt + click to follow link");
}
label = nls.localize('terminalLinkHandler.followLinkAlt', "Alt + click");
}
} else {
if (isMacintosh) {
return nls.localize('terminalLinkHandler.followLinkCmd', "Cmd + click to follow link");
label = nls.localize('terminalLinkHandler.followLinkCmd', "Cmd + click");
} else {
label = nls.localize('terminalLinkHandler.followLinkCtrl', "Ctrl + click");
}
return nls.localize('terminalLinkHandler.followLinkCtrl', "Ctrl + click to follow link");
}
const message: IMarkdownString = new MarkdownString(`[Follow Link](${uri}) (${label})`, true);
message.uris = {
[uri]: URI.parse(uri).toJSON()
};
return message;
}
private get osPath(): IPath {
......
......@@ -88,7 +88,7 @@ export class TerminalPanel extends Panel {
label: nls.localize('terminal.useMonospace', "Use 'monospace'"),
run: () => this._configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'),
}];
this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts."), choices);
this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts. Be sure to restart VS Code if this is a newly installed font."), choices);
}
}
}));
......
......@@ -22,6 +22,7 @@ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { Disposable } from 'vs/base/common/lifecycle';
import { withNullAsUndefined } from 'vs/base/common/types';
/** The amount of time to consider terminal errors to be related to the launch */
const LAUNCHING_DURATION = 500;
......@@ -194,22 +195,22 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
): Promise<ITerminalChildProcess> {
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
const lastActiveWorkspace = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined;
if (!shellLaunchConfig.executable) {
const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(false);
shellLaunchConfig.executable = defaultConfig.shell;
shellLaunchConfig.args = defaultConfig.args;
} else {
shellLaunchConfig.executable = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.executable);
shellLaunchConfig.executable = this._configurationResolverService.resolve(lastActiveWorkspace, shellLaunchConfig.executable);
if (shellLaunchConfig.args) {
if (Array.isArray(shellLaunchConfig.args)) {
const resolvedArgs: string[] = [];
for (const arg of shellLaunchConfig.args) {
resolvedArgs.push(this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, arg));
resolvedArgs.push(this._configurationResolverService.resolve(lastActiveWorkspace, arg));
}
shellLaunchConfig.args = resolvedArgs;
} else {
shellLaunchConfig.args = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.args);
shellLaunchConfig.args = this._configurationResolverService.resolve(lastActiveWorkspace, shellLaunchConfig.args);
}
}
}
......@@ -217,7 +218,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
const initialCwd = terminalEnvironment.getCwd(
shellLaunchConfig,
this._environmentService.userHome,
lastActiveWorkspace ? lastActiveWorkspace : undefined,
lastActiveWorkspace,
this._configurationResolverService,
activeWorkspaceRootUri,
this._configHelper.config.cwd,
......
......@@ -4,6 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { URI } from 'vs/base/common/uri';
export enum WidgetVerticalAlignment {
Bottom,
......@@ -20,7 +24,8 @@ export class TerminalWidgetManager implements IDisposable {
private readonly _messageListeners = new DisposableStore();
constructor(
terminalWrapper: HTMLElement
terminalWrapper: HTMLElement,
private readonly _openerService: IOpenerService
) {
this._container = document.createElement('div');
this._container.classList.add('terminal-widget-overlay');
......@@ -48,20 +53,22 @@ export class TerminalWidgetManager implements IDisposable {
mutationObserver.observe(this._xtermViewport, { attributes: true, attributeFilter: ['style'] });
}
public showMessage(left: number, y: number, text: string, verticalAlignment: WidgetVerticalAlignment = WidgetVerticalAlignment.Bottom): void {
public showMessage(left: number, y: number, text: IMarkdownString, verticalAlignment: WidgetVerticalAlignment = WidgetVerticalAlignment.Bottom): void {
if (!this._container) {
return;
}
dispose(this._messageWidget);
this._messageListeners.clear();
this._messageWidget = new MessageWidget(this._container, left, y, text, verticalAlignment);
this._messageWidget = new MessageWidget(this._container, left, y, text, verticalAlignment, this._openerService);
}
public closeMessage(): void {
this._messageListeners.clear();
if (this._messageWidget) {
setTimeout(() => {
if (this._messageWidget && !this._messageWidget.mouseOver) {
this._messageListeners.add(MessageWidget.fadeOut(this._messageWidget));
}
}, 50);
}
private _refreshHeight(): void {
......@@ -73,13 +80,16 @@ export class TerminalWidgetManager implements IDisposable {
}
class MessageWidget {
private _domNode: HTMLDivElement;
private _domNode: HTMLElement;
private _mouseOver = false;
private readonly _messageListeners = new DisposableStore();
public get left(): number { return this._left; }
public get y(): number { return this._y; }
public get text(): string { return this._text; }
public get text(): IMarkdownString { return this._text; }
public get domNode(): HTMLElement { return this._domNode; }
public get verticalAlignment(): WidgetVerticalAlignment { return this._verticalAlignment; }
public get mouseOver(): boolean { return this._mouseOver; }
public static fadeOut(messageWidget: MessageWidget): IDisposable {
let handle: any;
......@@ -98,10 +108,16 @@ class MessageWidget {
private _container: HTMLElement,
private _left: number,
private _y: number,
private _text: string,
private _verticalAlignment: WidgetVerticalAlignment
private _text: IMarkdownString,
private _verticalAlignment: WidgetVerticalAlignment,
private readonly _openerService: IOpenerService
) {
this._domNode = document.createElement('div');
this._domNode = renderMarkdown(this._text, {
actionHandler: {
callback: this._handleLinkClicked.bind(this),
disposeables: this._messageListeners
}
});
this._domNode.style.position = 'absolute';
this._domNode.style.left = `${_left}px`;
......@@ -114,7 +130,15 @@ class MessageWidget {
}
this._domNode.classList.add('terminal-message-widget', 'fadeIn');
this._domNode.textContent = _text;
this._domNode.addEventListener('mouseenter', () => {
this._mouseOver = true;
});
this._domNode.addEventListener('mouseleave', () => {
this._mouseOver = false;
this._messageListeners.add(MessageWidget.fadeOut(this));
});
this._container.appendChild(this._domNode);
}
......@@ -122,5 +146,11 @@ class MessageWidget {
if (this.domNode.parentElement === this._container) {
this._container.removeChild(this.domNode);
}
this._messageListeners.dispose();
}
private _handleLinkClicked(content: string) {
this._openerService.open(URI.parse(content));
}
}
......@@ -91,6 +91,7 @@ export interface ITerminalConfiguration {
rightClickBehavior: 'default' | 'copyPaste' | 'paste' | 'selectWord';
cursorBlinking: boolean;
cursorStyle: string;
cursorWidth: number;
drawBoldTextInBrightColors: boolean;
fastScrollSensitivity: number;
fontFamily: string;
......
......@@ -74,10 +74,10 @@ function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerminalEnv
}
}
function resolveConfigurationVariables(configurationResolverService: IConfigurationResolverService, env: ITerminalEnvironment, lastActiveWorkspaceRoot: IWorkspaceFolder | null): ITerminalEnvironment {
function resolveConfigurationVariables(configurationResolverService: IConfigurationResolverService, env: ITerminalEnvironment, lastActiveWorkspaceRoot: IWorkspaceFolder | undefined): ITerminalEnvironment {
Object.keys(env).forEach((key) => {
const value = env[key];
if (typeof value === 'string' && lastActiveWorkspaceRoot !== null) {
if (typeof value === 'string') {
try {
env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, value);
} catch (e) {
......@@ -346,7 +346,7 @@ function getShellSetting(
export function createTerminalEnvironment(
shellLaunchConfig: IShellLaunchConfig,
lastActiveWorkspace: IWorkspaceFolder | null,
lastActiveWorkspace: IWorkspaceFolder | undefined,
envFromConfig: { userValue?: ITerminalEnvironment, value?: ITerminalEnvironment, defaultValue?: ITerminalEnvironment },
configurationResolverService: IConfigurationResolverService | undefined,
isWorkspaceShellAllowed: boolean,
......
......@@ -10042,15 +10042,15 @@ xterm-addon-web-links@0.2.1:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2"
integrity sha512-2KnHtiq0IG7hfwv3jw2/jQeH1RBk2d5CH4zvgwQe00rLofSJqSfgnJ7gwowxxpGHrpbPr6Lv4AmH/joaNw2+HQ==
xterm-addon-webgl@0.4.0-beta.11:
version "0.4.0-beta.11"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.4.0-beta.11.tgz#0e4a7242e2353cf74aba55e5a5bdc0b4ec87ad10"
integrity sha512-AteDxm1RFy1WnjY9r5iJSETozLebvUkR+jextdZk/ASsK21vsYK0DuVWwRI8afgiN2hUVhxcxuHEJUOV+CJDQA==
xterm@4.3.0-beta.28.vscode.1:
version "4.3.0-beta.28.vscode.1"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.vscode.1.tgz#89b85398b5801708e833d08bf92b2124fa128943"
integrity sha512-JNHNZyDtAWnybJTrenPzD6g/yXpHOvPqmjau91Up4onRbjQYMSNlth17SqaES68DKn/+4kcIl2c/RG5SXJjvGw==
xterm-addon-webgl@0.5.0-beta.7:
version "0.5.0-beta.7"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.5.0-beta.7.tgz#b7b95a362e942ad6f86fa286d7b7bd8ee3e7cf67"
integrity sha512-v6aCvhm1C6mvaurGwUYQfyhb2cAUyuVnzf3Ob/hy5ebtyzUj4wW0N9NbqDEJk67UeMi1lV2xZqrO5gNeTpVqFA==
xterm@4.4.0-beta.13:
version "4.4.0-beta.13"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.4.0-beta.13.tgz#f7c5fa0d2b098ce0dd8b7c96d3d5fcaee22b86ed"
integrity sha512-ZoDOVO3w84CXekBveGw1H2lcvM4HkJG5suXesE/3S+N4DnBhBcK/vw4kdooALGoorJV2GtgA1XEA6+m4N5Sgnw==
y18n@^3.2.1:
version "3.2.1"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册